Module Http.Request

HTTP requests.

These values are:

Requests

type t

The type for HTTP requests.

val make : ?headers:Http.Headers.t -> ?log:string -> ?path:Path.t -> ?query:string option -> ?scheme:Scheme.t -> ?service_path:Path.t -> ?version:Version.t -> Method.t -> raw_path:string -> Body.t -> t

make method' ~raw_path body is a request with given method', raw_path and body and:

  • headers, the request headers. Defaults to Http.Headers.empty. In general it is better to let the body define content type and content length headers, see the client requests and service requests conventions.
  • log, the connector side log message, see log. Defaults to "".
  • path, see path. Defaults to Path.none.
  • query, see query. Defaults to None.
  • scheme is the scheme of the request, see scheme. Defaults to `Https.
  • service_path, see service_path. Defaults to Path.root.
  • version, the HTTP version, see version. Defaults to Http.Version.none. Client connectors generally ignore this, they decide how they want to send the request to the server.

Usually you should rather use for_service_connector or of_url. This ensures that derived data like path and query are computed correctly.

val for_service_connector : ?log:string -> ?scheme:Scheme.t -> service_path:Path.t -> version:Version.t -> Method.t -> raw_path:string -> headers:Http.Headers.t -> Body.t -> (t, Response.t) Stdlib.result

for_service_connector ~service_path ~version method' ~raw_path ~headers body is a request that satisfies the service requests conventions.

In case the response cannot satisfy them an error response is returned according to the connector responses conventions and body is Http.Body.dismissed.

val of_url : ?body:Body.t -> ?headers:Http.Headers.t -> ?log:string -> Method.t -> url:string -> (t, string) Stdlib.result

of_url method' ~url is a method' request on url ensuring that the request satsifies the client request conventions. If url is Url.is_likely_percent_decoded, it is percent-encoded before constructing the request.

headers defaults to Headers.empty and a suitable Headers.host derived from url is added to it. body defaults to Body.empty. Both query and path properties are derived from url and the service_path is Path.root. The scheme property is determined from url.

An error is returned if the scheme is neither http or https or if a decoding error occurs. In this case body is Http.Body.dismissed.

val to_url : t -> (string, string) Stdlib.result

to_url request is an URL for request. This can be seen as the inverse of of_url. This only errors if no Headers.host header can be found in the headers of request. The resulting URL should be percent encoded (but that depends if request was well formed).

val with_body : Body.t -> t -> t

with_body b request is request with body b. The body of request is Http.Body.dismissed.

val with_headers : Http.Headers.t -> t -> t

with_headers headers request is request with headers headers.

val override_headers : by:Http.Headers.t -> t -> t

override_headers ~by request is request with headers Http.Headers.override (headers response) ~by.

Properties

val body : t -> Body.t

body request is the body of request.

val headers : t -> Http.Headers.t

headers request are the HTTP headers of request. Should always at least includes at the Http.Headers.host header.

val log : t -> string

log request is the log of request. The log is a client-side explanatation not meant to be sent to the server. It can be used to log further details or explanations about the request.

val method' : t -> Method.t

method' request is the HTTP method of request.

val path : t -> Path.t

path request is the absolute path of the raw_path of request stripped by the service_path of request. This is the path you want your service to handle.

val query : t -> string option

query request is the the query part (without the ?) of the raw_path of request. None is returned if there is no ? at all. Some "" is returned if there is a ? followed by emptyness. To decode the query and possibly handle those that are POSTed aswell, see to_query.

val raw_path : t -> string

raw_path request is the request target (HTTP/1.1) or :path pseudo-header (HTTP/2, HTTP/3) of request. Usually one rather wants to use the convenience path and query which are derived from this value as this makes the service insensitive to where it is attached, see service_path.

val scheme : t -> Scheme.t

scheme request is the scheme of the request. Note that this is indicative. In particular services should not rely on this as this may depend on the way you are proxied or not be set by the connector. It it is mainly used by client connectors to be able to reconstruct the requested URL for example to follow redirections.

val service_path : t -> Path.t

service_path request is service path of request.

  • For client connectors this is irrelevant and set to Path.root.
  • For service connectors this is the path on which the root of the service is attached. This is usually defined by the service connector. The path value of r is the path mentioned in raw_path stripped by this path.
val version : t -> Version.t

version request is the HTTP version of request.

  • For client connectors this is mostly irrelevant: the connectors decides how they want to talk to the client. But it can be used as hint for which HTTP version to use.
  • For service connectors this should be the HTTP version of the request made on the connector. Note that if the service connector interfaces with a gateway this may be different from the actual version used by the gateway with the client.

Deconstructing and responding

Request deconstruction and response helpers. When they error these functions directly do with responses that have the right statuses and, unless otherwise noted, empty bodies. They also generally dismiss the body of the erroring request, see the individual combinators for details.

Redirection

val redirect_to_path : ?body:Body.t -> ?headers:Http.Headers.t -> ?log:string -> ?reason:string -> t -> Status.t -> Path.t -> Response.t

redirect_to_path request status path redirects to path in the service of request. This is Response.redirect status loc with loc the result of encoding the path:

Path.concat (service_path request) path

and the body of request is Http.Body.dismissed.

Header decoding

val decode_header : Http.Headers.Name.t -> (string -> ('a, string) Stdlib.result) -> t -> ('a option, Response.t) Stdlib.result

decode_header h dec rrequest decodes header h (if any) in request. Errors with Http.Status.bad_request_400 in case of decoding errors, transfers the error message to Response.reason and the body of request is Http.Body.dismissed.

Method constraints

val allow : 'a Method.constraint' list -> t -> ('a, Response.t) Stdlib.result

allow ms request is:

Cookies

find_cookie ~name request is the value of cookie name or None if undefined in request. Errors on header or cookie decoding errors.

FIXME. Why is this a string error ?

Queries

val to_query : t -> (Http.Query.t, Response.t) Stdlib.result

to_query request extracts a query from request. This is:

Warning. Http.Query.t values are untrusted, you need to properly validate their data.

Path cleaning

val clean_path : t -> (unit, Response.t) Stdlib.result

clean_path request is:

Note. There's more than one way to handle empty segments and trailing slashes in request paths. The scheme proposed here simply always redirects to paths in which all empty segments, and thus trailing slashes, are removed; except on the root path. The advantage of this scheme is that no elaborate file extension logic on the final segment is needed to route file serving (I no longer understand this comment).

Warning. This cleaning does not touch dot segments or percent-encoded directory separators that may be present in the path. You should still use that function or to_absolute_filepath for mapping paths to file paths.

Absolute file paths

val to_absolute_filepath : ?strip:Path.t -> file_root:Path.fpath -> t -> (Path.fpath, Response.t) Stdlib.result

absolute_filepath ~strip ~file_root request is:

Etags

val eval_if_none_match : t -> Etag.t -> headers:Http.Headers.t -> (Http.Headers.t, Response.t) Stdlib.result

eval_if_none_match request etag ~headers is

Design note. This slightly abuses the idea of the result design idea which was rather to carry error responses in the Error _ case. But… it's convenient.

Echo

val echo : ?status:Status.t -> t -> Response.t

echo request is a response with status status (defaults to Http.Status.ok_200) and a text/plain body that has all the properties of request, including the request body, which is consumed by the function with Body.to_string.

Note. In general using echo violates numerous HTTP MUSTs.

Predicates and comparisons

val is_body_empty : t -> bool

is_body_empty request is Body.is_empty (body request).

val equal : t -> t -> bool

equal tests requests for equality. This consumes the body.

val compare : t -> t -> int

compare is a total order on requests compatible with equal. This consumes the body.

Formatting

val pp : Stdlib.Format.formatter -> t -> unit

pp formats requests for inspection. Guarantees not to consume the body.