(** 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