aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/src/manual/cowboy_req.asciidoc793
-rw-r--r--doc/src/manual/cowboy_req.header.asciidoc74
-rw-r--r--doc/src/manual/cowboy_req.headers.asciidoc51
-rw-r--r--doc/src/manual/cowboy_req.host.asciidoc52
-rw-r--r--doc/src/manual/cowboy_req.method.asciidoc60
-rw-r--r--doc/src/manual/cowboy_req.path.asciidoc51
-rw-r--r--doc/src/manual/cowboy_req.peer.asciidoc61
-rw-r--r--doc/src/manual/cowboy_req.port.asciidoc52
-rw-r--r--doc/src/manual/cowboy_req.qs.asciidoc50
-rw-r--r--doc/src/manual/cowboy_req.scheme.asciidoc55
-rw-r--r--doc/src/manual/cowboy_req.uri.asciidoc116
-rw-r--r--doc/src/manual/cowboy_req.version.asciidoc49
12 files changed, 819 insertions, 645 deletions
diff --git a/doc/src/manual/cowboy_req.asciidoc b/doc/src/manual/cowboy_req.asciidoc
index e1a2c4d..b1d97ff 100644
--- a/doc/src/manual/cowboy_req.asciidoc
+++ b/doc/src/manual/cowboy_req.asciidoc
@@ -6,685 +6,188 @@ cowboy_req - HTTP request and response
== Description
-The `cowboy_req` module provides functions to access, manipulate
+The module `cowboy_req` provides functions to access, manipulate
and respond to requests.
-The functions in this module follow patterns for their return types,
-based on the kind of function.
+There are four types of functions in this module. They can be
+differentiated by their name and their return type:
-* access: `Value`
-* action: `ok | {Result, Req} | {Result, Value, Req}`
-* modification: `Req`
-* question: `boolean()`
-
-Whenever `Req` is returned, you must use this returned value and
-ignore any previous you may have had. This value contains various
-values which are necessary for Cowboy to keep track of the request
-and response states.
-
-All functions which perform an action should only be called once.
-This includes reading the request body or replying. Cowboy will
-throw an error on the second call when it detects suspicious behavior.
+[options="header"]
+|===
+| Type | Name pattern | Return type
+| access | no verb, parse_*, match_* | `Value`
+| question | has_* | `boolean()`
+| modification | set_* | `Req`
+| action | any other verb | `ok \| {Result, Value, Req}`
+|===
-It is highly discouraged to pass the Req object to another process.
-Doing so and calling `cowboy_req` functions from it leads to
-undefined behavior.
+Any `Req` returned must be used in place of the one passed as
+argument. Functions that perform an action in particular write
+state in the Req object to make sure you are using the function
+correctly. For example, it's only possible to send one response,
+and to read the body once.
+
+== Exports
+
+Raw request:
+
+* link:man:cowboy_req:method(3)[cowboy_req:method(3)] - HTTP method
+* link:man:cowboy_req:version(3)[cowboy_req:version(3)] - HTTP version
+* link:man:cowboy_req:scheme(3)[cowboy_req:scheme(3)] - URI scheme
+* link:man:cowboy_req:host(3)[cowboy_req:host(3)] - URI host name
+* link:man:cowboy_req:port(3)[cowboy_req:port(3)] - URI port number
+* link:man:cowboy_req:path(3)[cowboy_req:path(3)] - URI path
+* link:man:cowboy_req:qs(3)[cowboy_req:qs(3)] - URI query string
+* link:man:cowboy_req:uri(3)[cowboy_req:uri(3)] - Reconstructed URI
+* link:man:cowboy_req:header(3)[cowboy_req:header(3)] - HTTP header
+* link:man:cowboy_req:headers(3)[cowboy_req:headers(3)] - HTTP headers
+* link:man:cowboy_req:peer(3)[cowboy_req:peer(3)] - Peer address and port
+
+Processed request:
+
+* link:man:cowboy_req:parse_qs(3)[cowboy_req:parse_qs(3)] - Parse the query string
+* link:man:cowboy_req:match_qs(3)[cowboy_req:match_qs(3)] - Match the query string against constraints
+* link:man:cowboy_req:parse_header(3)[cowboy_req:parse_header(3)] - Parse the given HTTP header
+* link:man:cowboy_req:parse_cookies(3)[cowboy_req:parse_cookies(3)] - Parse cookie headers
+* link:man:cowboy_req:match_cookies(3)[cowboy_req:match_cookies(3)] - Match cookies against constraints
+* link:man:cowboy_req:binding(3)[cowboy_req:binding(3)] - Access a value bound from the route
+* link:man:cowboy_req:bindings(3)[cowboy_req:bindings(3)] - Access all values bound from the route
+* link:man:cowboy_req:host_info(3)[cowboy_req:host_info(3)] - Access the route's heading host segments
+* link:man:cowboy_req:path_info(3)[cowboy_req:path_info(3)] - Access the route's trailing path segments
+
+Request body:
+
+* link:man:cowboy_req:has_body(3)[cowboy_req:has_body(3)] - Is there a request body?
+* link:man:cowboy_req:body_length(3)[cowboy_req:body_length(3)] - Body length
+* link:man:cowboy_req:read_body(3)[cowboy_req:read_body(3)] - Read the request body
+* link:man:cowboy_req:read_urlencoded_body(3)[cowboy_req:read_urlencoded_body(3)] - Read and parse a urlencoded request body
+* link:man:cowboy_req:read_part(3)[cowboy_req:read_part(3)] - Read the next part of a multipart body
+* link:man:cowboy_req:read_part_body(3)[cowboy_req:read_part_body(3)] - Read the current part's body in a multipart body
+
+Response:
+
+* link:man:cowboy_req:set_resp_cookie(3)[cowboy_req:set_resp_cookie(3)] - Set a cookie
+* link:man:cowboy_req:set_resp_header(3)[cowboy_req:set_resp_header(3)] - Set a response header
+* link:man:cowboy_req:has_resp_header(3)[cowboy_req:has_resp_header(3)] - Is the given response header set?
+* link:man:cowboy_req:delete_resp_header(3)[cowboy_req:delete_resp_header(3)] - Delete a response header
+* link:man:cowboy_req:set_resp_body(3)[cowboy_req:set_resp_body(3)] - Set the response body
+* link:man:cowboy_req:has_resp_body(3)[cowboy_req:has_resp_body(3)] - Is there a response body?
+* link:man:cowboy_req:reply(3)[cowboy_req:reply(3)] - Send the response
+* link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)] - Send the response and stream its body
+* link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)] - Send a chunk of the response body
+* link:man:cowboy_req:push(3)[cowboy_req:push(3)] - Push a resource to the client
== Types
-=== body_opts() = [Option]
+=== push_opts()
[source,erlang]
----
-Option = {continue, boolean()}
- | {length, non_neg_integer()}
- | {read_length, non_neg_integer()}
- | {read_timeout, timeout()}
- | {transfer_decode, transfer_decode_fun(), any()}
- | {content_decode, content_decode_fun()}
+push_opts() :: #{
+ method => binary(), %% case sensitive
+ scheme => binary(), %% lowercase; case insensitive
+ host => binary(), %% lowercase; case insensitive
+ port => inet:port_number(),
+ qs => binary() %% case sensitive
+}
----
-Request body reading options.
+Push options.
-=== cookie_opts() = [Option]
+By default, Cowboy will use the GET method, an empty query string,
+and take the scheme, host and port directly from the current
+request's URI.
+
+=== read_body_opts()
[source,erlang]
----
-Option = {max_age, non_neg_integer()}
- | {domain, binary()}
- | {path, binary()}
- | {secure, boolean()}
- | {http_only, boolean()}
+read_body_opts() :: #{
+ length => non_neg_integer(),
+ period => non_neg_integer(),
+ timeout => timeout()
+}
----
-Cookie options.
-
-=== req() - opaque to the user
-
-The Req object.
-
-All functions in this module receive a `Req` as argument,
-and some of them return a new object labelled `Req2` in
-the function descriptions below.
-
-== Request related exports
-
-=== binding(Name, Req) -> binding(Name, Req, undefined)
-
-Alias of `cowboy_req:binding/3`.
-
-=== binding(Name, Req, Default) -> Value
-
-Name = atom():: Binding name.
-Default = any():: Default value.
-Value = any() | Default:: Binding value.
-
-Return the value for the given binding.
-
-By default the value is a binary, however constraints may change
-the type of this value (for example automatically converting
-numbers to integer).
-
-=== bindings(Req) -> [{Name, Value}]
-
-Name = atom():: Binding name.
-Value = any():: Binding value.
-
-Return all bindings.
-
-By default the value is a binary, however constraints may change
-the type of this value (for example automatically converting
-numbers to integer).
-
-=== header(Name, Req) -> header(Name, Req, undefined)
-
-Alias of `cowboy_req:header/3`.
-
-=== header(Name, Req, Default) -> Value
-
-Name = binary():: Request header name.
-Default = any():: Default value.
-Value = binary() | Default:: Request header value.
-
-Return the value for the given header.
-
-While header names are case insensitive, this function expects
-the name to be a lowercase binary.
-
-=== headers(Req) -> Headers
-
-Headers = cowboy:http_headers():: Request headers.
-
-Return all headers.
-
-=== host(Req) -> Host
-
-Host = binary():: Requested host.
-
-Return the requested host.
-
-=== host_info(Req) -> HostInfo
-
-HostInfo = cowboy_router:tokens() | undefined:: Extra tokens for the host.
-
-Return the extra tokens from matching against `...` during routing.
-
-=== host_url(Req) -> HostURL
-
-HostURL = binary() | undefined:: Requested URL, without the path component.
-
-Return the requested URL excluding the path component.
-
-This function will always return `undefined` until the
-`cowboy_router` middleware has been executed.
-
-=== match_cookies(Fields, Req) -> Map
-
-Fields = cowboy:fields():: Cookie fields match rules.
-Map = map():: Cookie fields matched.
-
-Match cookies against the given fields.
-
-Cowboy will only return the cookie values specified in the
-fields list, and ignore all others. Fields can be either
-the name of the cookie requested; the name along with a
-list of constraints; or the name, a list of constraints
-and a default value in case the cookie is missing.
-
-This function will crash if the cookie is missing and no
-default value is provided. This function will also crash
-if a constraint fails.
-
-The name of the cookie must be provided as an atom. The
-key of the returned map will be that atom. The value may
-be converted through the use of constraints, making this
-function able to extract, validate and convert values all
-in one step.
-
-=== match_qs(Fields, Req) -> Map
-
-Fields = cowboy:fields():: Query string fields match rules.
-Map = map():: Query string fields matched.
-
-Match the query string against the given fields.
-
-Cowboy will only return the query string values specified
-in the fields list, and ignore all others. Fields can be
-either the key requested; the key along with a list of
-constraints; or the key, a list of constraints and a
-default value in case the key is missing.
-
-This function will crash if the key is missing and no
-default value is provided. This function will also crash
-if a constraint fails.
-
-The key must be provided as an atom. The key of the
-returned map will be that atom. The value may be converted
-through the use of constraints, making this function able
-to extract, validate and convert values all in one step.
-
-=== meta(Name, Req) -> meta(Name, Req, undefined)
-
-Alias for `cowboy_req:meta/3`.
-
-=== meta(Name, Req, Default) -> Value
-
-Name = atom():: Metadata name.
-Default = any():: Default value.
-Value = any():: Metadata value.
-
-Return metadata about the request.
-
-=== method(Req) -> Method
-
-Method = binary():: Request method.
-
-Return the method.
-
-Methods are case sensitive. Standard methods are always uppercase.
-
-=== parse_cookies(Req) -> [{Name, Value}]
-
-Name = binary():: Cookie name.
-Value = binary():: Cookie value.
-
-Parse and return all cookies.
-
-Cookie names are case sensitive.
-
-=== parse_header(Name, Req) -> see below
-
-Alias of `cowboy_req:parse_header/3`.
-
-The `parse_header/2` function will call `parser_header/3` with a
-different default value depending on the header being parsed. The
-following table summarizes the default values used.
-
-[cols="<,^",options="header"]
-|===
-| Header name | Header value
-| content-length | `0`
-| cookie | `[]`
-| transfer-encoding | `[<<"identity">>]`
-| Any other header | `undefined`
-|===
-
-=== parse_header(Name, Req, Default) -> ParsedValue | Default
-
-Name = binary():: Request header name.
-Default = any():: Default value.
-ParsedValue - see below:: Parsed request header value.
-
-Parse the given header.
-
-While header names are case insensitive, this function expects
-the name to be a lowercase binary.
-
-The parsed value differs depending on the header being parsed. The
-following table summarizes the different types returned.
-
-[cols="<,^",options="header"]
-|===
-| Header name | Type of parsed header value
-| accept | `[{{Type, SubType, Params}, Quality, AcceptExt}]`
-| accept-charset | `[{Charset, Quality}]`
-| accept-encoding | `[{Encoding, Quality}]`
-| accept-language | `[{LanguageTag, Quality}]`
-| authorization | `{AuthType, Credentials}`
-| content-length | `non_neg_integer()`
-| content-type | `{Type, SubType, ContentTypeParams}`
-| cookie | `[{binary(), binary()}]`
-| expect | `[Expect \| {Expect, ExpectValue, Params}]`
-| if-match | `'*' \| [{weak \| strong, OpaqueTag}]`
-| if-modified-since | `calendar:datetime()`
-| if-none-match | `'*' \| [{weak \| strong, OpaqueTag}]`
-| if-unmodified-since | `calendar:datetime()`
-| range | `{Unit, [Range]}`
-| sec-websocket-protocol | `[binary()]`
-| transfer-encoding | `[binary()]`
-| upgrade | `[binary()]`
-| x-forwarded-for | `[binary()]`
-|===
-
-Types for the above table:
-
-* Type = SubType = Charset = Encoding = LanguageTag = binary()
-* AuthType = Expect = OpaqueTag = Unit = binary()
-* Params = ContentTypeParams = [{binary(), binary()}]
-* Quality = 0..1000
-* AcceptExt = [{binary(), binary()} | binary()]
-* Credentials - see below
-* Range = {non_neg_integer(), non_neg_integer() | infinity} | neg_integer()
-
-The cookie names and values, the values of the sec-websocket-protocol
-and x-forwarded-for headers, the values in `AcceptExt` and `Params`,
-the authorization `Credentials`, the `ExpectValue` and `OpaqueTag`
-are case sensitive. All values in `ContentTypeParams` are case sensitive
-except the value of the charset parameter, which is case insensitive.
-All other values are case insensitive and will be returned as lowercase.
-
-The headers accept, accept-encoding and cookie headers can return
-an empty list. Some other headers are expected to have a value if provided
-and may crash if the value is missing.
-
-The authorization header parsing code currently only supports basic
-HTTP authentication. The `Credentials` type is thus `{Username, Password}`
-with `Username` and `Password` being `binary()`.
-
-The range header value `Range` can take three forms:
-
-* `{From, To}`: from `From` to `To` units
-* `{From, infinity}`: everything after `From` units
-* `-Final`: the final `Final` units
-
-An `undefined` tuple will be returned if Cowboy doesn't know how
-to parse the requested header.
-
-=== parse_qs(Req) -> [{Name, Value}]
-
-Name = binary():: Query string field name.
-Value = binary() | true:: Query string field value.
-
-Return the request's query string as a list of tuples.
-
-The atom `true` is returned for keys which have no value.
-Keys with no value are different from keys with an empty
-value in that they do not have a `=` indicating the presence
-of a value.
-
-=== path(Req) -> Path
-
-Path = binary():: Requested path.
-
-Return the requested path.
-
-=== path_info(Req) -> PathInfo
-
-PathInfo = cowboy_router:tokens() | undefined:: Extra tokens for the path.
-
-Return the extra tokens from matching against `...` during routing.
-
-=== peer(Req) -> Peer
-
-Peer = `{inet:ip_address(), inet:port_number()}`:: Peer IP address and port number.
-
-Return the client's IP address and port number.
-
-=== port(Req) -> Port
-
-Port = inet:port_number():: Requested port number.
-
-Return the request's port.
-
-The port returned by this function is obtained by parsing
-the host header. It may be different than the actual port
-the client used to connect to the Cowboy server.
-
-=== qs(Req) -> QueryString
-
-QueryString = binary():: Unprocessed query string.
-
-Return the request's query string.
-
-=== set_meta(Name, Value, Req) -> Req2
-
-Name = atom():: Metadata name.
-Value = any():: Metadata value.
-
-Set metadata about the request.
-
-An existing value will be overwritten.
-
-=== url(Req) -> URL
-
-URL = binary() | undefined:: Requested URL.
+Body reading options.
-Return the requested URL.
+The defaults are function-specific.
-This function will always return `undefined` until the
-`cowboy_router` middleware has been executed.
+=== req()
-=== version(Req) -> Version
-
-Version = cowboy:http_version():: Client's advertised HTTP version.
-
-Return the HTTP version used for this request.
-
-== Request body related exports
-
-=== body(Req) -> body(Req, [])
-
-Alias of `cowboy_req:body/2`.
-
-=== body(Req, Opts) -> {ok, Data, Req2} | {more, Data, Req2}
-
-Opts = [body_opt()]:: Request body reading options.
-Data = binary():: Data read from the body.
-
-Read the request body.
-
-This function will read a chunk of the request body. If there is
-more data to be read after this function call, then a `more` tuple
-is returned. Otherwise an `ok` tuple is returned.
-
-Cowboy will automatically send a `100 Continue` reply if
-required. If this behavior is not desirable, it can be disabled
-by setting the `continue` option to `false`.
-
-Cowboy will by default attempt to read up to 8MB of the body,
-but in chunks of 1MB. It will use a timeout of 15s per chunk.
-All these values can be changed using the `length`, `read_length`
-and `read_timeout` options respectively. Note that the size
-of the data may not be the same as requested as the decoding
-functions may grow or shrink it, and Cowboy makes not attempt
-at returning an exact amount.
-
-Cowboy will properly handle chunked transfer-encoding by
-default. If any other transfer-encoding or content-encoding
-has been used for the request, custom decoding functions
-can be used. The `content_decode` and `transfer_decode`
-options allow setting the decode functions manually.
-
-After the body has been streamed fully, Cowboy will remove
-the transfer-encoding header from the Req object, and add
-the content-length header if it wasn't already there.
-
-This function can only be called once. Cowboy will not cache
-the result of this call.
-
-=== body_length(Req) -> Length
-
-Length = non_neg_integer() | undefined:: Length of the request body.
-
-Return the length of the request body.
-
-The length will only be returned if the request does not
-use any transfer-encoding and if the content-length header
-is present.
-
-=== body_qs(Req) -> body_qs(Req, [{length, 64000}, {read_length, 64000}, {read_timeout, 5000}])
-
-Alias of `cowboy_req:body_qs/2`.
-
-=== body_qs(Req, Opts) -> {ok, [{Name, Value}], Req2} | {badlength, Req2}
-
-Opts = [body_opt()]:: Request body reading options.
-Name = binary():: Field name.
-Value = binary() | true:: Field value.
-
-Return the request body as a list of tuples.
-
-This function will parse the body assuming the content-type
-application/x-www-form-urlencoded, commonly used for the
-query string.
-
-This function calls `body/2` for reading the body, with the
-same options it received. By default it will attempt to read
-a body of 64KB in one chunk, with a timeout of 5s. If the
-body is larger then a `badlength` tuple is returned.
-
-This function can only be called once. Cowboy will not cache
-the result of this call.
-
-=== has_body(Req) -> boolean()
-
-Return whether the request has a body.
-
-=== part(Req) -> part(Req, [{length, 64000}, {read_length, 64000}, {read_timeout, 5000}])
-
-Alias of `cowboy_req:part/2`.
-
-=== part(Req, Opts) -> {ok, Headers, Req2} | {done, Req2}
-
-Opts = [body_opt()]:: Request body reading options.
-Headers = cow_multipart:headers():: Part's headers.
-
-Read the headers for the next part of the multipart message.
-
-Cowboy will skip any data remaining until the beginning of
-the next part. This includes the preamble to the multipart
-message but also the body of a previous part if it hasn't
-been read. Both are skipped automatically when calling this
-function.
-
-The headers returned are MIME headers, NOT HTTP headers.
-They can be parsed using the functions from the `cow_multipart`
-module. In addition, the `cow_multipart:form_data/1` function
-can be used to quickly figure out `multipart/form-data` messages.
-It takes the list of headers and returns whether this part is
-a simple form field or a file being uploaded.
-
-Note that once a part has been read, or skipped, it cannot
-be read again.
-
-This function calls `body/2` for reading the body, with the
-same options it received. By default it will only read chunks
-of 64KB with a timeout of 5s. This is tailored for reading
-part headers, not for skipping the previous part's body.
-You might want to consider skipping large parts manually.
-
-=== part_body(Req) -> part_body(Req, [])
-
-Alias of `cowboy_req:part_body/2`.
-
-=== part_body(Req, Opts) -> {ok, Data, Req2} | {more, Data, Req2}
-
-Opts = [body_opt()]:: Request body reading options.
-Data = binary():: Part's body.
-
-Read the body of the current part of the multipart message.
-
-This function calls `body/2` for reading the body, with the
-same options it received. It uses the same defaults.
-
-If there are more data to be read from the socket for this
-part, the function will return what it could read inside a
-`more` tuple. Otherwise, it will return an `ok` tuple.
-
-Calling this function again after receiving a `more` tuple
-will return another chunk of body. The last chunk will be
-returned inside an `ok` tuple.
-
-Note that once the body has been read, fully or partially,
-it cannot be read again.
-
-== Response related exports
-
-=== chunk(Data, Req) -> ok
-
-Data = iodata():: Chunk data to be sent.
-
-Send a chunk of data.
-
-This function should be called as many times as needed
-to send data chunks after calling `chunked_reply/{2,3}`.
-
-When the method is HEAD, no data will actually be sent.
-
-If the request uses HTTP/1.0, the data is sent directly
-without wrapping it in an HTTP/1.1 chunk, providing
-compatibility with older clients.
-
-=== chunked_reply(StatusCode, Req) -> chunked_reply(StatusCode, [], Req)
-
-Alias of `cowboy_req:chunked_reply/3`.
-
-=== chunked_reply(StatusCode, Headers, Req) -> Req2
-
-StatusCode = cowboy:http_status():: Response status code.
-Headers = cowboy:http_headers():: Response headers.
-
-Send a response using chunked transfer-encoding.
-
-This function effectively sends the response status line
-and headers to the client.
-
-This function will not send any body set previously. After
-this call the handler must use the `chunk/2` function
-repeatedly to send the body in as many chunks as needed.
-
-If the request uses HTTP/1.0, the data is sent directly
-without wrapping it in an HTTP/1.1 chunk, providing
-compatibility with older clients.
-
-This function can only be called once, with the exception
-of overriding the response in the `onresponse` hook.
-
-=== continue(Req) -> ok
-
-Send a 100 Continue intermediate reply.
-
-This reply is required before the client starts sending the
-body when the request contains the `expect` header with the
-`100-continue` value.
-
-Cowboy will send this automatically when required. However
-you may want to do it manually by disabling this behavior
-with the `continue` body option and then calling this
-function.
-
-=== delete_resp_header(Name, Req) -> Req2
-
-Name = binary():: Response header name.
-
-Delete the given response header.
-
-While header names are case insensitive, this function expects
-the name to be a lowercase binary.
-
-=== has_resp_body(Req) -> boolean()
-
-Return whether a response body has been set.
-
-This function will return false if a response body has
-been set with a length of 0.
-
-=== has_resp_header(Name, Req) -> boolean()
-
-Name = binary():: Response header name.
-
-Return whether the given response header has been set.
-
-While header names are case insensitive, this function expects
-the name to be a lowercase binary.
-
-=== reply(StatusCode, Req) -> reply(StatusCode, [], Req)
-
-Alias of `cowboy_req:reply/3`.
-
-=== reply(StatusCode, Headers, Req) - see below
-
-Alias of `cowboy_req:reply/4`, with caveats.
-
-=== reply(StatusCode, Headers, Body, Req) -> Req2
-
-StatusCode = cowboy:http_status():: Response status code.
-Headers = cowboy:http_headers():: Response headers.
-Body = iodata():: Response body.
-
-Send a response.
-
-This function effectively sends the response status line,
-headers and body to the client, in a single send function
-call.
-
-The `reply/2` and `reply/3` functions will send the body
-set previously, if any. The `reply/4` function overrides
-any body set previously and sends `Body` instead.
-
-If a body function was set, and `reply/2` or `reply/3` was
-used, it will be called before returning.
-
-No more data can be sent to the client after this function
-returns.
-
-This function can only be called once, with the exception
-of overriding the response in the `onresponse` hook.
-
-=== set_resp_body(Body, Req) -> Req2
-
-Body = iodata():: Response body.
-
-Set a response body.
-
-This body will not be sent if `chunked_reply/{2,3}` or
-`reply/4` is used, as they override it.
-
-=== set_resp_body_fun(Fun, Req) -> Req2
-
-Alias of `cowboy_req:set_resp_body_fun/3`.
-
-=== set_resp_body_fun(Length, Fun, Req) -> Req2
-
-Fun = fun((Socket, Transport) -> ok):: Fun that will send the response body.
-Socket = inet:socket():: Socket for this connection.
-Transport = module():: Transport module for this socket.
-Length = non_neg_integer():: Length of the response body.
-
-Set a fun for sending the response body.
+[source,erlang]
+----
+req() :: #{
+ method := binary(), %% case sensitive
+ version := cowboy:http_version() | atom(),
+ scheme := binary(), %% lowercase; case insensitive
+ host := binary(), %% lowercase; case insensitive
+ port := inet:port_number(),
+ path := binary(), %% case sensitive
+ qs := binary(), %% case sensitive
+ headers := cowboy:http_headers(),
+ peer := {inet:ip_address(), inet:port_number()}
+}
+----
-If a `Length` is provided, it will be sent in the
-content-length header in the response. It is recommended
-to set the length if it can be known in advance. Otherwise,
-the transfer-encoding header will be set to identity.
+The Req object.
-This function will only be called if the response is sent
-using the `reply/2` or `reply/3` function.
+Contains information about the request and response. While
+some fields are publicly documented, others aren't and shouldn't
+be used.
-The fun will receive the Ranch `Socket` and `Transport` as
-arguments. Only send and sendfile operations are supported.
+You may add custom fields if required. Make sure to namespace
+them by prepending an underscore and the name of your application:
-=== set_resp_body_fun(chunked, Fun, Req) -> Req2
+.Setting a custom field
+[source,erlang]
+----
+Req#{_myapp_auth_method => pubkey}.
+----
-Fun = fun((ChunkFun) -> ok):: Fun that will send the response body.
-ChunkFun = fun((iodata()) -> ok):: Fun to call for every chunk to be sent.
+=== resp_body()
-Set a fun for sending the response body using chunked transfer-encoding.
+[source,erlang]
+----
+resp_body() :: iodata()
+ | {sendfile, Offset, Length, Filename}
-This function will only be called if the response is sent
-using the `reply/2` or `reply/3` function.
+Offset :: non_neg_integer()
+Length :: pos_integer()
+Filename :: file:name_all()
+----
-The fun will receive another fun as argument. This fun is to
-be used to send chunks in a similar way to the `chunk/2` function,
-except the fun only takes one argument, the data to be sent in
-the chunk.
+Response body.
-=== set_resp_cookie(Name, Value, Opts, Req) -> Req2
+It can take two forms: the actual data to be sent or a
+tuple indicating which file to send.
-Name = iodata():: Cookie name.
-Value = iodata():: Cookie value.
-Opts = cookie_opts():: Cookie options.
+When sending data directly, the type is either a binary or
+an iolist. Iolists are an efficient way to build output.
+Instead of concatenating strings or binaries, you can simply
+build a list containing the fragments you want to send in the
+order they should be sent:
-Set a cookie in the response.
+.Example iolists usage
+[source,erlang]
+----
+1> RespBody = ["Hello ", [<<"world">>, $!]].
+["Hello ",[<<"world">>,33]]
+2> io:format("~s~n", [RespBody]).
+Hello world!
+----
-Cookie names are case sensitive.
+When using the sendfile tuple, the `Length` value is mandatory
+and must be higher than 0. It is sent with the response in the
+content-length header.
-=== set_resp_header(Name, Value, Req) -> Req2
+// @todo Make sure we have a test with an empty file...
+// @todo cowboy_static should probably NOT return a sendfile tuple if size is 0.
-Name = binary():: Response header name.
-Value = iodata():: Response header value.
+//%% While sendfile allows a Len of 0 that means "everything past Offset",
+//%% Cowboy expects the real length as it is used as metadata.
+//%% @todo We should probably explicitly reject it.
-Set a response header.
+== See also
-You should use `set_resp_cookie/4` instead of this function
-to set cookies.
+link:man:cowboy(7)[cowboy(7)]
diff --git a/doc/src/manual/cowboy_req.header.asciidoc b/doc/src/manual/cowboy_req.header.asciidoc
new file mode 100644
index 0000000..e16b902
--- /dev/null
+++ b/doc/src/manual/cowboy_req.header.asciidoc
@@ -0,0 +1,74 @@
+= cowboy_req:header(3)
+
+== Name
+
+cowboy_req:header - HTTP header
+
+== Description
+
+[source,erlang]
+----
+header(Name :: binary(), Req) -> header(Name, Req, undefined)
+header(Name :: binary(), Req, Default) -> binary() | Default
+
+Req :: cowboy_req:req()
+----
+
+Return the value for the given HTTP header.
+
+The header name must be given as a lowercase binary string.
+While header names are case insensitive, Cowboy requires them
+to be given as lowercase to function properly.
+
+Headers can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{headers := #{Name := Value}} = Req.
+----
+
+Note that this snippet will crash if the header is missing.
+
+== Arguments
+
+Name::
+
+Desired HTTP header name as a binary string.
+
+Req::
+
+The Req object.
+
+Default::
+
+Default value returned when the header is missing.
+
+== Return value
+
+The header value is returned as a binary string. When the
+header is missing, the default argument is returned.
+
+== Changelog
+
+* *2.0*: Only the header value is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get the accept header
+[source,erlang]
+----
+Accept = cowboy_req:header(<<"accept">>, Req).
+----
+
+.Get the content-length header with a default value
+[source,erlang]
+----
+Length = cowboy_req:header(<<"content-length">>, Req, <<"0">>).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:headers(3)[cowboy_req:headers(3)],
+link:man:cowboy_req:parse_header(3)[cowboy_req:parse_header(3)]
diff --git a/doc/src/manual/cowboy_req.headers.asciidoc b/doc/src/manual/cowboy_req.headers.asciidoc
new file mode 100644
index 0000000..c370f6d
--- /dev/null
+++ b/doc/src/manual/cowboy_req.headers.asciidoc
@@ -0,0 +1,51 @@
+= cowboy_req:headers(3)
+
+== Name
+
+cowboy_req:headers - HTTP headers
+
+== Description
+
+[source,erlang]
+----
+headers(Req :: cowboy_req:req()) -> cowboy:http_headers()
+----
+
+Return all request headers.
+
+Request headers can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{headers := Headers} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+Headers are returned as a map with keys being lowercase
+binary strings, and values as binary strings.
+
+== Changelog
+
+* *2.0*: Only the headers are returned, they are no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get all headers
+[source,erlang]
+----
+Headers = cowboy_req:headers(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:header(3)[cowboy_req:header(3)],
+link:man:cowboy_req:parse_header(3)[cowboy_req:parse_header(3)]
diff --git a/doc/src/manual/cowboy_req.host.asciidoc b/doc/src/manual/cowboy_req.host.asciidoc
new file mode 100644
index 0000000..2c512e2
--- /dev/null
+++ b/doc/src/manual/cowboy_req.host.asciidoc
@@ -0,0 +1,52 @@
+= cowboy_req:host(3)
+
+== Name
+
+cowboy_req:host - URI host name
+
+== Description
+
+[source,erlang]
+----
+host(Req :: cowboy_req:req()) -> Host :: binary()
+----
+
+Return the host name of the effective request URI.
+
+The host name can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{host := Host} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The host name is returned as a lowercase binary string.
+It is case insensitive.
+
+== Changelog
+
+* *2.0*: Only the host name is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get the effective request URI's host name
+[source,erlang]
+----
+Host = cowboy_req:host(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:binding(3)[cowboy_req:binding(3)],
+link:man:cowboy_req:bindings(3)[cowboy_req:bindings(3)],
+link:man:cowboy_req:host_info(3)[cowboy_req:host_info(3)]
diff --git a/doc/src/manual/cowboy_req.method.asciidoc b/doc/src/manual/cowboy_req.method.asciidoc
new file mode 100644
index 0000000..bb3ad6e
--- /dev/null
+++ b/doc/src/manual/cowboy_req.method.asciidoc
@@ -0,0 +1,60 @@
+= cowboy_req:method(3)
+
+== Name
+
+cowboy_req:method - HTTP method
+
+== Description
+
+[source,erlang]
+----
+method(Req :: cowboy_req:req()) -> Method :: binary()
+----
+
+Return the request's HTTP method.
+
+The method can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{method := Method} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The request's HTTP method is returned as a binary string.
+While methods are case sensitive, standard methods are
+always uppercase.
+
+== Changelog
+
+* *2.0*: Only the method is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Ensure the request's method is GET
+[source,erlang]
+----
+<<"GET">> = cowboy_req:method(Req).
+----
+
+.Allow methods from list
+[source,erlang]
+----
+init(Req, State) ->
+ case lists:member(cowboy_req:method(Req), [<<"GET">>, <<"POST">>]) of
+ true -> handle(Req, State);
+ false -> method_not_allowed(Req, State)
+ end.
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)]
diff --git a/doc/src/manual/cowboy_req.path.asciidoc b/doc/src/manual/cowboy_req.path.asciidoc
new file mode 100644
index 0000000..5f26548
--- /dev/null
+++ b/doc/src/manual/cowboy_req.path.asciidoc
@@ -0,0 +1,51 @@
+= cowboy_req:path(3)
+
+== Name
+
+cowboy_req:path - URI path
+
+== Description
+
+[source,erlang]
+----
+path(Req :: cowboy_req:req()) -> Path :: binary()
+----
+
+Return the path of the effective request URI.
+
+The path can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{path := Path} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The path is returned as a binary string. It is case sensitive.
+
+== Changelog
+
+* *2.0*: Only the path is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get the effective request URI's path
+[source,erlang]
+----
+Path = cowboy_req:path(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:binding(3)[cowboy_req:binding(3)],
+link:man:cowboy_req:bindings(3)[cowboy_req:bindings(3)],
+link:man:cowboy_req:path_info(3)[cowboy_req:path_info(3)]
diff --git a/doc/src/manual/cowboy_req.peer.asciidoc b/doc/src/manual/cowboy_req.peer.asciidoc
new file mode 100644
index 0000000..e2df691
--- /dev/null
+++ b/doc/src/manual/cowboy_req.peer.asciidoc
@@ -0,0 +1,61 @@
+= cowboy_req:peer(3)
+
+== Name
+
+cowboy_req:peer - Peer address and port
+
+== Description
+
+[source,erlang]
+----
+peer(Req :: cowboy_req:req()) -> Peer
+
+Peer :: {inet:ip_address(), inet:port_number()}
+----
+
+Return the peer's IP address and port number.
+
+The peer can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{peer := {IP, Port}} = Req.
+----
+
+// @todo So we need tests for accessing the Req directly.
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The peer's IP address and port number.
+
+The peer is not necessarily the client's IP address and port.
+It is the IP address of the endpoint connecting directly to
+the server, which may be a gateway or a proxy.
+
+The forwarded header can be used to get better information
+about the different endpoints from the client to the server.
+Note however that it is only informative; there is no reliable
+way of determining the source of an HTTP request.
+
+== Changelog
+
+* *2.0*: Only the peer is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get the peer IP address and port number.
+[source,erlang]
+----
+{IP, Port} = cowboy_req:peer(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)]
diff --git a/doc/src/manual/cowboy_req.port.asciidoc b/doc/src/manual/cowboy_req.port.asciidoc
new file mode 100644
index 0000000..57f0875
--- /dev/null
+++ b/doc/src/manual/cowboy_req.port.asciidoc
@@ -0,0 +1,52 @@
+= cowboy_req:port(3)
+
+== Name
+
+cowboy_req:port - URI port number
+
+== Description
+
+[source,erlang]
+----
+port(Req :: cowboy_req:req()) -> Port :: inet:port_number()
+----
+
+Return the port number of the effective request URI.
+
+Note that the port number returned by this function is obtained
+by parsing the host header. It may be different from the port
+the peer used to connect to Cowboy.
+
+The port number can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{port := Port} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The port number is returned as an integer.
+
+== Changelog
+
+* *2.0*: Only the port number is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get the effective request URI's port number
+[source,erlang]
+----
+Port = cowboy_req:port(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)]
diff --git a/doc/src/manual/cowboy_req.qs.asciidoc b/doc/src/manual/cowboy_req.qs.asciidoc
new file mode 100644
index 0000000..6e92357
--- /dev/null
+++ b/doc/src/manual/cowboy_req.qs.asciidoc
@@ -0,0 +1,50 @@
+= cowboy_req:qs(3)
+
+== Name
+
+cowboy_req:qs - URI query string
+
+== Description
+
+[source,erlang]
+----
+qs(Req :: cowboy_req:req()) -> Qs :: binary()
+----
+
+Return the query string of the effective request URI.
+
+The query string can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{qs := Qs} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The query string is returned as a binary string. It is case sensitive.
+
+== Changelog
+
+* *2.0*: Only the query string is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get the effective request URI's query string
+[source,erlang]
+----
+Qs = cowboy_req:qs(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:parse_qs(3)[cowboy_req:parse_qs(3)],
+link:man:cowboy_req:match_qs(3)[cowboy_req:match_qs(3)]
diff --git a/doc/src/manual/cowboy_req.scheme.asciidoc b/doc/src/manual/cowboy_req.scheme.asciidoc
new file mode 100644
index 0000000..bbe147d
--- /dev/null
+++ b/doc/src/manual/cowboy_req.scheme.asciidoc
@@ -0,0 +1,55 @@
+= cowboy_req:scheme(3)
+
+== Name
+
+cowboy_req:scheme - URI scheme
+
+== Description
+
+[source,erlang]
+----
+scheme(Req :: cowboy_req:req()) -> Scheme :: binary()
+----
+
+Return the scheme of the effective request URI.
+
+The scheme can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{scheme := Scheme} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The scheme is returned as a binary. It is case insensitive.
+
+Cowboy will only set the scheme to `<<"http">>` or `<<"https">>`.
+
+== Changelog
+
+* *2.0*: Function introduced.
+
+== Examples
+
+.Redirect HTTP to HTTPS
+[source,erlang]
+----
+init(Req0=#{scheme := <<"http">>}, State) ->
+ Req = cowboy_req:reply(302, #{
+ <<"location">> => cowboy_req:uri(Req, #{scheme => <<"https">>})
+ }, Req0),
+ {ok, Req, State};
+init(Req, State) ->
+ {cowboy_rest, Req, State}.
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)]
diff --git a/doc/src/manual/cowboy_req.uri.asciidoc b/doc/src/manual/cowboy_req.uri.asciidoc
new file mode 100644
index 0000000..790f863
--- /dev/null
+++ b/doc/src/manual/cowboy_req.uri.asciidoc
@@ -0,0 +1,116 @@
+= cowboy_req:uri(3)
+
+== Name
+
+cowboy_req:uri - Reconstructed URI
+
+== Description
+
+[source,erlang]
+----
+uri(Req :: cowboy_req:req()) -> uri(Req, #{})
+uri(Req :: cowboy_req:req(), Opts) -> URI :: iodata()
+
+Opts :: #{
+ scheme => iodata() | undefined,
+ host => iodata() | undefined,
+ port => inet:port_number() | undefined,
+ path => iodata() | undefined,
+ qs => iodata() | undefined,
+ fragment => iodata() | undefined
+}
+----
+
+Reconstruct the effective request URI, optionally modifying components.
+
+By default Cowboy will build a URI using the components found
+in the request. Options allow disabling or replacing individual
+components.
+
+== Arguments
+
+Req::
+
+The Req object.
+
+Opts::
+
+Map for overriding individual components.
++
+To replace a component, provide its new value as a binary
+string or an iolist. To disable a component, set its value
+to `undefined`.
++
+As this function always returns a valid URI, there are some
+things to note:
++
+ * Disabling the host also disables the scheme and port.
+ * There is no fragment component by default as these are
+ not sent with the request.
+ * The port number may not appear in the resulting URI if
+ it is the default port for the given scheme (http: 80; https: 443).
+
+== Return value
+
+The reconstructed URI is returned as an iolist or a binary string.
+
+== Changelog
+
+* *2.0*: Individual components can be replaced or disabled.
+* *2.0*: Only the URI is returned, it is no longer wrapped in a tuple.
+* *2.0*: Function introduced. Replaces `host_url/1` and `url/1`.
+
+== Examples
+
+With an effective request URI http://example.org/path/to/res?edit=1
+we can have:
+
+.Protocol relative form
+[source,erlang]
+----
+%% //example.org/path/to/res?edit=1
+cowboy_req:uri(Req, #{scheme => undefined}).
+----
+
+.Serialized origin for use in the origin header
+[source,erlang]
+----
+%% http://example.org
+cowboy_req:uri(Req, #{path => undefined, qs => undefined}).
+----
+
+.HTTP/1.1 origin form (path and query string only)
+[source,erlang]
+----
+%% /path/to/res?edit=1
+cowboy_req:uri(Req, #{host => undefined}).
+----
+
+.Add a fragment to the URI
+[source,erlang]
+----
+%% http://example.org/path/to/res?edit=1#errors
+cowboy_req:uri(Req, #{fragment => <<"errors">>}).
+----
+
+.Ensure the scheme is HTTPS
+[source,erlang]
+----
+%% https://example.org/path/to/res?edit=1
+cowboy_req:uri(Req, #{scheme => <<"https">>}).
+----
+
+.Convert the URI to a binary string
+[source,erlang]
+----
+iolist_to_binary(cowboy_req:uri(Req)).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:scheme(3)[cowboy_req:scheme(3)],
+link:man:cowboy_req:host(3)[cowboy_req:host(3)],
+link:man:cowboy_req:port(3)[cowboy_req:port(3)],
+link:man:cowboy_req:path(3)[cowboy_req:path(3)],
+link:man:cowboy_req:qs(3)[cowboy_req:qs(3)]
diff --git a/doc/src/manual/cowboy_req.version.asciidoc b/doc/src/manual/cowboy_req.version.asciidoc
new file mode 100644
index 0000000..15920c4
--- /dev/null
+++ b/doc/src/manual/cowboy_req.version.asciidoc
@@ -0,0 +1,49 @@
+= cowboy_req:version(3)
+
+== Name
+
+cowboy_req:version - HTTP version
+
+== Description
+
+[source,erlang]
+----
+version(Req :: cowboy_req:req()) -> Version :: cowboy:http_version()
+----
+
+Return the HTTP version used for the request.
+
+The version can also be obtained using pattern matching:
+
+[source,erlang]
+----
+#{version := Version} = Req.
+----
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+The HTTP version used for the request is returned as an
+atom. It is provided for informative purposes only.
+
+== Changelog
+
+* *2.0*: Only the version is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Get the HTTP version
+[source,erlang]
+----
+Version = cowboy_req:version(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)]