2016-01-14 13:35:25 +01:00
|
|
|
[[req]]
|
|
|
|
== The Req object
|
2013-01-01 18:27:41 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
The Req object is a variable used for obtaining information
|
|
|
|
about a request, read its body or send a response.
|
|
|
|
|
|
|
|
It is not really an object in the object-oriented sense.
|
|
|
|
It is a simple map that can be directly accessed or
|
|
|
|
used when calling functions from the `cowboy_req` module.
|
|
|
|
|
|
|
|
The Req object is the subject of a few different chapters.
|
|
|
|
In this chapter we will learn about the Req object and
|
|
|
|
look at how to retrieve information about the request.
|
|
|
|
|
|
|
|
=== Direct access
|
|
|
|
|
|
|
|
The Req map contains a number of fields which are documented
|
|
|
|
and can be accessed directly. They are the fields that have
|
|
|
|
a direct mapping to HTTP: the request `method`; the HTTP
|
|
|
|
`version` used; the effective URI components `scheme`,
|
|
|
|
`host`, `port`, `path` and `qs`; the request `headers`;
|
2018-06-11 20:51:57 +02:00
|
|
|
the connection `peer` address and port; and the TLS
|
|
|
|
certificate `cert` when applicable.
|
2016-08-24 17:25:33 +02:00
|
|
|
|
|
|
|
Note that the `version` field can be used to determine
|
|
|
|
whether a connection is using HTTP/2.
|
|
|
|
|
|
|
|
To access a field, you can simply match in the function
|
|
|
|
head. The following example sends a simple "Hello world!"
|
|
|
|
response when the `method` is GET, and a 405 error
|
|
|
|
otherwise.
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
----
|
|
|
|
init(Req0=#{method := <<"GET">>}, State) ->
|
2016-09-14 18:51:11 +02:00
|
|
|
Req = cowboy_req:reply(200, #{
|
|
|
|
<<"content-type">> => <<"text/plain">>
|
|
|
|
}, <<"Hello world!">>, Req0),
|
|
|
|
{ok, Req, State};
|
2016-08-24 17:25:33 +02:00
|
|
|
init(Req0, State) ->
|
2016-09-14 18:51:11 +02:00
|
|
|
Req = cowboy_req:reply(405, #{
|
|
|
|
<<"allow">> => <<"GET">>
|
|
|
|
}, Req0),
|
|
|
|
{ok, Req, State}.
|
2016-08-24 17:25:33 +02:00
|
|
|
----
|
|
|
|
|
|
|
|
Any other field is internal and should not be accessed.
|
|
|
|
They may change in future releases, including maintenance
|
|
|
|
releases, without notice.
|
|
|
|
|
|
|
|
Modifying the Req object, while allowed, is not recommended
|
|
|
|
unless strictly necessary. If adding new fields, make sure
|
|
|
|
to namespace the field names so that no conflict can occur
|
|
|
|
with future Cowboy updates or third party projects.
|
|
|
|
|
|
|
|
=== Introduction to the cowboy_req interface
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
// @todo Link to cowboy_req manual
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Functions in the `cowboy_req` module provide access to
|
|
|
|
the request information but also various operations that
|
|
|
|
are common when dealing with HTTP requests.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
All the functions that begin with a verb indicate an action.
|
|
|
|
Other functions simply return the corresponding value
|
|
|
|
(sometimes that value does need to be built, but the
|
|
|
|
cost of the operation is equivalent to retrieving a value).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Some of the `cowboy_req` functions return an updated Req
|
|
|
|
object. They are the read, reply, set and delete functions.
|
|
|
|
While ignoring the returned Req will not cause incorrect
|
|
|
|
behavior for some of them, it is highly recommended to
|
|
|
|
always keep and use the last returned Req object. The
|
|
|
|
manual for `cowboy_req` details these functions and what
|
|
|
|
modifications are done to the Req object.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Some of the calls to `cowboy_req` have side effects. This
|
|
|
|
is the case of the read and reply functions. Cowboy reads
|
|
|
|
the request body or replies immediately when the function
|
|
|
|
is called.
|
2014-09-23 16:43:29 +03:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
All functions will crash if something goes wrong. There
|
|
|
|
is usually no need to catch these errors, Cowboy will
|
|
|
|
send the appropriate 4xx or 5xx response depending on
|
|
|
|
where the crash occurred.
|
2014-09-23 16:43:29 +03:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
=== Request method
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
The request method can be retrieved directly:
|
2013-01-01 18:27:41 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
[source, erlang]
|
|
|
|
#{method := Method} = Req.
|
2013-01-18 18:04:21 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Or using a function:
|
2013-01-18 18:04:21 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
Method = cowboy_req:method(Req).
|
2013-01-01 18:27:41 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
The method is a case sensitive binary string. Standard
|
|
|
|
methods include GET, HEAD, OPTIONS, PATCH, POST, PUT
|
|
|
|
or DELETE.
|
|
|
|
|
|
|
|
=== HTTP version
|
|
|
|
|
|
|
|
The HTTP version is informational. It does not indicate that
|
|
|
|
the client implements the protocol well or fully.
|
|
|
|
|
|
|
|
There is typically no need to change behavior based on the
|
|
|
|
HTTP version: Cowboy already does it for you.
|
|
|
|
|
|
|
|
It can be useful in some cases, though. For example, one may
|
|
|
|
want to redirect HTTP/1.1 clients to use Websocket, while HTTP/2
|
|
|
|
clients keep using HTTP/2.
|
|
|
|
|
|
|
|
The HTTP version can be retrieved directly:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
#{version := Version} = Req.
|
|
|
|
|
|
|
|
Or using a function:
|
2013-01-01 18:27:41 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2016-08-24 17:25:33 +02:00
|
|
|
Version = cowboy_req:version(Req).
|
|
|
|
|
|
|
|
Cowboy defines the `'HTTP/1.0'`, `'HTTP/1.1'` and `'HTTP/2'`
|
|
|
|
versions. Custom protocols can define their own values as
|
|
|
|
atoms.
|
|
|
|
|
|
|
|
=== Effective request URI
|
|
|
|
|
|
|
|
The scheme, host, port, path and query string components
|
|
|
|
of the effective request URI can all be retrieved directly:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
----
|
|
|
|
#{
|
2016-09-14 18:51:11 +02:00
|
|
|
scheme := Scheme,
|
|
|
|
host := Host,
|
|
|
|
port := Port,
|
|
|
|
path := Path,
|
|
|
|
qs := Qs
|
2016-08-24 17:25:33 +02:00
|
|
|
} = Req.
|
|
|
|
----
|
|
|
|
|
|
|
|
Or using the related functions:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
Scheme = cowboy_req:scheme(Req),
|
2014-09-23 16:43:29 +03:00
|
|
|
Host = cowboy_req:host(Req),
|
|
|
|
Port = cowboy_req:port(Req),
|
|
|
|
Path = cowboy_req:path(Req).
|
2016-08-24 17:25:33 +02:00
|
|
|
Qs = cowboy_req:qs(Req).
|
|
|
|
|
|
|
|
The scheme and host are lowercased case insensitive binary
|
|
|
|
strings. The port is an integer representing the port number.
|
|
|
|
The path and query string are case sensitive binary strings.
|
|
|
|
|
2016-08-30 14:18:14 +02:00
|
|
|
Cowboy defines only the `<<"http">>` and `<<"https">>` schemes.
|
|
|
|
They are chosen so that the scheme will only be `<<"https">>`
|
2016-08-24 17:25:33 +02:00
|
|
|
for requests on secure HTTP/1.1 or HTTP/2 connections.
|
|
|
|
// @todo Is that tested well?
|
2013-01-01 18:27:41 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
The effective request URI itself can be reconstructed with
|
|
|
|
the `cowboy_req:uri/1,2` function. By default, an absolute
|
|
|
|
URI is returned:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2016-08-24 17:25:33 +02:00
|
|
|
%% scheme://host[:port]/path[?qs]
|
|
|
|
URI = cowboy_req:uri(Req).
|
|
|
|
|
|
|
|
Options are available to either disable or replace some
|
|
|
|
or all of the components. Various URIs or URI formats can
|
|
|
|
be generated this way, including the origin form:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
%% /path[?qs]
|
|
|
|
URI = cowboy_req:uri(Req, #{host => undefined}).
|
|
|
|
|
|
|
|
The protocol relative form:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
%% //host[:port]/path[?qs]
|
|
|
|
URI = cowboy_req:uri(Req, #{scheme => undefined}).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
The absolute URI without a query string:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
URI = cowboy_req:uri(Req, #{qs => undefined}).
|
|
|
|
|
|
|
|
A different host:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
URI = cowboy_req:uri(Req, #{host => <<"example.org">>}).
|
|
|
|
|
|
|
|
And any other combination.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
=== Bindings
|
2013-01-01 18:27:41 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Bindings are the host and path components that you chose
|
|
|
|
to extract when defining the routes of your application.
|
|
|
|
They are only available after the routing.
|
|
|
|
|
|
|
|
Cowboy provides functions to retrieve one or all bindings.
|
|
|
|
|
|
|
|
To retrieve a single value:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2016-08-24 17:25:33 +02:00
|
|
|
Value = cowboy_req:binding(userid, Req).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
When attempting to retrieve a value that was not bound,
|
|
|
|
`undefined` will be returned. A different default value
|
|
|
|
can be provided:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2016-08-24 17:25:33 +02:00
|
|
|
Value = cowboy_req:binding(userid, Req, 42).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
To retrieve everything that was bound:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2016-08-24 17:25:33 +02:00
|
|
|
Bindings = cowboy_req:bindings(Req).
|
|
|
|
|
2017-02-19 16:51:16 +01:00
|
|
|
They are returned as a map, with keys being atoms.
|
2016-08-24 17:25:33 +02:00
|
|
|
|
|
|
|
The Cowboy router also allows you to capture many host
|
|
|
|
or path segments at once using the `...` qualifier.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
To retrieve the segments captured from the host name:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
HostInfo = cowboy_req:host_info(Req).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
And the path segments:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
PathInfo = cowboy_req:path_info(Req).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Cowboy will return `undefined` if `...` was not used
|
|
|
|
in the route.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
=== Query parameters
|
2014-09-23 16:43:29 +03:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Cowboy provides two functions to access query parameters.
|
|
|
|
You can use the first to get the entire list of parameters.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
QsVals = cowboy_req:parse_qs(Req),
|
|
|
|
{_, Lang} = lists:keyfind(<<"lang">>, 1, QsVals).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Cowboy will only parse the query string, and not do any
|
|
|
|
transformation. This function may therefore return duplicates,
|
2016-08-25 17:40:37 +02:00
|
|
|
or parameter names without an associated value. The order of
|
|
|
|
the list returned is undefined.
|
2016-08-24 17:25:33 +02:00
|
|
|
|
|
|
|
When a query string is `key=1&key=2`, the list returned will
|
|
|
|
contain two parameters of name `key`.
|
|
|
|
|
|
|
|
The same is true when trying to use the PHP-style suffix `[]`.
|
|
|
|
When a query string is `key[]=1&key[]=2`, the list returned will
|
|
|
|
contain two parameters of name `key[]`.
|
|
|
|
|
|
|
|
When a query string is simply `key`, Cowboy will return the
|
|
|
|
list `[{<<"key">>, true}]`, using `true` to indicate that the
|
|
|
|
parameter `key` was defined, but with no value.
|
|
|
|
|
|
|
|
The second function Cowboy provides allows you to match out
|
|
|
|
only the parameters you are interested in, and at the same
|
2016-08-30 13:23:31 +02:00
|
|
|
time do any post processing you require using xref:constraints[constraints].
|
2016-08-24 17:25:33 +02:00
|
|
|
This function returns a map.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-10-04 13:21:16 +03:00
|
|
|
#{id := ID, lang := Lang} = cowboy_req:match_qs([id, lang], Req).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Constraints can be applied automatically. The following
|
|
|
|
snippet will crash when the `id` parameter is not an integer,
|
|
|
|
or when the `lang` parameter is empty. At the same time, the
|
|
|
|
value for `id` will be converted to an integer term:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-10-04 13:21:16 +03:00
|
|
|
QsMap = cowboy_req:match_qs([{id, int}, {lang, nonempty}], Req).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
A default value may also be provided. The default will be used
|
2014-09-23 16:43:29 +03:00
|
|
|
if the `lang` key is not found. It will not be used if
|
|
|
|
the key is found but has an empty value.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-10-04 13:21:16 +03:00
|
|
|
#{lang := Lang} = cowboy_req:match_qs([{lang, [], <<"en-US">>}], Req).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2014-09-23 16:43:29 +03:00
|
|
|
If no default is provided and the value is missing, the
|
|
|
|
query string is deemed invalid and the process will crash.
|
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
When the query string is `key=1&key=2`, the value for `key`
|
|
|
|
will be the list `[1, 2]`. Parameter names do not need to
|
|
|
|
include the PHP-style suffix. Constraints may be used to
|
|
|
|
ensure that only one value was passed through.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
=== Headers
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Header values can be retrieved either as a binary string
|
2013-09-23 15:44:10 +02:00
|
|
|
or parsed into a more meaningful representation.
|
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
The get the raw value:
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
HeaderVal = cowboy_req:header(<<"content-type">>, Req).
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Cowboy expects all header names to be provided as lowercase
|
|
|
|
binary strings. This is true for both requests and responses,
|
|
|
|
regardless of the underlying protocol.
|
|
|
|
|
|
|
|
When the header is missing from the request, `undefined`
|
|
|
|
will be returned. A different default can be provided:
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
|
|
|
HeaderVal = cowboy_req:header(<<"content-type">>, Req, <<"text/plain">>).
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
All headers can be retrieved at once, either directly:
|
|
|
|
|
|
|
|
[source,erlang]
|
|
|
|
#{headers := AllHeaders} = Req.
|
|
|
|
|
|
|
|
Or using a function:
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
AllHeaders = cowboy_req:headers(Req).
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
Cowboy provides equivalent functions to parse individual
|
|
|
|
headers. There is no function to parse all headers at once.
|
|
|
|
|
|
|
|
To parse a specific header:
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
ParsedVal = cowboy_req:parse_header(<<"content-type">>, Req).
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
An exception will be thrown if it doesn't know how to parse the
|
|
|
|
given header, or if the value is invalid. The list of known headers
|
|
|
|
and default values can be found in the manual.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
When the header is missing, `undefined` is returned. You can
|
|
|
|
change the default value. Note that it should be the parsed value
|
|
|
|
directly:
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
|
|
|
----
|
2014-09-23 16:43:29 +03:00
|
|
|
ParsedVal = cowboy_req:parse_header(<<"content-type">>, Req,
|
2016-09-14 18:51:11 +02:00
|
|
|
{<<"text">>, <<"plain">>, []}).
|
2016-01-14 13:35:25 +01:00
|
|
|
----
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
=== Peer
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
The peer address and port number for the connection can be
|
|
|
|
retrieved either directly or using a function.
|
2013-01-20 15:09:54 +01:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
To retrieve the peer directly:
|
2013-01-29 13:32:48 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2016-08-24 17:25:33 +02:00
|
|
|
#{peer := {IP, Port}} = Req.
|
2013-09-23 15:44:10 +02:00
|
|
|
|
2016-08-24 17:25:33 +02:00
|
|
|
And using a function:
|
2013-01-29 13:32:48 +01:00
|
|
|
|
2016-01-14 13:35:25 +01:00
|
|
|
[source,erlang]
|
2014-09-23 16:43:29 +03:00
|
|
|
{IP, Port} = cowboy_req:peer(Req).
|
2016-08-24 17:25:33 +02:00
|
|
|
|
|
|
|
Note that the peer corresponds to the remote end of the
|
|
|
|
connection to the server, which may or may not be the
|
|
|
|
client itself. It may also be a proxy or a gateway.
|