wip: stream response…

This commit is contained in:
Simon Cruanes 2024-03-11 14:58:42 -04:00
parent d50a53ebda
commit fbd71baa19
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
2 changed files with 70 additions and 19 deletions

View file

@ -159,22 +159,23 @@ let pp_response_info out r =
let string_of_response_info s = Format.asprintf "%a" pp_response_info s let string_of_response_info s = Format.asprintf "%a" pp_response_info s
type response = { type 'body response = {
code: int; code: int;
headers: (string * string) list; headers: (string * string) list;
body: string; body: 'body;
info: response_info; info: response_info;
} }
let pp_response out r = let pp_response_with ppbody out r =
let pp_header out (s1, s2) = Format.fprintf out "@[<2>%s:@ %s@]" s1 s2 in let pp_header out (s1, s2) = Format.fprintf out "@[<2>%s:@ %s@]" s1 s2 in
let pp_headers out l = let pp_headers out l =
Format.fprintf out "@[<v>%a@]" (Format.pp_print_list pp_header) l Format.fprintf out "@[<v>%a@]" (Format.pp_print_list pp_header) l
in in
let { code; body; headers; info } = r in let { code; body; headers; info } = r in
Format.fprintf out "{@[code=%d;@ headers=@[%a@];@ info=%a;@ body=@[%a@]@]}" Format.fprintf out "{@[code=%d;@ headers=@[%a@];@ info=%a;@ body=@[%a@]@]}"
code pp_headers headers pp_response_info info Format.pp_print_text body code pp_headers headers pp_response_info info ppbody body
let pp_response = pp_response_with Format.pp_print_text
let string_of_response s = Format.asprintf "%a" pp_response s let string_of_response s = Format.asprintf "%a" pp_response s
type meth = type meth =
@ -224,7 +225,7 @@ module type S = sig
url:string -> url:string ->
meth:meth -> meth:meth ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** General purpose HTTP call via cURL. (** General purpose HTTP call via cURL.
@param url the URL to query @param url the URL to query
@param meth which method to use (see {!meth}) @param meth which method to use (see {!meth})
@ -245,6 +246,27 @@ module type S = sig
@param headers headers of the query @param headers headers of the query
*) *)
type stream = {
on_close: unit -> unit io;
on_chunk: string -> int -> int -> unit io;
}
(** Push-based stream of bytes
@since NEXT_RELEASE *)
val http_stream :
?tries:int ->
?client:t ->
?config:Config.t ->
?range:string ->
?content:[ `String of string | `Write of bytes -> int -> int ] ->
?headers:(string * string) list ->
url:string ->
meth:meth ->
unit ->
(stream response, Curl.curlCode * string) result io
(** HTTP call via cURL, with a streaming response body.
@since NEXT_RELEASE *)
val get : val get :
?tries:int -> ?tries:int ->
?client:t -> ?client:t ->
@ -253,7 +275,7 @@ module type S = sig
?headers:(string * string) list -> ?headers:(string * string) list ->
url:string -> url:string ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:GET] (** Shortcut for [http ~meth:GET]
See {!http} for more info. See {!http} for more info.
*) *)
@ -266,7 +288,7 @@ module type S = sig
url:string -> url:string ->
content:[ `String of string | `Write of bytes -> int -> int ] -> content:[ `String of string | `Write of bytes -> int -> int ] ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:PUT] (** Shortcut for [http ~meth:PUT]
See {!http} for more info. See {!http} for more info.
*) *)
@ -280,7 +302,7 @@ module type S = sig
params:Curl.curlHTTPPost list -> params:Curl.curlHTTPPost list ->
url:string -> url:string ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:(POST params)] (** Shortcut for [http ~meth:(POST params)]
See {!http} for more info. See {!http} for more info.
*) *)
@ -288,7 +310,7 @@ end
exception Parse_error of Curl.curlCode * string exception Parse_error of Curl.curlCode * string
let mk_res (self : t) headers body : (response, _) result = let mk_res (self : t) headers body : (_ response, _) result =
let split_colon s = let split_colon s =
match String.index s ':' with match String.index s ':' with
| exception Not_found -> | exception Not_found ->
@ -340,8 +362,13 @@ module Make (IO : IO) : S with type 'a io = 'a IO.t = struct
| `String s -> Some (String.length s) | `String s -> Some (String.length s)
| `Write _ -> None | `Write _ -> None
let http ?(tries = 1) ?client ?(config = Config.default) ?range ?content type stream = {
?(headers = []) ~url ~meth () : _ result io = on_close: unit -> unit io;
on_chunk: string -> int -> int -> unit io;
}
let http_ ?(tries = 1) ?client ?(config = Config.default) ?range ?content
?(headers = []) ~url ~meth () : (stream response, _) result io =
let headers = ref headers in let headers = ref headers in
let do_cleanup, self = let do_cleanup, self =
match client with match client with

View file

@ -78,17 +78,20 @@ type response_info = {
val pp_response_info : Format.formatter -> response_info -> unit val pp_response_info : Format.formatter -> response_info -> unit
val string_of_response_info : response_info -> string val string_of_response_info : response_info -> string
type response = { type 'body response = {
code: int; code: int;
(** Response code. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status *) (** Response code. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status *)
headers: (string * string) list; (** Response headers *) headers: (string * string) list; (** Response headers *)
body: string; (** Response body, or [""] *) body: 'body; (** Response body, or [""] *)
info: response_info; (** Information about the response *) info: response_info; (** Information about the response *)
} }
(** Response for a given request. *) (** Response for a given request. *)
val pp_response : Format.formatter -> response -> unit val pp_response_with :
val string_of_response : response -> string (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a response -> unit
val pp_response : Format.formatter -> string response -> unit
val string_of_response : string response -> string
(** The {{: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods} HTTP method} (** The {{: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods} HTTP method}
to use *) to use *)
@ -131,7 +134,7 @@ module type S = sig
url:string -> url:string ->
meth:meth -> meth:meth ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** General purpose HTTP call via cURL. (** General purpose HTTP call via cURL.
@param url the URL to query @param url the URL to query
@param meth which method to use (see {!meth}) @param meth which method to use (see {!meth})
@ -152,6 +155,27 @@ module type S = sig
@param headers headers of the query @param headers headers of the query
*) *)
type stream = {
on_close: unit -> unit io;
on_chunk: string -> int -> int -> unit io;
}
(** Push-based stream of bytes
@since NEXT_RELEASE *)
val http_stream :
?tries:int ->
?client:t ->
?config:Config.t ->
?range:string ->
?content:[ `String of string | `Write of bytes -> int -> int ] ->
?headers:(string * string) list ->
url:string ->
meth:meth ->
unit ->
(stream response, Curl.curlCode * string) result io
(** HTTP call via cURL, with a streaming response body.
@since NEXT_RELEASE *)
val get : val get :
?tries:int -> ?tries:int ->
?client:t -> ?client:t ->
@ -160,7 +184,7 @@ module type S = sig
?headers:(string * string) list -> ?headers:(string * string) list ->
url:string -> url:string ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:GET] (** Shortcut for [http ~meth:GET]
See {!http} for more info. See {!http} for more info.
*) *)
@ -173,7 +197,7 @@ module type S = sig
url:string -> url:string ->
content:[ `String of string | `Write of bytes -> int -> int ] -> content:[ `String of string | `Write of bytes -> int -> int ] ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:PUT] (** Shortcut for [http ~meth:PUT]
See {!http} for more info. See {!http} for more info.
*) *)
@ -187,7 +211,7 @@ module type S = sig
params:Curl.curlHTTPPost list -> params:Curl.curlHTTPPost list ->
url:string -> url:string ->
unit -> unit ->
(response, Curl.curlCode * string) result io (string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:(POST params)] (** Shortcut for [http ~meth:(POST params)]
See {!http} for more info. See {!http} for more info.
*) *)