Module Opium.Request
Module to create and work with HTTP requests.
It offers convenience functions to read headers, decode a request body or URI.
The requests are most likely provided to you by Opium when you are writing your application, but this module contains all the constructors and setters that you need to initialize new requests.
Working with stream bodies
All the functions in this module will clone the stream before reading from it, so you can process the body multiple times if needed. Just make sure that you didn't drain the body before calling a function that reads from it.
Functions from other modules may drain the body stream. You can use Body.copy to copy the body yourself.
type t= Rock.Request.t={version : Version.t;target : string;headers : Headers.t;meth : Method.t;body : Body.t;env : Context.t;}
Constructors
make
val make : ?version:Version.t -> ?body:Body.t -> ?env:Context.t -> ?headers:Headers.t -> string -> Method.t -> tmake ?version ?body ?env ?headers target methodcreates a new request from the given values.By default, the HTTP version will be set to 1.1 and the request will not contain any header or body.
get
post
put
delete
val delete : ?version:Version.t -> ?body:Body.t -> ?env:Context.t -> ?headers:Headers.t -> string -> tdelete ?version ?body ?env ?headers targetcreates a newDELETErequest from the given values.By default, the HTTP version will be set to 1.1 and the request will not contain any header or body.
of_plain_text
val of_plain_text : ?version:Version.t -> ?headers:Headers.t -> ?env:Context.t -> body:string -> string -> Method.t -> tof_plain_text ?version ?headers ?env ~body target methodcreates a new request from the given values and a string body.The content type of the request will be set to
text/plainand the body will contain the stringbody.Example
The request initialized with:
Request.of_plain_text ~body:"Hello World" "/target" `POSTWill be represented as:
POST /target HTTP/HTTP/1.1 Content-Type: text/plain Hello World
of_json
val of_json : ?version:Version.t -> ?headers:Headers.t -> ?env:Context.t -> body:Yojson.Safe.t -> string -> Method.t -> tof_json ?version ?headers ?env ~body target methodcreates a new request from the given values and a json body.The content type of the request will be set to
application/jsonand the body will contain the json payloadbody.Example
The request initialized with:
Request.of_json ~body:(`Assoc [ "Hello", `String "World" ]) "/target" `POSTWill be represented as:
POST /target HTTP/HTTP/1.1 Content-Type: application/json {"Hello":"World"}
of_urlencoded
val of_urlencoded : ?version:Version.t -> ?headers:Headers.t -> ?env:Context.t -> body:(string * string list) list -> string -> Method.t -> tof_urlencoded ?version ?headers ?env ~body target methodcreates a new request from the given values and a urlencoded body.The content type of the request will be set to
application/x-www-form-urlencodedand the body will contain the key value pairsbodyformatted in the urlencoded format.Example
The request initialized with:
Request.of_urlencoded ~body:[ "key", [ "value" ] ] "/target" `POSTWill be represented as:
POST /target HTTP/HTTP/1.1 Content-Type: application/x-www-form-urlencoded key=value
Decoders
to_plain_text
val to_plain_text : t -> string Lwt.tto_plain_text tparses the body of the requesttas a string.Example
let request = Request.of_plain_text "Hello world!" let body = Request.to_json requestbodywill be:"Hello world!"
to_json
val to_json : t -> Yojson.Safe.t option Lwt.tto_json tparses the body of the requesttas a JSON structure.If the body of the request cannot be parsed as a JSON structure,
Noneis returned. Useto_json_exnto raise an exception instead.Example
let request = Request.of_json (`Assoc [ "Hello", `String "World" ]) let body = Request.to_json requestbodywill be:`Assoc [ "Hello", `String "World" ]
to_json_exn
to_urlencoded
val to_urlencoded : t -> (string * string list) list Lwt.tto_urlencoded tparses the body of the requesttfrom a urlencoded format to a list of key-values pairs.This function exist to offer a simple way to get all of the key-values pairs, but most of the time, you'll probably only want the value of a key given. If you don't need the entire list of values, it is recommended to use
urlencodedinstead.If the body of the request cannot be parsed as a urlencoded string, an empty list is returned.
Example
let request = Request.of_urlencoded ~body:[ "username", [ "admin" ]; "password", [ "password" ] ] "/" `POST ;; let values = Request.to_urlencoded requestvalueswill be:[ "username", [ "admin" ]; "password", [ "password" ] ]
to_multipart_form_data
val to_multipart_form_data : ?callback:(name:string -> filename:string -> string -> unit Lwt.t) -> t -> (string * string) list option Lwt.tto_multipart_form_data ?callback tparses the body of the requesttfrom amultipart/form-dataformat to a list of key-values pairs.The request has to to contain a
Content-Typeheader with a valuemultipart/form-dataand the HTTP method has to bePOST, otherwise the request will not be parsed anNonewill be returned. Seeto_multipart_form_data_exnto raise an exception instead.If the body of the request cannot be parsed as a
multipart/form-datastring, an empty list is returned.When provided, the callback is a function of type
val _ : ~filename:string ~name:string string -> Lwt.unitthat is called for each part of the body.
to_multipart_form_data_exn
val to_multipart_form_data_exn : ?callback:(name:string -> filename:string -> string -> unit Lwt.t) -> t -> (string * string) list Lwt.tto_multipart_form_data_exn ?callback tparses the body of the requesttfrom amultipart/form-dataformat to a list of key-values pairs.The request has to to contain a
Content-Typeheader with a valuemultipart/form-dataand the HTTP method has to bePOST, otherwise the request will not be parsed and anInvalid_argumentexception will be raised. Seeto_multipart_form_datato return an option instead.If the body of the request cannot be parsed as a
multipart/form-datastring, an empty list is returned.When provided, the callback is a function of type
val _ : ~filename:string ~name:string string -> Lwt.unitthat is called for each part of the body.
Getters and Setters
General Headers
header
headers
add_header
val add_header : (string * string) -> t -> tadd_header (key, value) tadds a header with the keykeyand the valuevalueto the requestt.If a header with the same key is already persent, a new header is appended to the list of headers regardless. If you want to add the header only if an header with the same key could not be found, you can use
add_header_unless_exists.See also
add_headersto add multiple headers.
add_header_or_replace
val add_header_or_replace : (string * string) -> t -> tadd_header_or_replace (key, value) tadds a header with the keykeyand the valuevalueto the requestt.If a header with the same key already exist, its value is replaced by
value. If you want to add the header only if it doesn't already exist, you can useadd_header_unless_exists.See also
add_headers_or_replaceto add multiple headers.
add_header_unless_exists
val add_header_unless_exists : (string * string) -> t -> tadd_header_unless_exists (key, value) tadds a header with the keykeyand the valuevalueto the requesttif an header with the same key does not already exist.If a header with the same key already exist, the request remains unmodified. If you want to add the header regardless of whether the header is already present, you can use
add_header.See also
add_headers_unless_existsto add multiple headers.
add_headers
val add_headers : (string * string) list -> t -> tadd_headers headers tadds the headersheadersto the requestt.The headers are added regardless of whether a header with the same key is already present. If you want to add the header only if an header with the same key could not be found, you can use
add_headers_unless_exists.See also
add_headerto add a single header.
add_headers_or_replace
val add_headers_or_replace : (string * string) list -> t -> tadd_headers_or_replace (key, value) tadds a headersheadersto the requestt.If a header with the same key already exist, its value is replaced by
value. If you want to add the header only if it doesn't already exist, you can useadd_headers_unless_exists.See also
add_header_or_replaceto add a single header.
add_headers_unless_exists
val add_headers_unless_exists : (string * string) list -> t -> tadd_headers_unless_exists headers tadds the headersheadersto the requesttif an header with the same key does not already exist.If a header with the same key already exist, the header is will not be added to the request. If you want to add the header regardless of whether the header is already present, you can use
add_headers.See also
add_header_unless_existsto add a single header.
remove_header
Specific Headers
content_type
val content_type : t -> string optioncontent_type treturns the value of the headerContent-Typeof the requestt.
set_content_type
Cookies
cookie
val cookie : ?signed_with:Cookie.Signer.t -> string -> t -> string optioncookie ?signed_with key treturns the value of the cookie with keykeyin theCookieheader of the requestt.If
signed_withis provided, the cookies will be unsigned with the given Signer and only a cookie with a valid signature will be returned.If the request does not contain a valid
Cookieor if no cookie with the keykeyexist,Nonewill be returned.
cookies
val cookies : ?signed_with:Cookie.Signer.t -> t -> Cookie.value listcookies ?signed_with treturns all the value of the cookies in theCookieheader of the requestt.If
signed_withis provided, the cookies will be unsigned with the given Signer and only the cookies with a valid signature will be returned.If the request does not contain a valid
Cookie,Nonewill be returned.
add_cookie
val add_cookie : ?sign_with:Cookie.Signer.t -> Cookie.value -> t -> tadd_cookie ?sign_with ?expires ?scope ?same_site ?secure ?http_only value tadds a cookie with valuevalueto the requestt.If a cookie with the same key already exists, its value will be replaced with the new value of
value.If
sign_withis provided, the cookie will be signed with the given Signer.
add_cookie_unless_exists
val add_cookie_unless_exists : ?sign_with:Cookie.Signer.t -> Cookie.value -> t -> tadd_cookie_unless_exists ?sign_with ?expires ?scope ?same_site ?secure ?http_only value tadds a cookie with valuevalueto the requestt.If a cookie with the same key already exists, it will remain untouched.
If
sign_withis provided, the cookie will be signed with the given Signer.
remove_cookie
Body
urlencoded
val urlencoded : string -> t -> string option Lwt.turlencoded key treturns the first value associated tokeyin the urlencoded body of the requestt.The function only returns the first value for the given key, because in the great majority of cases, there is only one parameter per key. If you want to return all the values associated to the key, you can use
to_urlencoded.If the key could not be found or if the request could not be parsed as urlencoded,
Noneis returned. Useurlencoded_exnto raise an exception instead.Example
let request = Request.of_urlencoded ~body:[ "username", [ "admin" ]; "password", [ "password" ] ] "/" `POST ;; let username = Request.urlencoded "username" requestusernamewill be:Some "admin"
urlencoded_exn
val urlencoded_exn : string -> t -> string Lwt.turlencoded_exn key treturns the first value associated tokeyin the urlencoded body of the requestt.The function only returns the first value for the given key, because in the great majority of cases, there is only one parameter per key. If you want to return all the values associated to the key, you can use
to_urlencoded.If the key could not be found or if the request could not be parsed as urlencoded, an
Invalid_argumentexception is raised. Useurlencodedto return an option instead.
urlencoded_list
val urlencoded_list : string -> t -> string list Lwt.turlencoded_list key treturns all the values associated tokeyin the urlencoded body of the requestt.If the key could not be found or if the request could not be parsed as urlencoded, an empty list
[]is returned instead.
URI
query
val query : string -> t -> string optionquery key treturns the first value associated tokeyin the URI query parameters of the requestt.The function only returns the first value for the given key, because in the great majority of cases, there is only one parameter per key. If you want to return all the values associated to the key, you can use
query_list.If the key could not be found or if the request URI does not contain any query parameter,
Noneis returned. Usequery_exnto raise an exception instead.Example
let request = Request.make "/target?key=value" `GET let query = Request.query "key" requestquerywill be:Some "value"
query_exn
val query_exn : string -> t -> stringquery_exn key treturns the first value associated tokeyin the URI query parameters of the requestt.The function only returns the first value for the given key, because in the great majority of cases, there is only one parameter per key. If you want to return all the values associated to the key, you can use
query_list.If the key could not be found or if the request URI does not contain any query parameter, an
Invalid_argumentexception is raised. Usequeryto return an option instead.
query_list
val query_list : t -> (string * string list) listquery_list key treturns all the values associated tokeyin the URI query parameters of the requestt.This function exist to offer a simple way to get all of the values associated to a key, but most of the time, there is only one value per key. If you're not specifically trying to decode a request with multiple values per key, it is recommended to use
queryinstead.If the key could not be found or if the request could not be parsed as query, an empty list is returned.
Example
let request = Request.make "/target?key=value&key2=value2" `GET let values = Request.query_list requestvalueswill be:[ "key", [ "value" ]; "key2", [ "value2" ] ]
Utilities
sexp_of_t
val sexp_of_t : t -> Sexplib0.Sexp.tsexp_of_t tconverts the requesttto an s-expression
pp
val pp : Stdlib.Format.formatter -> t -> unitppformats the requesttas an s-expression
pp_hum
val pp_hum : Stdlib.Format.formatter -> t -> unitpp_humformats the requesttas a standard HTTP request