mirror of
https://github.com/c-cube/tiny_httpd.git
synced 2025-12-05 19:00:32 -05:00
165 lines
5.5 KiB
OCaml
165 lines
5.5 KiB
OCaml
(** Requests
|
|
|
|
Requests are sent by a client, e.g. a web browser or cURL. From the point of
|
|
view of the server, they're inputs. *)
|
|
|
|
open Common_
|
|
|
|
type 'body t = private {
|
|
meth: Meth.t; (** HTTP method for this request. *)
|
|
host: string;
|
|
(** Host header, mandatory. It can also be found in {!headers}. *)
|
|
client_addr: Unix.sockaddr; (** Client address. Available since 0.14. *)
|
|
headers: Headers.t; (** List of headers. *)
|
|
mutable meta: Hmap.t; (** Metadata. @since 0.17 *)
|
|
http_version: int * int;
|
|
(** HTTP version. This should be either [1, 0] or [1, 1]. *)
|
|
path: string; (** Full path of the requested URL. *)
|
|
path_components: string list;
|
|
(** Components of the path of the requested URL. *)
|
|
query: (string * string) list; (** Query part of the requested URL. *)
|
|
body: 'body; (** Body of the request. *)
|
|
start_time: float;
|
|
(** Obtained via [get_time_s] in {!create}
|
|
@since 0.11 *)
|
|
}
|
|
(** A request with method, path, host, headers, and a body, sent by a client.
|
|
|
|
The body is polymorphic because the request goes through several
|
|
transformations. First it has no body, as only the request and headers are
|
|
read; then it has a stream body; then the body might be entirely read as a
|
|
string via {!read_body_full}.
|
|
|
|
@since 0.6 The field [query] was added and contains the query parameters in ["?foo=bar,x=y"]
|
|
@since 0.6 The field [path_components] is the part of the path that precedes [query] and is split on ["/"].
|
|
@since 0.11 the type is a private alias
|
|
@since 0.11 the field [start_time] was added *)
|
|
|
|
val add_meta : _ t -> 'a Hmap.key -> 'a -> unit
|
|
(** Add metadata
|
|
@since 0.17 *)
|
|
|
|
val get_meta : _ t -> 'a Hmap.key -> 'a option
|
|
(** Get metadata
|
|
@since 0.17 *)
|
|
|
|
val get_meta_exn : _ t -> 'a Hmap.key -> 'a
|
|
(** Like {!get_meta} but can fail
|
|
@raise Invalid_argument if not present
|
|
@since 0.17 *)
|
|
|
|
val pp_with :
|
|
?mask_header:(string -> bool) ->
|
|
?headers_to_mask:string list ->
|
|
?show_query:bool ->
|
|
?pp_body:(Format.formatter -> 'body -> unit) ->
|
|
unit ->
|
|
Format.formatter ->
|
|
'body t ->
|
|
unit
|
|
(** Pretty print the request. The exact format of this printing
|
|
is not specified.
|
|
@param mask_header function which is given each header name. If it
|
|
returns [true], the header's value is masked. The presence of
|
|
the header is still printed. Default [fun _ -> false].
|
|
@param headers_to_mask a list of headers masked by default.
|
|
Default is ["authorization"; "cookie"].
|
|
@show_query if [true] (default [true]), the query part of the
|
|
request is shown.
|
|
@param pp_body body printer (default prints "?" instead of the body,
|
|
which works even for stream bodies) *)
|
|
|
|
val pp : Format.formatter -> string t -> unit
|
|
(** Pretty print the request and its body. The exact format of this printing is
|
|
not specified. *)
|
|
|
|
val pp_ : Format.formatter -> _ t -> unit
|
|
(** Pretty print the request without its body. The exact format of this printing
|
|
is not specified. *)
|
|
|
|
val headers : _ t -> Headers.t
|
|
(** List of headers of the request, including ["Host"]. *)
|
|
|
|
val get_header : ?f:(string -> string) -> _ t -> string -> string option
|
|
(** [get_header req h] looks up header [h] in [req]. It returns [None] if the
|
|
header is not present. This is case insensitive and should be used rather
|
|
than looking up [h] verbatim in [headers]. *)
|
|
|
|
val get_header_int : _ t -> string -> int option
|
|
(** Same as {!get_header} but also performs a string to integer conversion. *)
|
|
|
|
val set_header : string -> string -> 'a t -> 'a t
|
|
(** [set_header k v req] sets [k: v] in the request [req]'s headers. *)
|
|
|
|
val remove_header : string -> 'a t -> 'a t
|
|
(** Remove one instance of this header.
|
|
@since 0.17 *)
|
|
|
|
val update_headers : (Headers.t -> Headers.t) -> 'a t -> 'a t
|
|
(** Modify headers using the given function.
|
|
@since 0.11 *)
|
|
|
|
val set_body : 'a -> _ t -> 'a t
|
|
(** [set_body b req] returns a new query whose body is [b].
|
|
@since 0.11 *)
|
|
|
|
val host : _ t -> string
|
|
(** Host field of the request. It also appears in the headers. *)
|
|
|
|
val client_addr : _ t -> Unix.sockaddr
|
|
(** Client address of the request.
|
|
@since 0.16 *)
|
|
|
|
val meth : _ t -> Meth.t
|
|
(** Method for the request. *)
|
|
|
|
val path : _ t -> string
|
|
(** Request path. *)
|
|
|
|
val query : _ t -> (string * string) list
|
|
(** Decode the query part of the {!path} field.
|
|
@since 0.4 *)
|
|
|
|
val body : 'b t -> 'b
|
|
(** Request body, possibly empty. *)
|
|
|
|
val start_time : _ t -> float
|
|
(** time stamp (from {!Unix.gettimeofday}) after parsing the first line of the
|
|
request
|
|
@since 0.11 *)
|
|
|
|
val limit_body_size :
|
|
max_size:int -> bytes:bytes -> IO.Input.t t -> IO.Input.t t
|
|
(** Limit the body size to [max_size] bytes, or return a [413] error.
|
|
@since 0.3 *)
|
|
|
|
val read_body_full : ?bytes:bytes -> ?buf_size:int -> IO.Input.t t -> string t
|
|
(** Read the whole body into a string. Potentially blocking.
|
|
|
|
@param buf_size initial size of underlying buffer (since 0.11)
|
|
@param bytes the initial buffer (since 0.14) *)
|
|
|
|
(**/**)
|
|
|
|
(* for internal usage, do not use. There is no guarantee of stability. *)
|
|
module Private_ : sig
|
|
val parse_req_start :
|
|
client_addr:Unix.sockaddr ->
|
|
get_time_s:(unit -> float) ->
|
|
buf:Buf.t ->
|
|
IO.Input.t ->
|
|
unit t option resp_result
|
|
|
|
val parse_req_start_exn :
|
|
?buf:Buf.t ->
|
|
client_addr:Unix.sockaddr ->
|
|
get_time_s:(unit -> float) ->
|
|
IO.Input.t ->
|
|
unit t option
|
|
|
|
val close_after_req : _ t -> bool
|
|
val parse_body : ?bytes:bytes -> unit t -> IO.Input.t -> IO.Input.t t
|
|
val set_body : 'a -> _ t -> 'a t
|
|
end
|
|
|
|
(**/**)
|