diff options
Diffstat (limited to 'docs/en/cowboy/2.0/guide/req.asciidoc')
-rw-r--r-- | docs/en/cowboy/2.0/guide/req.asciidoc | 366 |
1 files changed, 0 insertions, 366 deletions
diff --git a/docs/en/cowboy/2.0/guide/req.asciidoc b/docs/en/cowboy/2.0/guide/req.asciidoc deleted file mode 100644 index b879fa3d..00000000 --- a/docs/en/cowboy/2.0/guide/req.asciidoc +++ /dev/null @@ -1,366 +0,0 @@ -[[req]] -== The Req object - -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`; -and the connection `peer` address and port. - -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) -> - Req = cowboy_req:reply(200, #{ - <<"content-type">> => <<"text/plain">> - }, <<"Hello world!">>, Req0), - {ok, Req, State}; -init(Req0, State) -> - Req = cowboy_req:reply(405, #{ - <<"allow">> => <<"GET">> - }, Req0), - {ok, Req, State}. ----- - -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. - -// @todo There are currently no tests for direct access. - -=== Introduction to the cowboy_req interface - -// @todo Link to cowboy_req manual - -Functions in the `cowboy_req` module provide access to -the request information but also various operations that -are common when dealing with HTTP requests. - -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). - -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. - -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. - -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. - -=== Request method - -The request method can be retrieved directly: - -[source, erlang] -#{method := Method} = Req. - -Or using a function: - -[source,erlang] -Method = cowboy_req:method(Req). - -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: - -[source,erlang] -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] ----- -#{ - scheme := Scheme, - host := Host, - port := Port, - path := Path, - qs := Qs -} = Req. ----- - -Or using the related functions: - -[source,erlang] -Scheme = cowboy_req:scheme(Req), -Host = cowboy_req:host(Req), -Port = cowboy_req:port(Req), -Path = cowboy_req:path(Req). -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. - -Cowboy defines only the `<<"http">>` and `<<"https">>` schemes. -They are chosen so that the scheme will only be `<<"https">>` -for requests on secure HTTP/1.1 or HTTP/2 connections. -// @todo Is that tested well? - -The effective request URI itself can be reconstructed with -the `cowboy_req:uri/1,2` function. By default, an absolute -URI is returned: - -[source,erlang] -%% 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}). - -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. - -=== Bindings - -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: - -[source,erlang] -Value = cowboy_req:binding(userid, Req). - -When attempting to retrieve a value that was not bound, -`undefined` will be returned. A different default value -can be provided: - -[source,erlang] -Value = cowboy_req:binding(userid, Req, 42). - -To retrieve everything that was bound: - -[source,erlang] -Bindings = cowboy_req:bindings(Req). - -They are returned as a map, with keys being atoms. - -The Cowboy router also allows you to capture many host -or path segments at once using the `...` qualifier. - -To retrieve the segments captured from the host name: - -[source,erlang] -HostInfo = cowboy_req:host_info(Req). - -And the path segments: - -[source,erlang] -PathInfo = cowboy_req:path_info(Req). - -Cowboy will return `undefined` if `...` was not used -in the route. - -=== Query parameters - -Cowboy provides two functions to access query parameters. -You can use the first to get the entire list of parameters. - -[source,erlang] -QsVals = cowboy_req:parse_qs(Req), -{_, Lang} = lists:keyfind(<<"lang">>, 1, QsVals). - -Cowboy will only parse the query string, and not do any -transformation. This function may therefore return duplicates, -or parameter names without an associated value. The order of -the list returned is undefined. - -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 -time do any post processing you require using xref:constraints[constraints]. -This function returns a map. - -[source,erlang] -#{id := ID, lang := Lang} = cowboy_req:match_qs([id, lang], Req). - -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: - -[source,erlang] -QsMap = cowboy_req:match_qs([{id, int}, {lang, nonempty}], Req). - -A default value may also be provided. The default will be used -if the `lang` key is not found. It will not be used if -the key is found but has an empty value. - -[source,erlang] -#{lang := Lang} = cowboy_req:match_qs([{lang, [], <<"en-US">>}], Req). - -If no default is provided and the value is missing, the -query string is deemed invalid and the process will crash. - -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. - -=== Headers - -Header values can be retrieved either as a binary string -or parsed into a more meaningful representation. - -The get the raw value: - -[source,erlang] -HeaderVal = cowboy_req:header(<<"content-type">>, Req). - -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: - -[source,erlang] -HeaderVal = cowboy_req:header(<<"content-type">>, Req, <<"text/plain">>). - -All headers can be retrieved at once, either directly: - -[source,erlang] -#{headers := AllHeaders} = Req. - -Or using a function: - -[source,erlang] -AllHeaders = cowboy_req:headers(Req). - -Cowboy provides equivalent functions to parse individual -headers. There is no function to parse all headers at once. - -To parse a specific header: - -[source,erlang] -ParsedVal = cowboy_req:parse_header(<<"content-type">>, Req). - -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. - -When the header is missing, `undefined` is returned. You can -change the default value. Note that it should be the parsed value -directly: - -[source,erlang] ----- -ParsedVal = cowboy_req:parse_header(<<"content-type">>, Req, - {<<"text">>, <<"plain">>, []}). ----- - -=== Peer - -The peer address and port number for the connection can be -retrieved either directly or using a function. - -To retrieve the peer directly: - -[source,erlang] -#{peer := {IP, Port}} = Req. - -And using a function: - -[source,erlang] -{IP, Port} = cowboy_req:peer(Req). - -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. |