diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/src/guide/resource_design.asciidoc | 9 | ||||
-rw-r--r-- | doc/src/manual/cowboy_rest.asciidoc | 757 | ||||
-rw-r--r-- | doc/src/manual/cowboy_static.asciidoc | 2 |
3 files changed, 454 insertions, 314 deletions
diff --git a/doc/src/guide/resource_design.asciidoc b/doc/src/guide/resource_design.asciidoc index 691953f..2325b9f 100644 --- a/doc/src/guide/resource_design.asciidoc +++ b/doc/src/guide/resource_design.asciidoc @@ -164,11 +164,10 @@ implement the `moved_permanently` callback. === The request -Do we need to perform extra checks to make sure the request -is valid? Cowboy will do many checks when receiving the -request already, do we need more? Note that this only -applies to the request-line and headers of the request, -and not the body. Implement `malformed_request`. +Do you need to read the query string? Individual headers? +Implement `malformed_request` and do all the parsing and +validation in this function. Note that the body should not +be read at this point. May there be a request body? Will I know its size? What's the maximum size of the request body I'm willing diff --git a/doc/src/manual/cowboy_rest.asciidoc b/doc/src/manual/cowboy_rest.asciidoc index edf4b5c..26515fb 100644 --- a/doc/src/manual/cowboy_rest.asciidoc +++ b/doc/src/manual/cowboy_rest.asciidoc @@ -6,287 +6,363 @@ cowboy_rest - REST handlers == Description -The `cowboy_rest` module implements REST semantics on top of -the HTTP protocol. +The module `cowboy_rest` implements the HTTP state machine. -This module is a sub protocol that defines many callbacks -be implemented by handlers. The `init/2` and `terminate/3` -callbacks are common to all handler types and are documented -in the manual for the link:cowboy_handler.asciidoc[cowboy_handler] module. +Implementing REST handlers is not enough to provide a REST +interface; this interface must also follow the REST +constraints including HATEOAS (hypermedia as the engine +of application state). -All other callbacks are optional, though some may become -required depending on the return value of previous callbacks. +== Callbacks + +REST handlers implement the following interface: + +[source,erlang] +---- +init(Req, State) + -> {cowboy_rest, Req, State} + | {cowboy_rest, Req, State, hibernate} + | {cowboy_rest, Req, State, timeout()} + | {cowboy_rest, Req, State, timeout(), hibernate} + +Callback(Req, State) + -> {Result, Req, State} + | {stop, Req, State} -== Meta values +terminate(Reason, Req, State) -> ok %% optional -charset = binary():: - Negotiated charset. - + - This value may not be defined if no charset was negotiated. +Req :: cowboy_req:req() +State :: any() +Reason :: normal + | {crash, error | exit | throw, any()} -language = binary():: - Negotiated language. - + - This value may not be defined if no language was negotiated. +Callback - see below +Result - see below +Default - see below +---- -media_type = {binary(), binary(), '*' | [{binary(), binary()}]}:: - Negotiated media-type. - + - The media-type is the content-type, excluding the charset. - + - This value is always defined after the call to - `content_types_provided/2`. +The `init/2` callback is common to all handlers. To switch +to the REST handler behavior, it must return `cowboy_rest` +as the first element of the tuple. -== Terminate reasons +The `Callback/2` above represents all the REST-specific +callbacks. They are described in the following section +of this manual. REST-specific callbacks differ by their +name, semantics, result and default values. The default +value is the one used when the callback has not been +implemented. They otherwise all follow the same interface. -The following values may be received as the terminate reason -in the optional `terminate/3` callback. +The `stop` tuple can be returned to stop REST processing. +If no response was sent before then, Cowboy will send a +'204 No Content'. + +The optional `terminate/3` callback will ultimately be called +with the reason for the termination of the handler. +Cowboy will terminate the process right after this. There +is no need to perform any cleanup in this callback. + +The following terminate reasons are defined for loop handlers: normal:: - The connection was closed normally. + The handler terminated normally. {crash, Class, Reason}:: - A crash occurred in the handler. `Class` and `Reason` can be - used to obtain more information about the crash. The function - `erlang:get_stacktrace/0` can also be called to obtain the - stacktrace of the process when the crash occurred. + A crash occurred in the handler. `Class` and `Reason` can be + used to obtain more information about the crash. The function + `erlang:get_stacktrace/0` can also be called to obtain the + stacktrace of the process when the crash occurred. -== Callbacks +== REST callbacks -=== Callback(Req, State) -> {Value, Req, State} | {stop, Req, State} +=== AcceptCallback -Callback:: One of the REST callbacks described below. -Req = cowboy_req:req():: The Req object. -State = any():: Handler state. -Value:: See the REST callbacks description below. +// @todo The flowcharts should rename AcceptResource into AcceptCallback. -Please see the REST callbacks description below for details -on the `Value` type, the default value if the callback is -not defined, and more general information on when the -callback is called and what its intended use is. +[source,erlang] +---- +AcceptCallback(Req, State) -> {Result, Req, State} -The `stop` tuple can be returned to stop REST processing. -It is up to the resource code to send a reply before that, -otherwise a `204 No Content` will be sent. +Result :: true | {true, URI :: iodata()} | false} +Default - crash +---- + +Process the request body. + +This function should create or update the resource using the +request body. -== REST callbacks description +For PUT requests, the body is a representation of the resource +that is being created or replaced. + +For POST requests, the body is typically application-specific +instructions on how to process the request, but it may also +be a representation of the resource. When creating a new +resource with POST at a different location, return `{true, URI}` +with `URI` the new location. + +For PATCH requests, the body is a series of instructions on +how to update the resource. Patch files or JSON Patch are +examples of such media types. + +A response body may be sent. The appropriate media type, charset +and language for the response can be retrieved from the Req +object using the `media_type`, `charset` and `language` keys, +respectively. The body can be set using +link:man:cowboy_req:set_resp_body(3)[cowboy_req:set_resp_body(3)]. === allowed_methods -Methods:: all -Value type:: [binary()] -Default value:: `[<<"GET">>, <<"HEAD">>, <<"OPTIONS">>]` +[source,erlang] +---- +allowed_methods(Req, State) -> {Result, Req, State} -Return the list of allowed methods. +Result :: [binary()] %% case sensitive +Default :: [<<"GET">>, <<"HEAD">>, <<"OPTIONS">>] +---- -Methods are case sensitive. Standard methods are always uppercase. +Return the list of allowed methods. === allow_missing_post -Methods:: POST -Value type:: boolean() -Default value:: true +[source,erlang] +---- +allow_missing_post(Req, State) -> {Result, Req, State} + +Result :: boolean() +Default :: true +---- Return whether POST is allowed when the resource doesn't exist. Returning `true` here means that a new resource will be -created. The URL to the created resource should also be -returned from the `AcceptResource` callback. +created. The URI for the newly created resource should be +returned from the `AcceptCallback` function. === charsets_provided -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: [binary()] -Default behavior:: Skip to the next step if undefined. +[source,erlang] +---- +charsets_provided(Req, State) -> {Result, Req, State} -Return the list of charsets the resource provides. +Result :: [binary()] %% lowercase; case insensitive +Default - skip this step +---- -The list must be ordered in order of preference. +Return the list of charsets the resource provides in order +of preference. -If the accept-charset header was not sent, the first charset -in the list will be selected. Otherwise Cowboy will select -the most appropriate charset from the list. +During content negotiation Cowboy will pick the most +appropriate charset for the client. The client advertises +charsets it prefers with the accept-charset header. When +that header is missing, Cowboy picks the first charset +from the resource. -The chosen charset will be set in the `Req` object as the meta -value `charset`. +// @todo We should explain precisely how charsets are picked. -While charsets are case insensitive, this callback is expected -to return them as lowercase binary. +Cowboy will add the negotiated `charset` to the Req object +after this step completes: + +[source,erlang] +---- +req() :: #{ + charset => binary() %% lowercase; case insensitive +} +---- === content_types_accepted -Methods:: POST, PUT, PATCH -Value type:: [{binary() | {Type, SubType, Params}, AcceptResource}] -Default behavior:: Crash if undefined. +[source,erlang] +---- +content_types_accepted(Req, State) -> {Result, Req, State} -With types: +Result :: [{binary() | ParsedMime, AcceptCallback :: atom()}] +ParsedMime :: {Type :: binary(), SubType :: binary(), '*' | Params} +Params :: [{Key :: binary(), Value :: binary()}] -* Type = SubType = binary() -* Params = '*' | [{binary(), binary()}] -* AcceptResource = atom() +Default - crash +---- -Return the list of content-types the resource accepts. +// @todo Case sensitivity of parsed mime content? -The list must be ordered in order of preference. +Return the list of media types the resource accepts in +order of preference. -Each content-type can be given either as a binary string or as -a tuple containing the type, subtype and parameters. +A media type is made of different parts. The media type +`text/html;charset=utf-8` is of type `text`, subtype `html` +and has a single parameter `charset` with value `utf-8`. -Cowboy will select the most appropriate content-type from the list. -If any parameter is acceptable, then the tuple form should be used -with parameters set to `'*'`. If the parameters value is set to `[]` -only content-type values with no parameters will be accepted. All -parameter values are treated in a case sensitive manner except the -`charset` parameter, if present, which is case insensitive. +// @todo Cowboy needs to ignore the boundary parameter for +// multipart, as we never want to match against it. Or allow +// ignoring specific parameters at the very least. -This function will be called for POST, PUT and PATCH requests. -It is entirely possible to define different callbacks for different -methods if the handling of the request differs. Simply verify -what the method is with `cowboy_req:method/1` and return a -different list for each methods. +Cowboy will match the content-type request header against +the media types the server accepts and select the appropriate +callback. When that header is missing, or when the server does not +accept this media type, the request fails and an error response +is returned. Cowboy will execute the callback immediately otherwise. -The `AcceptResource` value is the name of the callback that will -be called if the content-type matches. It is defined as follows. +// @todo We should explain precisely how media types are picked. -Value type:: true | {true, URL} | false -Default behavior:: Crash if undefined. +An empty parameters list `[]` means that no parameters will be +accepted. When any parameter is acceptable, the tuple form +should be used with parameters as the atom `'*'`. -Process the request body. +Cowboy treats all parameters as case sensitive, except for the +`charset` parameter, which is known to be case insensitive. You +should therefore always provide the charset as a lowercase +binary string. -This function should create or update the resource with the -information contained in the request body. This information -may be full or partial depending on the request method. +// @todo Maybe this should be in the user guide instead. +//This function will be called for POST, PUT and PATCH requests. +//It is entirely possible to define different callbacks for different +//methods if the handling of the request differs. Simply verify +//what the method is with `cowboy_req:method/1` and return a +//different list for each methods. -If the request body was processed successfully, `true` must -be returned. If the request method is POST, `{true, URL}` may -be returned instead, and Cowboy will redirect the client to -the location of the newly created resource. +=== content_types_provided -If a response body must be sent, the appropriate media-type, charset -and language can be retrieved using the `cowboy_req:meta/{2,3}` -functions. The respective keys are `media_type`, `charset` -and `language`. The body can be set using `cowboy_req:set_resp_body/2`. +[source,erlang] +---- +content_types_provided(Req, State) -> {Result, Req, State} -=== content_types_provided +Result :: [{binary() | ParsedMime, ProvideCallback :: atom()}] +ParsedMime :: {Type :: binary(), SubType :: binary(), '*' | Params} +Params :: [{Key :: binary(), Value :: binary()}] -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: [{binary() | {Type, SubType, Params}, ProvideResource}] +Default - [{{ <<"text">>, <<"html">>, '*'}, to_html}] +---- + +// @todo Case sensitivity of parsed mime content? // @todo Space required for the time being: https://github.com/spf13/hugo/issues/2398 -Default value:: `[{{ <<"text">>, <<"html">>, '*'}, to_html}]` -With types: +Return the list of media types the resource provides in +order of preference. -* Type = SubType = binary() -* Params = '*' | [{binary(), binary()}] -* ProvideResource = atom() +A media type is made of different parts. The media type +`text/html;charset=utf-8` is of type `text`, subtype `html` +and has a single parameter `charset` with value `utf-8`. -Return the list of content-types the resource provides. +// @todo Cowboy needs to ignore the boundary parameter for +// multipart, as we never want to match against it. Or allow +// ignoring specific parameters at the very least. -The list must be ordered in order of preference. +During content negotiation Cowboy will pick the most appropriate +media type for the client. The client advertises media types it +prefers with the accept header. When that header is missing, +the content negotiation fails and an error response is returned. -Each content-type can be given either as a binary string or as -a tuple containing the type, subtype and parameters. +The callback given for the selected media type will be called +at the end of the execution of GET and HEAD requests when a +representation must be sent to the client. -Cowboy will select the most appropriate content-type from the list. -If any parameter is acceptable, then the tuple form should be used -with parameters set to `'*'`. If the parameters value is set to `[]` -only content-type values with no parameters will be accepted. All -parameter values are treated in a case sensitive manner except the -`charset` parameter, if present, which is case insensitive. +// @todo We should explain precisely how media types are picked. -The `ProvideResource` value is the name of the callback that will -be called if the content-type matches. It will only be called when -a representation of the resource needs to be returned. It is defined -as follow. +An empty parameters list `[]` means that no parameters will be +accepted. When any parameter is acceptable, the tuple form +should be used with parameters as the atom `'*'`. -Methods:: GET, HEAD -Value type:: iodata() | {stream, Fun} | {stream, Len, Fun} | {chunked, ChunkedFun} -Default behavior:: Crash if undefined. +Cowboy treats all parameters as case sensitive, except for the +`charset` parameter, which is known to be case insensitive. You +should therefore always provide the charset as a lowercase +binary string. -Return the response body. +Cowboy will add the negotiated `media_type` to the Req object +after this step completes: -The response body may be provided directly or through a fun. -If a fun tuple is returned, the appropriate `set_resp_body_fun` -function will be called. Please refer to the documentation for -these functions for more information about the types. +[source,erlang] +---- +req() :: #{ + media_type => ParsedMime +} +---- -The call to this callback happens a good time after the call to -`content_types_provided/2`, when it is time to start rendering -the response body. +// @todo Case sensitivity of parsed mime content? === delete_completed -Methods:: DELETE -Value type:: boolean() -Default value:: true +[source,erlang] +---- +delete_completed(Req, State) -> {Result, Req, State} -Return whether the delete action has been completed. +Result :: boolean() +Default :: true +---- -This function should return `false` if there is no guarantee -that the resource gets deleted immediately from the system, -including from any internal cache. +Return whether the resource has been fully deleted from the +system, including from any internal cache. -When this function returns `false`, a `202 Accepted` -response will be sent instead of a `200 OK` or `204 No Content`. +Returning `false` will result in a '202 Accepted' response +being sent instead of a '200 OK' or '204 No Content'. === delete_resource -Methods:: DELETE -Value type:: boolean() -Default value:: false +[source,erlang] +---- +delete_resource(Req, State) -> {Result, Req, State} + +Result :: boolean() +Default :: false +---- Delete the resource. -The value returned indicates if the action was successful, -regardless of whether the resource is immediately deleted -from the system. +Cowboy will send an error response when this function +returns `false`. === expires -Methods:: GET, HEAD -Value type:: calendar:datetime() | binary() | undefined -Default value:: undefined +[source,erlang] +---- +expires(Req, State) -> {Result, Req, State} -Return the date of expiration of the resource. +Result :: calendar:datetime() | binary() | undefined +Default :: undefined +---- -This date will be sent as the value of the expires header. +Return the resource's expiration date. === forbidden -Methods:: all -Value type:: boolean() -Default value:: false +[source,erlang] +---- +forbidden(Req, State) -> {Result, Req, State} + +Result :: boolean() +Default :: false +---- Return whether access to the resource is forbidden. -A `403 Forbidden` response will be sent if this +A '403 Forbidden' response will be sent if this function returns `true`. This status code means that access is forbidden regardless of authentication, and that the request shouldn't be repeated. === generate_etag -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: binary() | {weak | strong, binary()} -Default value:: undefined +[source,erlang] +---- +generate_etag(Req, State) -> {Result, Req, State} -Return the entity tag of the resource. +Result :: binary() | {weak | strong, binary()} +Default - no etag value +---- -This value will be sent as the value of the etag header. +Return the entity tag of the resource. -If a binary is returned, then the value will be parsed -to the tuple form automatically. The value must be in -the same format as the etag header, including quotes. +When a binary is returned, the value is automatically +parsed to a tuple. The binary must be in the same +format as the etag header, including quotes. === is_authorized -Methods:: all -Value type:: true | {false, AuthHeader} -Default value:: true +[source,erlang] +---- +is_authorized(Req, State) -> {Result, Req, State} -With types: - -* AuthHead = iodata() +Result :: true | {false, AuthHeader :: iodata()} +Default - true +---- Return whether the user is authorized to perform the action. @@ -294,26 +370,34 @@ This function should be used to perform any necessary authentication of the user before attempting to perform any action on the resource. -If the authentication fails, the value returned will be sent -as the value for the www-authenticate header in the -`401 Unauthorized` response. +When authentication fails, the `AuthHeader` value will +be sent in the www-authenticate header for the +'401 Unauthorized' response. === is_conflict -Methods:: PUT -Value type:: boolean() -Default value:: false +[source,erlang] +---- +is_conflict(Req, State) -> {Result, Req, State} + +Result :: boolean() +Default :: false +---- -Return whether the put action results in a conflict. +Return whether the PUT request results in a conflict. -A `409 Conflict` response will be sent if this function -returns `true`. +A '409 Conflict' response is sent when `true`. === known_methods -Methods:: all -Value type:: [binary()] -Default value:: `[<<"GET">>, <<"HEAD">>, <<"POST">>, <<"PUT">>, <<"PATCH">>, <<"DELETE">>, <<"OPTIONS">>]` +[source,erlang] +---- +known_methods(Req, State) -> {Result, Req, State} + +Result :: [binary()] %% case sensitive +Default :: [<<"GET">>, <<"HEAD">>, <<"POST">>, <<"PUT">>, + <<"PATCH">>, <<"DELETE">>, <<"OPTIONS">>] +---- Return the list of known methods. @@ -323,208 +407,263 @@ returned, regardless of their use in the resource. The default value lists the methods Cowboy knows and implement in `cowboy_rest`. -Methods are case sensitive. Standard methods are always uppercase. - === languages_provided -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: [binary()] -Default behavior:: Skip to the next step if undefined. +[source,erlang] +---- +languages_provided(Req, State) -> {Result, Req, State} + +Result :: [binary()] %% lowercase; case insensitive +Default - skip this step +---- -Return the list of languages the resource provides. +Return the list of languages the resource provides in order +of preference. -The list must be ordered in order of preference. +During content negotiation Cowboy will pick the most +appropriate language for the client. The client advertises +languages it prefers with the accept-language header. When +that header is missing, Cowboy picks the first language +from the resource. -If the accept-language header was not sent, the first language -in the list will be selected. Otherwise Cowboy will select -the most appropriate language from the list. +// @todo We should explain precisely how languages are picked. -The chosen language will be set in the `Req` object as the meta -value `language`. +Cowboy will add the negotiated `language` to the Req object +after this step completes: -While languages are case insensitive, this callback is expected -to return them as lowercase binary. +[source,erlang] +---- +req() :: #{ + language => binary() %% lowercase; case insensitive +} +---- === last_modified -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: calendar:datetime() -Default value:: undefined +[source,erlang] +---- +last_modified(Req, State) -> {Result, Req, State} -Return the date of last modification of the resource. +Result :: calendar:datetime() +Default - no last modified value +---- + +Return the resource's last modification date. This date will be used to test against the if-modified-since and if-unmodified-since headers, and sent as the last-modified -header in the response of GET and HEAD requests. +header in the response to GET and HEAD requests. === malformed_request -Methods:: all -Value type:: boolean() -Default value:: false +[source,erlang] +---- +malformed_request(Req, State) -> {Result, Req, State} -Return whether the request is malformed. +Result :: boolean() +Default :: false +---- -Cowboy has already performed all the necessary checks -by the time this function is called, so few resources -are expected to implement it. +Return whether the request is malformed. -The check is to be done on the request itself, not on -the request body, which is processed later. +A request is malformed when a component required by the +resource is invalid. This may include the query string +or individual headers. They should be parsed and validated +in this function. The body should not be read at this point. === moved_permanently -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: {true, URL} | false -Default value:: false - -With types: +[source,erlang] +---- +moved_permanently(Req, State) -> {Result, Req, State} -* URL = iodata() +Result :: {true, URI :: iodata()} | false +Default :: false +---- -Return whether the resource was permanently moved. - -If it was, its new URL is also returned and sent in the -location header in the response. +Return whether the resource was permanently moved, and +what its new location is. === moved_temporarily -Methods:: GET, HEAD, POST, PATCH, DELETE -Value type:: {true, URL} | false -Default value:: false +[source,erlang] +---- +moved_temporarily(Req, State) -> {Result, Req, State} -With types: +Result :: {true, URI :: iodata()} | false +Default :: false +---- -* URL = iodata() +Return whether the resource was temporarily moved, and +what its new location is. -Return whether the resource was temporarily moved. +=== multiple_choices -If it was, its new URL is also returned and sent in the -location header in the response. +[source,erlang] +---- +multiple_choices(Req, State) -> {Result, Req, State} -=== multiple_choices +Result :: boolean() +Default :: false +---- -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: boolean() -Default value:: false +Return whether the client should engage in reactive +negotiation. -Return whether there are multiple representations of the resource. +Return `true` when the server has multiple representations +of a resource, each with their specific identifier, but is +unable to determine which is best for the client. For +example an image might have different sizes and the server +is unable to determine the capabilities of the client. -This function should be used to inform the client if there -are different representations of the resource, for example -different content-type. If this function returns `true`, -the response body should include information about these -different representations using `cowboy_req:set_resp_body/2`. -The content-type of the response should be the one previously -negociated and that can be obtained by calling -`cowboy_req:meta(media_type, Req)`. +When returning `true` the server should send a body with +links to the different representations. If the server has +a preferred representation it can send its link inside a +location header. === options -Methods:: OPTIONS -Value type:: ok -Default value:: ok +[source,erlang] +---- +options(Req, State) -> {ok, Req, State} +---- -Handle a request for information. +Respond to an OPTIONS request. The response should inform the client the communication -options available for this resource. - -By default, Cowboy will send a `200 OK` response with the -allow header set. +options available for this resource. By default Cowboy +will send a '200 OK' response with the allow header set. === previously_existed -Methods:: GET, HEAD, POST, PATCH, DELETE -Value type:: boolean() -Default value:: false +[source,erlang] +---- +previously_existed(Req, State) -> {Result, Req, State} + +Result :: boolean() +Default :: false +---- Return whether the resource existed previously. +=== ProvideCallback + +[source,erlang] +---- +ProvideCallback(Req, State) -> {Result, Req, State} + +Result :: cowboy_req:resp_body() +Default - crash +---- + +Return the response body. + +The response body can be provided either as the actual data +to be sent or a tuple indicating which file to send. + +This function is called for both GET and HEAD requests. For +the latter the body is not sent, however. + +// @todo Perhaps we can optimize HEAD requests and just +// allow calculating the length instead of returning the +// whole thing. + +Note that there used to be a way to stream the response body. +It was temporarily removed and will be added back in a later +release. + +// @todo Add a way to switch to loop handler for streaming the body. + === resource_exists -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: boolean() -Default value:: true +[source,erlang] +---- +resource_exists(Req, State) -> {Result, Req, State} -Return whether the resource exists. +Result :: boolean() +Default :: true +---- -If it exists, conditional headers will be tested before -attempting to perform the action. Otherwise, Cowboy will -check if the resource previously existed first. +Return whether the resource exists. === service_available -Methods:: all -Value type:: boolean() -Default value:: true +[source,erlang] +---- +service_available(Req, State) -> {Result, Req, State} -Return whether the service is available. +Result :: boolean() +Default :: true +---- -This function can be used to test that all relevant backend -systems are up and able to handle requests. +Return whether the service is available. -A `503 Service Unavailable` response will be sent if this +A '503 Service Unavailable' response will be sent when this function returns `false`. === uri_too_long -Methods:: all -Value type:: boolean() -Default value:: false +[source,erlang] +---- +uri_too_long(Req, State) -> {Result, Req, State} -Return whether the requested URI is too long. +Result :: boolean() +Default :: false +---- -Cowboy has already performed all the necessary checks -by the time this function is called, so few resources -are expected to implement it. +Return whether the requested URI is too long. -A `414 Request-URI Too Long` response will be sent if this -function returns `true`. +This function can be used to further restrict the length +of the URI for this specific resource. === valid_content_headers -Methods:: all -Value type:: boolean() -Default value:: true +[source,erlang] +---- +valid_content_headers(Req, State) -> {Result, Req, State} -Return whether the content-* headers are valid. +Result :: boolean() +Default :: true +---- -This also applies to the transfer-encoding header. This -function must return `false` for any unknown content-* -headers, or if the headers can't be understood. The -function `cowboy_req:parse_header/2` can be used to -quickly check the headers can be parsed. +Return whether the content headers are valid. -A `501 Not Implemented` response will be sent if this -function returns `false`. +This callback can be used to reject requests that have +invalid content header values, for example an unsupported +content-encoding. === valid_entity_length -Methods:: all -Value type:: boolean() -Default value:: true +[source,erlang] +---- +valid_entity_length(Req, State) -> {Result, Req, State} + +Result :: boolean() +Default :: true +---- Return whether the request body length is within acceptable boundaries. -A `413 Request Entity Too Large` response will be sent if this +A '413 Request Entity Too Large' response will be sent if this function returns `false`. === variances -Methods:: GET, HEAD, POST, PUT, PATCH, DELETE -Value type:: [binary()] -Default value:: [] +[source,erlang] +---- +variances(Req, State) -> {Result, Req, State} + +Result :: [binary()] %% case insensitive +Default :: [] +---- -Return the list of headers that affect the representation of the resource. +Return the list of request headers that affect the +representation of the resource. -These request headers return the same resource but with different -parameters, like another language or a different content-type. +Cowboy automatically adds the accept, accept-charset and +accept-language headers when necessary. -Cowboy will automatically add the accept, accept-language and -accept-charset headers to the list if the respective functions -were defined in the resource. +== See also -This operation is performed right before the `resource_exists/2` -callback. All responses past that point will contain the vary -header which holds this list. +link:man:cowboy(7)[cowboy(7)], +link:man:cowboy_handler(3)[cowboy_handler(3)] diff --git a/doc/src/manual/cowboy_static.asciidoc b/doc/src/manual/cowboy_static.asciidoc index 7a78660..a0069da 100644 --- a/doc/src/manual/cowboy_static.asciidoc +++ b/doc/src/manual/cowboy_static.asciidoc @@ -100,6 +100,8 @@ ParsedMime :: {Type :: binary(), SubType :: binary(), Params} Params :: [{Key :: binary(), Value :: binary()}] ---- +// @todo Case sensitivity of parsed mime content? + Cowboy comes with two such functions; the default function `cow_mimetypes:web/1`, and a second function generated from the Apache 'mime.types' file, `cow_mimetypes:all/1`. |