aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2016-08-24 17:25:33 +0200
committerLoïc Hoguin <[email protected]>2016-08-24 17:25:33 +0200
commit7839f1367194813c70d7e223a476f96a62b298ae (patch)
treed5f7be7d443c47dfc67856e9c10474232cb79686
parentb9ad02d3057e78ff82dacbd38042e33073c4bc75 (diff)
downloadcowboy-7839f1367194813c70d7e223a476f96a62b298ae.tar.gz
cowboy-7839f1367194813c70d7e223a476f96a62b298ae.tar.bz2
cowboy-7839f1367194813c70d7e223a476f96a62b298ae.zip
More 2.0 documentation updates
Still incomplete.
-rw-r--r--doc/src/guide/getting_started.asciidoc8
-rw-r--r--doc/src/guide/handlers.asciidoc47
-rw-r--r--doc/src/guide/introduction.asciidoc30
-rw-r--r--doc/src/guide/loop_handlers.asciidoc12
-rw-r--r--doc/src/guide/req.asciidoc403
-rw-r--r--doc/src/guide/rest_handlers.asciidoc4
-rw-r--r--doc/src/guide/routing.asciidoc10
-rw-r--r--doc/src/guide/sub_protocols.asciidoc10
-rw-r--r--doc/src/guide/ws_handlers.asciidoc22
9 files changed, 351 insertions, 195 deletions
diff --git a/doc/src/guide/getting_started.asciidoc b/doc/src/guide/getting_started.asciidoc
index a4e5637..e9a2756 100644
--- a/doc/src/guide/getting_started.asciidoc
+++ b/doc/src/guide/getting_started.asciidoc
@@ -106,7 +106,7 @@ chapter. For this tutorial we map the path `/` to the handler
module `hello_handler`. This module doesn't exist yet.
Build and start the release, then open http://localhost:8080
-in your browser. You will get an error because the module is missing.
+in your browser. You will get a 500 error because the module is missing.
Any other URL, like http://localhost:8080/test, will result in a
404 error.
@@ -126,11 +126,11 @@ the `init/2` function like this to send a reply.
[source,erlang]
----
-init(Req, State) ->
- cowboy_req:reply(200,
+init(Req0, State) ->
+ Req = cowboy_req:reply(200,
#{<<"content-type">> => <<"text/plain">>},
<<"Hello Erlang!">>,
- Req),
+ Req0),
{ok, Req, State}.
----
diff --git a/doc/src/guide/handlers.asciidoc b/doc/src/guide/handlers.asciidoc
index 83ae2ff..a59b8cf 100644
--- a/doc/src/guide/handlers.asciidoc
+++ b/doc/src/guide/handlers.asciidoc
@@ -9,40 +9,42 @@ The most basic handler in Cowboy implements the mandatory
`init/2` callback, manipulates the request, optionally
sends a response and then returns.
-This callback receives the xref:req[Req object] and the options
-defined during the xref:routing[router configuration].
+This callback receives the xref:req[Req object] and the initial
+state defined in the xref:routing[router configuration].
A handler that does nothing would look like this:
[source,erlang]
----
-init(Req, _Opts) ->
- {ok, Req, #state{}}.
+init(Req, State) ->
+ {ok, Req, State}.
----
-Despite sending no reply, a `204 No Content` reply will be
-sent to the client, as Cowboy makes sure that a reply is
+Despite sending no reply, a `204 No Content` response will be
+sent to the client, as Cowboy makes sure that a response is
sent for every request.
-We need to use the Req object for sending a reply.
+We need to use the Req object to reply.
[source,erlang]
----
-init(Req, State) ->
- cowboy_req:reply(200, [
+init(Req0, State) ->
+ Req = cowboy_req:reply(200, [
{<<"content-type">>, <<"text/plain">>}
- ], <<"Hello World!">>, Req),
+ ], <<"Hello World!">>, Req0),
{ok, Req, State}.
----
-As you can see we return a 3-tuple. `ok` means that the
-handler ran successfully. Note that Cowboy will immediately
-send a response when `cowboy:reply/4` is called.
+Cowboy will immediately send a response when `cowboy:reply/4`
+is called.
+
+We then return a 3-tuple. `ok` means that the handler ran
+successfully. We also give the modified Req back to Cowboy.
The last value of the tuple is a state that will be used
in every subsequent callbacks to this handler. Plain HTTP
handlers only have one additional callback, the optional
-`terminate/3`.
+and rarely used `terminate/3`.
=== Other handlers
@@ -62,16 +64,16 @@ following snippet switches to a Websocket handler:
[source,erlang]
----
-init(Req, _Opts) ->
- {cowboy_websocket, Req, #state{}}.
+init(Req, State) ->
+ {cowboy_websocket, Req, State}.
----
You can also switch to your own custom handler type:
[source,erlang]
----
-init(Req, _Opts) ->
- {my_handler_type, Req, #state{}}.
+init(Req, State) ->
+ {my_handler_type, Req, State}.
----
How to implement a custom handler type is described in the
@@ -79,12 +81,12 @@ xref:sub_protocols[Sub protocols] chapter.
=== Cleaning up
-All handlers coming with Cowboy allow the use of the optional
-`terminate/3` callback.
+With the exception of Websocket handlers, all handler types
+provide the optional `terminate/3` callback.
[source,erlang]
----
-terminate(_Reason, Req, State) ->
+terminate(_Reason, _Req, _State) ->
ok.
----
@@ -96,4 +98,5 @@ This callback is optional because it is rarely necessary.
Cleanup should be done in separate processes directly (by
monitoring the handler process to detect when it exits).
-Cowboy does not reuse processes for different requests.
+Cowboy does not reuse processes for different requests. The
+process will terminate soon after this call returns.
diff --git a/doc/src/guide/introduction.asciidoc b/doc/src/guide/introduction.asciidoc
index 0179c16..d262b5c 100644
--- a/doc/src/guide/introduction.asciidoc
+++ b/doc/src/guide/introduction.asciidoc
@@ -35,7 +35,27 @@ guarantee that the experience will be safe and smooth. You are advised
to perform the necessary testing and security audits prior to deploying
on other platforms.
-Cowboy is developed for Erlang/OTP 18.0 and newer.
+Cowboy is developed for Erlang/OTP 19.0 and newer.
+
+=== License
+
+Cowboy uses the ISC License.
+
+----
+Copyright (c) 2011-2016, Loïc Hoguin <[email protected]>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+----
=== Versioning
@@ -46,8 +66,10 @@ Cowboy uses http://semver.org/[Semantic Versioning 2.0.0].
In the HTTP protocol, the method name is case sensitive. All standard
method names are uppercase.
-Header names are case insensitive. Cowboy converts all the request
-header names to lowercase, and expects your application to provide
-lowercase header names in the response.
+Header names are case insensitive. When using HTTP/1.1, Cowboy converts
+all the request header names to lowercase. HTTP/2 requires clients to
+send them as lowercase. Any other header name is expected to be provided
+lowercased, including when querying information about the request or
+when sending responses.
The same applies to any other case insensitive value.
diff --git a/doc/src/guide/loop_handlers.asciidoc b/doc/src/guide/loop_handlers.asciidoc
index d3655e5..c0195ea 100644
--- a/doc/src/guide/loop_handlers.asciidoc
+++ b/doc/src/guide/loop_handlers.asciidoc
@@ -38,8 +38,8 @@ This snippet enables the loop handler.
[source,erlang]
----
-init(Req, _Opts) ->
- {cowboy_loop, Req, #state{}}.
+init(Req, State) ->
+ {cowboy_loop, Req, State}.
----
However it is largely recommended that you set a timeout
@@ -48,8 +48,8 @@ also makes the process hibernate.
[source,erlang]
----
-init(Req, _Opts) ->
- {cowboy_loop, Req, #state{}, 30000, hibernate}.
+init(Req, State) ->
+ {cowboy_loop, Req, State, 30000, hibernate}.
----
=== Receive loop
@@ -101,9 +101,9 @@ and the loop is stopped by sending an `eof` message.
[source,erlang]
----
-init(Req, _Opts) ->
+init(Req, State) ->
Req2 = cowboy_req:chunked_reply(200, [], Req),
- {cowboy_loop, Req2, #state{}}.
+ {cowboy_loop, Req2, State}.
info(eof, Req, State) ->
{stop, Req, State};
diff --git a/doc/src/guide/req.asciidoc b/doc/src/guide/req.asciidoc
index 09d442a..39fcde6 100644
--- a/doc/src/guide/req.asciidoc
+++ b/doc/src/guide/req.asciidoc
@@ -1,155 +1,293 @@
++++
+title = "The Req object"
++++
+
[[req]]
== The Req object
-The Req object is this variable that you will use to obtain
-information about a request, read the body of the request
-and send a response.
+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.
-=== A special variable
+=== Introduction to the cowboy_req interface
-While we call it an "object", it is not an object in the
-OOP sense of the term. In fact it is completely opaque
-to you and the only way you can perform operations using
-it is by calling the functions from the `cowboy_req`
-module.
+// @todo Link to cowboy_req manual
-Almost all the calls to the `cowboy_req` module will
-return an updated request object. Just like you would
-keep the updated `State` variable in a gen_server,
-you MUST keep the updated `Req` variable in a Cowboy
-handler. Cowboy will use this object to know whether
-a response has been sent when the handler has finished
-executing.
+Functions in the `cowboy_req` module provide access to
+the request information but also various operations that
+are common when dealing with HTTP requests.
-The Req object allows accessing both immutable and
-mutable state. This means that calling some of the
-functions twice will not produce the same result.
-For example, when streaming the request body, the
-function will return the body by chunks, one at a
-time, until there is none left.
+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).
-=== Overview of the cowboy_req interface
+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.
-With the exception of functions manipulating the request
-body, all functions return a single value. Depending on
-the function this can be the requested value (method,
-host, path, ...), a boolean (has_body, has_resp_header...)
-a new Req object (set_resp_body, set_resp_header...), or
-simply the atom `ok` (chunk, continue, ...).
+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.
-The request body reading functions may return `{Result, Req}`
-or `{Result, Value, Req}`. The functions in this category
-are `body/{1,2}`, `body_qs/{1,2}`, `part/{1,2}`, `part_body/{1,2}`.
+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.
-This chapter covers the access functions mainly. Cookies,
-request body and response functions are covered in their
-own chapters.
+=== Request method
-=== Request
+The request method can be retrieved directly:
-When a client performs a request, it first sends a few required
-values. They are sent differently depending on the protocol
-being used, but the intent is the same. They indicate to the
-server the type of action it wants to do and how to locate
-the resource to perform it on.
+[source, erlang]
+#{method := Method} = Req.
-The method identifies the action. Standard methods include
-GET, HEAD, OPTIONS, PATCH, POST, PUT, DELETE. Method names
-are case sensitive.
+Or using a function:
[source,erlang]
Method = cowboy_req:method(Req).
-The host, port and path parts of the URL identify the resource
-being accessed. The host and port information may not be
-available if the client uses HTTP/1.0.
+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 version used by the client can of course also be obtained.
+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]
-Version = cowboy_req:version(Req).
+%% 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}).
-Do note however that clients claiming to implement one version
-of the protocol does not mean they implement it fully, or even
-properly.
+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
-After routing the request, bindings are available. Bindings
-are these parts of the host or path that you chose to extract
-when defining the routes of your application.
+// @todo Bindings should probably be a map themselves.
-You can fetch a single binding. The value will be `undefined`
-if the binding doesn't exist.
+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]
-Binding = cowboy_req:binding(my_binding, Req).
+Value = cowboy_req:binding(userid, Req).
-If you need a different value when the binding doesn't exist,
-you can change the default.
+When attempting to retrieve a value that was not bound,
+`undefined` will be returned. A different default value
+can be provided:
[source,erlang]
-Binding = cowboy_req:binding(my_binding, Req, 42).
+Value = cowboy_req:binding(userid, Req, 42).
-You can also obtain all bindings in one call. They will be
-returned as a list of key/value tuples.
+To retrieve everything that was bound:
[source,erlang]
-AllBindings = cowboy_req:bindings(Req).
+Bindings = cowboy_req:bindings(Req).
+
+They are returned as a list of key/value pairs, with
+keys being atoms.
+
+// ...
+
+The Cowboy router also allows you to capture many host
+or path segments at once using the `...` qualifier.
-If you used `...` at the beginning of the route's pattern
-for the host, you can retrieve the matched part of the host.
-The value will be `undefined` otherwise.
+To retrieve the segments captured from the host name:
[source,erlang]
HostInfo = cowboy_req:host_info(Req).
-Similarly, if you used `...` at the end of the route's
-pattern for the path, you can retrieve the matched part,
-or get `undefined` otherwise.
+And the path segments:
[source,erlang]
PathInfo = cowboy_req:path_info(Req).
-=== Query string
+Cowboy will return `undefined` if `...` was not used
+in the route.
-The raw query string can be obtained directly.
+=== Query parameters
-[source,erlang]
-Qs = cowboy_req:qs(Req).
-
-You can parse the query string and then use standard library
-functions to access individual values.
+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).
-You can match the query string into a map.
+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.
+
+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 ^constraints^.
+This function returns a map.
[source,erlang]
#{id := ID, lang := Lang} = cowboy_req:match_qs([id, lang], Req).
-You can use constraints to validate the values while matching
-them. The following snippet will crash if the `id` value is
-not an integer number or if the `lang` value is empty. Additionally
-the `id` value will be converted to an integer term, saving
-you a conversion step.
+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).
-Note that in the case of duplicate query string keys, the map
-value will become a list of the different values.
-
-Read more about ^constraints^.
-
-A default value can be provided. The default will be used
+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.
@@ -159,51 +297,56 @@ the key is found but has an empty value.
If no default is provided and the value is missing, the
query string is deemed invalid and the process will crash.
-=== Request URL
-
-You can reconstruct the full URL of the resource.
-
-[source,erlang]
-URL = cowboy_req:url(Req).
-
-You can also obtain only the base of the URL, excluding the
-path and query string.
-
-[source,erlang]
-BaseURL = cowboy_req:host_url(Req).
+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
-Cowboy allows you to obtain the header values as string,
+Header values can be retrieved either as a binary string
or parsed into a more meaningful representation.
-This will get the string value of a header.
+The get the raw value:
[source,erlang]
HeaderVal = cowboy_req:header(<<"content-type">>, Req).
-You can of course set a default in case the header is missing.
+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">>).
-And also obtain all headers.
+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).
-To parse the previous header, simply call `parse_header/{2,3}`
-where you would call `header/{2,3}` otherwise.
+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).
-Cowboy will crash if it doesn't know how to parse the given
-header, or if the value is invalid.
+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.
-You can of course define a default value. Note that the default
-value you specify here is the parsed value you'd like to get
-by default.
+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]
----
@@ -211,37 +354,21 @@ ParsedVal = cowboy_req:parse_header(<<"content-type">>, Req,
{<<"text">>, <<"plain">>, []}).
----
-The list of known headers and default values is defined in the
-manual.
-
-=== Meta
-
-Cowboy will sometimes associate some meta information with
-the request. Built-in meta values are listed in the manual
-for their respective modules.
-
-This will get a meta value. The returned value will be `undefined`
-if it isn't defined.
-
-[source,erlang]
-MetaVal = cowboy_req:meta(websocket_version, Req).
-
-You can change the default value if needed.
+=== Peer
-[source,erlang]
-MetaVal = cowboy_req:meta(websocket_version, Req, 13).
+The peer address and port number for the connection can be
+retrieved either directly or using a function.
-You can also define your own meta values. The name must be
-an `atom()`.
+To retrieve the peer directly:
[source,erlang]
-Req2 = cowboy_req:set_meta(the_answer, 42, Req).
+#{peer := {IP, Port}} = Req.
-=== Peer
-
-You can obtain the peer address and port number. This is
-not necessarily the actual IP and port of the client, but
-rather the one of the machine that connected to the server.
+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.
diff --git a/doc/src/guide/rest_handlers.asciidoc b/doc/src/guide/rest_handlers.asciidoc
index 6bff18d..f28c066 100644
--- a/doc/src/guide/rest_handlers.asciidoc
+++ b/doc/src/guide/rest_handlers.asciidoc
@@ -15,8 +15,8 @@ must return a `cowboy_rest` tuple.
[source,erlang]
----
-init(Req, _Opts) ->
- {cowboy_rest, Req, #state{}}.
+init(Req, State) ->
+ {cowboy_rest, Req, State}.
----
Cowboy will then switch to the REST protocol and start executing
diff --git a/doc/src/guide/routing.asciidoc b/doc/src/guide/routing.asciidoc
index 150c634..864a19a 100644
--- a/doc/src/guide/routing.asciidoc
+++ b/doc/src/guide/routing.asciidoc
@@ -37,11 +37,11 @@ PathsList = [Path1, Path2, ... PathN].
Finally, each path contains matching rules for the path along with
optional constraints, and gives us the handler module to be used
-along with options that will be given to it on initialization.
+along with its initial state.
[source,erlang]
-Path1 = {PathMatch, Handler, Opts}.
-Path2 = {PathMatch, Constraints, Handler, Opts}.
+Path1 = {PathMatch, Handler, InitialState}.
+Path2 = {PathMatch, Constraints, Handler, InitialState}.
Continue reading to learn more about the match syntax and the optional
constraints.
@@ -199,8 +199,8 @@ This can be done with a simple call to `cowboy_router:compile/1`.
[source,erlang]
----
Dispatch = cowboy_router:compile([
- %% {HostMatch, list({PathMatch, Handler, Opts})}
- {'_', [{'_', my_handler, []}]}
+ %% {HostMatch, list({PathMatch, Handler, InitialState})}
+ {'_', [{'_', my_handler, #{}}]}
]),
%% Name, NbAcceptors, TransOpts, ProtoOpts
cowboy:start_clear(my_http_listener, 100,
diff --git a/doc/src/guide/sub_protocols.asciidoc b/doc/src/guide/sub_protocols.asciidoc
index 63fd52b..5332eec 100644
--- a/doc/src/guide/sub_protocols.asciidoc
+++ b/doc/src/guide/sub_protocols.asciidoc
@@ -16,8 +16,8 @@ is handled by the sub protocol.
[source,erlang]
----
-init(Req, _Opts) ->
- {cowboy_websocket, Req, #state{}}.
+init(Req, State) ->
+ {cowboy_websocket, Req, State}.
----
The return value may also have a `Timeout` value and/or the
@@ -29,10 +29,12 @@ The following snippet switches to the `my_protocol` sub
protocol, sets the timeout value to 5 seconds and enables
hibernation:
+// @todo Yeah maybe what we really need is an Opts map.
+
[source,erlang]
----
-init(Req, _Opts) ->
- {my_protocol, Req, #state{}, 5000, hibernate}.
+init(Req, State) ->
+ {my_protocol, Req, State, 5000, hibernate}.
----
If a sub protocol does not make use of these options, it should
diff --git a/doc/src/guide/ws_handlers.asciidoc b/doc/src/guide/ws_handlers.asciidoc
index 9ddddf4..b280fd8 100644
--- a/doc/src/guide/ws_handlers.asciidoc
+++ b/doc/src/guide/ws_handlers.asciidoc
@@ -18,8 +18,8 @@ must return a `ws` tuple.
[source,erlang]
----
-init(Req, _Opts) ->
- {cowboy_websocket, Req, #state{}}.
+init(Req, State) ->
+ {cowboy_websocket, Req, State}.
----
Upon receiving this tuple, Cowboy will switch to the code
@@ -34,18 +34,18 @@ the connection, assuming no correct subprotocol was found.
[source,erlang]
----
-init(Req, _Opts) ->
+init(Req, State) ->
case cowboy_req:parse_header(<<"sec-websocket-protocol">>, Req) of
undefined ->
- {ok, Req, #state{}};
+ {ok, Req, State};
Subprotocols ->
case lists:keymember(<<"mychat2">>, 1, Subprotocols) of
true ->
Req2 = cowboy_req:set_resp_header(<<"sec-websocket-protocol">>,
<<"mychat2">>, Req),
- {ok, Req2, #state{}};
+ {ok, Req2, State};
false ->
- {stop, Req, undefined}
+ {stop, Req, State}
end
end.
----
@@ -60,12 +60,14 @@ It is also very easy to ensure that this message arrives before
any message from other processes by sending it before registering
or enabling timers.
+// @todo This doesn't even work.
+
[source,erlang]
----
-init(Req, _Opts) ->
+init(Req, State) ->
self() ! post_init,
%% Register process here...
- {cowboy_websocket, Req, #state{}}.
+ {cowboy_websocket, Req, State}.
websocket_info(post_init, Req, State) ->
%% Perform post_init initialization here...
@@ -169,8 +171,8 @@ A good timeout value is 60 seconds.
[source,erlang]
----
-init(Req, _Opts) ->
- {cowboy_websocket, Req, #state{}, 60000}.
+init(Req, State) ->
+ {cowboy_websocket, Req, State, 60000}.
----
This value cannot be changed once it is set. It defaults to