From 4023e7f4e429179fd9c2cce4487c33646c6bd327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 14 Jan 2016 13:35:25 +0100 Subject: Convert the documentation to Asciidoc A few small revisions were made, and Erlang.mk has been updated. --- doc/src/manual/cowboy_req.asciidoc | 690 +++++++++++++++++++++++++++++++++++++ 1 file changed, 690 insertions(+) create mode 100644 doc/src/manual/cowboy_req.asciidoc (limited to 'doc/src/manual/cowboy_req.asciidoc') diff --git a/doc/src/manual/cowboy_req.asciidoc b/doc/src/manual/cowboy_req.asciidoc new file mode 100644 index 0000000..558592b --- /dev/null +++ b/doc/src/manual/cowboy_req.asciidoc @@ -0,0 +1,690 @@ += cowboy_req(3) + +== Name + +cowboy_req - HTTP request and response + +== Description + +The `cowboy_req` module 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. + +* 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. + +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. + +== Types + +=== body_opts() = [Option] + +[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()} +---- + +Request body reading options. + +=== cookie_opts() = [Option] + +[source,erlang] +---- +Option = {max_age, non_neg_integer()} + | {domain, binary()} + | {path, binary()} + | {secure, boolean()} + | {http_only, boolean()} +---- + +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. + +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. -- cgit v1.2.3