ezcurl/src/core/ezcurl_core.mli
2025-02-04 10:46:00 -05:00

254 lines
7.7 KiB
OCaml

(** Core signatures and implementation *)
(** Configuration for the client. *)
module Config : sig
type t
val default : t
val verbose : bool -> t -> t
val authmethod : Curl.curlAuth list -> t -> t
val max_redirects : int -> t -> t
val follow_location : bool -> t -> t
val username : string -> t -> t
val password : string -> t -> t
val pp : Format.formatter -> t -> unit
val to_string : t -> string
end
type t = private { curl: Curl.t } [@@unboxed]
(** A client, i.e. a cURL instance.
The wrapping record has been present since NEXT_RELEASE *)
val make :
?set_opts:(Curl.t -> unit) ->
?cookiejar_file:string ->
?enable_session_cookies:bool ->
unit ->
t
(** Create a new client.
@param set_opts called before returning the client, to set options
@param cookiejar_file if provided, tell curl to use the given file path to store/load cookies (since NEXT_RELEASE)
@param enable_session_cookies if provided, enable cookie handling in curl so it store/load cookies (since NEXT_RELEASE)
*)
val delete : t -> unit
(** Delete the client. It cannot be used anymore. *)
val with_client : ?set_opts:(Curl.t -> unit) -> (t -> 'a) -> 'a
(** Make a temporary client, call the function with it, then cleanup. *)
val set_no_signal : bool -> unit
(** Set no_signal default value for each new client instance. Default is [true].
See [CURLOPT_NOSIGNAL].
@since NEXT_RELEASE *)
(** Cookie handling.
@since NEXT_RELEASE *)
module Cookies : sig
val flush_cookiejar : t -> unit
(** If [cookiejar_file] was provided in {!make}, this flushes the current set of cookies
to the provided file.
@since NEXT_RELEASE *)
val reload_cookiejar : t -> unit
(** If [cookiejar_file] was provided in {!make}, this reloads cookies from
the provided file.
@since NEXT_RELEASE *)
val get_cookies : t -> string list
(** Get cookie list (in netscape format) *)
val set_cookies : t -> string list -> unit
(** Set cookie list (in netscape format) *)
val transfer : t -> t -> unit
(** [transfer c1 c2] copies cookies in [c1] into [c2] *)
end
(* TODO: duphandle is deprecated, how do we iterate on options?
val copy : t -> t
*)
type response_info = {
ri_response_time: float;
(** Total time (in seconds) for the request/response pair.
See {!Curl.get_totaltime}. *)
ri_redirect_count: int;
(** Number of redirects cURL followed.
See {!Curl.get_redirectcount}. *)
}
(** Metadata about a response from the server. *)
val pp_response_info : Format.formatter -> response_info -> unit
val string_of_response_info : response_info -> string
type 'body response = {
code: int;
(** Response code. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status *)
headers: (string * string) list; (** Response headers *)
body: 'body; (** Response body, or [""] *)
info: response_info; (** Information about the response *)
}
(** Response for a given request. *)
val pp_response_with :
(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}
to use *)
type meth =
| GET
| POST of Curl.curlHTTPPost list
| PUT
| DELETE
| HEAD
| CONNECT
| OPTIONS
| TRACE
| PATCH
val pp_meth : Format.formatter -> meth -> unit
val string_of_meth : meth -> string
type sse_frame = {
event: string option;
id: string option;
data: string option;
retry: int option;
empties: string list; (* Lines without a ':' *)
}
type sse_state =
| Frame of sse_frame
| End_of_stream
type sse_callback = sse_state -> bool
(** {2 Underlying IO Monad} *)
module type IO = sig
type 'a t
val return : 'a -> 'a t
val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t
val ( >|= ) : 'a t -> ('a -> 'b) -> 'b t
val fail : exn -> 'a t
val perform : Curl.t -> Curl.curlCode t
end
(** {2 Main Signature} *)
module type S = sig
type 'a io
val http :
?tries:int ->
?client:t ->
?config:Config.t ->
?range:string ->
?content:[ `String of string | `Write of bytes -> int -> int ] ->
?headers:(string * string) list ->
?callback:[ `Sse_event of sse_callback ] ->
url:string ->
meth:meth ->
unit ->
(string response, Curl.curlCode * string) result io
(** General purpose HTTP call via cURL.
@param url the URL to query
@param meth which method to use (see {!meth})
@param tries how many times to retry in case of [CURLE_AGAIN] code
@param client a client to reuse (instead of allocating a new one)
@param range an optional
{{: https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests} byte range}
to fetch (either to get large pages
by chunks, or to resume an interrupted download).
@param config configuration to set
@param content the content to send as the query's body, either
a [`String s] to write a single string, or [`Write f]
where [f] is a callback that is called on a buffer [b] with len [n]
(as in [f b n]) and returns how many bytes it wrote in the buffer
[b] starting at index [0] (at most [n] bytes).
It must return [0] when the content is entirely written, and not
before.
@param headers headers of the query
@param callback callback to use on received body, either
a [None] to keep normal Curl write behavior, or [`Sse_event f]
to enable {{: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events}
Server-sent events } processing, where [f] is a callback type [sse_callback]
and returns boolean to indicate if the internal write callback can
continue to proceed process or else close the incoming infinite stream.
*)
(** Push-based stream of bytes
@since NEXT_RELEASE *)
class type input_stream = object
method on_close : unit -> unit
method on_input : bytes -> int -> int -> unit
end
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 ->
?callback:[ `Sse_event of sse_callback ] ->
url:string ->
meth:meth ->
write_into:#input_stream ->
unit ->
(unit response, Curl.curlCode * string) result io
(** HTTP call via cURL, with a streaming response body.
The body is given to [write_into] by chunks,
then [write_into#on_close ()] is called
and the response is returned.
@since NEXT_RELEASE *)
val get :
?tries:int ->
?client:t ->
?config:Config.t ->
?range:string ->
?headers:(string * string) list ->
?callback:[ `Sse_event of sse_callback ] ->
url:string ->
unit ->
(string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:GET]
See {!http} for more info.
*)
val put :
?tries:int ->
?client:t ->
?config:Config.t ->
?headers:(string * string) list ->
?callback:[ `Sse_event of sse_callback ] ->
url:string ->
content:[ `String of string | `Write of bytes -> int -> int ] ->
unit ->
(string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:PUT]
See {!http} for more info.
*)
val post :
?tries:int ->
?client:t ->
?config:Config.t ->
?headers:(string * string) list ->
?content:[ `String of string | `Write of bytes -> int -> int ] ->
?callback:[ `Sse_event of sse_callback ] ->
params:Curl.curlHTTPPost list ->
url:string ->
unit ->
(string response, Curl.curlCode * string) result io
(** Shortcut for [http ~meth:(POST params)]
See {!http} for more info.
*)
end
module Make (IO : IO) : S with type 'a io = 'a IO.t