0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Partially update manual for the cowboy_req

Only the access functions have been modified so far.
This commit is contained in:
Loïc Hoguin 2016-11-05 14:17:30 +02:00
parent 8fe700f341
commit faca7866ed
No known key found for this signature in database
GPG key ID: 71366FF21851DF03
16 changed files with 1409 additions and 895 deletions

View file

@ -21,6 +21,8 @@ DEPS = cowlib ranch
dep_cowlib = git https://github.com/ninenines/cowlib master
dep_ranch = git https://github.com/ninenines/ranch 1.2.1
DOC_DEPS = asciideck
TEST_DEPS = ct_helper gun
dep_ct_helper = git https://github.com/extend/ct_helper master
dep_gun = git https://github.com/ninenines/gun master

View file

@ -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()`
[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}`
|===
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.
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.
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.
== Exports
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.
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.
Body reading options.
=== req() - opaque to the user
The defaults are function-specific.
=== req()
[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()}
}
----
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.
Contains information about the request and response. While
some fields are publicly documented, others aren't and shouldn't
be used.
== Request related exports
You may add custom fields if required. Make sure to namespace
them by prepending an underscore and the name of your application:
=== binding(Name, Req) -> binding(Name, Req, undefined)
.Setting a custom field
[source,erlang]
----
Req#{_myapp_auth_method => pubkey}.
----
Alias of `cowboy_req:binding/3`.
=== resp_body()
=== binding(Name, Req, Default) -> Value
[source,erlang]
----
resp_body() :: iodata()
| {sendfile, Offset, Length, Filename}
Name = atom():: Binding name.
Default = any():: Default value.
Value = any() | Default:: Binding value.
Offset :: non_neg_integer()
Length :: pos_integer()
Filename :: file:name_all()
----
Return the value for the given binding.
Response body.
By default the value is a binary, however constraints may change
the type of this value (for example automatically converting
numbers to integer).
It can take two forms: the actual data to be sent or a
tuple indicating which file to send.
=== bindings(Req) -> [{Name, Value}]
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:
Name = atom():: Binding name.
Value = any():: Binding value.
.Example iolists usage
[source,erlang]
----
1> RespBody = ["Hello ", [<<"world">>, $!]].
["Hello ",[<<"world">>,33]]
2> io:format("~s~n", [RespBody]).
Hello world!
----
Return all bindings.
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.
By default the value is a binary, however constraints may change
the type of this value (for example automatically converting
numbers to integer).
// @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.
=== header(Name, Req) -> header(Name, Req, undefined)
//%% 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.
Alias of `cowboy_req:header/3`.
== See also
=== 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.
Return the requested URL.
This function will always return `undefined` until the
`cowboy_router` middleware has been executed.
=== 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.
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.
This function will only be called if the response is sent
using the `reply/2` or `reply/3` function.
The fun will receive the Ranch `Socket` and `Transport` as
arguments. Only send and sendfile operations are supported.
=== set_resp_body_fun(chunked, Fun, Req) -> Req2
Fun = fun((ChunkFun) -> ok):: Fun that will send the response body.
ChunkFun = fun((iodata()) -> ok):: Fun to call for every chunk to be sent.
Set a fun for sending the response body using chunked transfer-encoding.
This function will only be called if the response is sent
using the `reply/2` or `reply/3` function.
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.
=== set_resp_cookie(Name, Value, Opts, Req) -> Req2
Name = iodata():: Cookie name.
Value = iodata():: Cookie value.
Opts = cookie_opts():: Cookie options.
Set a cookie in the response.
Cookie names are case sensitive.
=== set_resp_header(Name, Value, Req) -> Req2
Name = binary():: Response header name.
Value = iodata():: Response header value.
Set a response header.
You should use `set_resp_cookie/4` instead of this function
to set cookies.
link:man:cowboy(7)[cowboy(7)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -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)]

View file

@ -1,8 +1,9 @@
{application, cowboy, [
{description, "Small, fast, modern HTTP server."},
{vsn, "2.0.0-pre.2"},
{vsn, "2.0.0-pre.4"},
{modules, ['cowboy','cowboy_app','cowboy_bstr','cowboy_clear','cowboy_clock','cowboy_constraints','cowboy_handler','cowboy_http','cowboy_http2','cowboy_loop','cowboy_middleware','cowboy_req','cowboy_rest','cowboy_router','cowboy_static','cowboy_stream','cowboy_stream_h','cowboy_sub_protocol','cowboy_sup','cowboy_tls','cowboy_websocket']},
{registered, [cowboy_sup,cowboy_clock]},
{applications, [kernel,stdlib,crypto,cowlib,ranch]},
{mod, {cowboy_app, []}}
{mod, {cowboy_app, []}},
{env, []}
]}.

829
erlang.mk vendored

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,4 @@
{deps, [{cowlib,".*",{git,"https://github.com/ninenines/cowlib","master"}},{ranch,".*",{git,"https://github.com/ninenines/ranch","1.2.1"}}]}.
{deps, [
{cowlib,".*",{git,"https://github.com/ninenines/cowlib","master"}},{ranch,".*",{git,"https://github.com/ninenines/ranch","1.2.1"}}
]}.
{erl_opts, [debug_info,warn_export_vars,warn_shadow_vars,warn_obsolete_guard,warn_export_all,warn_missing_spec,warn_untyped_record]}.