aboutsummaryrefslogtreecommitdiffstats
path: root/manual
diff options
context:
space:
mode:
Diffstat (limited to 'manual')
-rw-r--r--manual/cowboy.md89
-rw-r--r--manual/cowboy_app.md25
-rw-r--r--manual/cowboy_handler.md25
-rw-r--r--manual/cowboy_http_handler.md57
-rw-r--r--manual/cowboy_loop_handler.md91
-rw-r--r--manual/cowboy_middleware.md56
-rw-r--r--manual/cowboy_protocol.md65
-rw-r--r--manual/cowboy_req.md597
-rw-r--r--manual/cowboy_rest.md549
-rw-r--r--manual/cowboy_router.md68
-rw-r--r--manual/cowboy_sub_protocol.md34
-rw-r--r--manual/cowboy_websocket.md34
-rw-r--r--manual/cowboy_websocket_handler.md131
-rw-r--r--manual/toc.md18
14 files changed, 1839 insertions, 0 deletions
diff --git a/manual/cowboy.md b/manual/cowboy.md
new file mode 100644
index 0000000..ebfe615
--- /dev/null
+++ b/manual/cowboy.md
@@ -0,0 +1,89 @@
+cowboy
+======
+
+The `cowboy` module provides convenience functions for
+manipulating Ranch listeners.
+
+Types
+-----
+
+### http_headers() = [{binary(), iodata()}]
+
+> HTTP headers as a list of key/values.
+
+### http_status() = non_neg_integer() | binary()
+
+> HTTP status.
+>
+> A binary status can be used to set a custom message.
+
+### http_version() = 'HTTP/1.1' | 'HTTP/1.0'
+
+> HTTP version.
+
+### onrequest_fun() = fun((cowboy_req:req()) -> cowboy_req:req())
+
+> Fun called immediately after receiving a request.
+>
+> It can perform any operation on the `Req` object, including
+> reading the request body or replying. If a reply is sent,
+> the processing of the request ends here, before any middleware
+> is executed.
+
+### onresponse_fun() = fun((http_status(), http_headers(),
+ iodata(), cowboy_req:req()) -> cowboy_req:req())
+
+> Fun called immediately before sending the response.
+>
+> It can perform any operation on the `Req` object, including
+> reading the request body or replying. If a reply is sent, it
+> overrides the reply initially sent. The callback will not be
+> called again for the new reply.
+
+Exports
+-------
+
+### start_http(Ref, NbAcceptors, TransOpts, ProtoOpts) -> {ok, pid()}
+
+> Types:
+> * Ref = ranch:ref()
+> * NbAcceptors = non_neg_integer()
+> * TransOpts = ranch_tcp:opts()
+> * ProtoOpts = cowboy_protocol:opts()
+>
+> Start listening for HTTP connections. Returns the pid for this
+> listener's supervisor.
+
+### start_https(Ref, NbAcceptors, TransOpts, ProtoOpts) -> {ok, pid()}
+
+> Types:
+> * Ref = ranch:ref()
+> * NbAcceptors = non_neg_integer()
+> * TransOpts = ranch_ssl:opts()
+> * ProtoOpts = cowboy_protocol:opts()
+>
+> Start listening for HTTPS connections. Returns the pid for this
+> listener's supervisor.
+
+### stop_listener(Ref) -> ok
+
+> Types:
+> * Ref = ranch:ref()
+>
+> Stop a previously started listener.
+
+### set_env(Ref, Name, Value) -> ok
+
+> Types:
+> * Ref = ranch:ref()
+> * Name = atom()
+> * Value = any()
+>
+> Set or update an environment value for an already running listener.
+> This will take effect on all subsequent connections.
+
+See also
+--------
+
+The [Ranch guide](http://ninenines.eu/docs/en/ranch/HEAD/guide)
+provides detailed information about how listeners work.
diff --git a/manual/cowboy_app.md b/manual/cowboy_app.md
new file mode 100644
index 0000000..5311109
--- /dev/null
+++ b/manual/cowboy_app.md
@@ -0,0 +1,25 @@
+The Cowboy Application
+======================
+
+Small, fast, modular HTTP server.
+
+Dependencies
+------------
+
+The `cowboy` application uses the Erlang applications `ranch`
+for listening and accepting TCP connections, and `crypto`
+for establishing Websocket connections. These dependencies must
+be loaded for the `cowboy` application to work. In an embedded
+environment this means that they need to be started with the
+`application:start/{1,2}` function before the `cowboy`
+application is started.
+
+The `cowboy` application also uses the Erlang applications
+`public_key` and `ssl` when listening for HTTPS connections.
+These are started automatically if they weren't before.
+
+Environment
+-----------
+
+The `cowboy` application does not define any application
+environment configuration parameters.
diff --git a/manual/cowboy_handler.md b/manual/cowboy_handler.md
new file mode 100644
index 0000000..8d13492
--- /dev/null
+++ b/manual/cowboy_handler.md
@@ -0,0 +1,25 @@
+cowboy_handler
+==============
+
+The `cowboy_handler` middleware executes the handler passed
+through the environment values `handler` and `handler_opts`,
+and add the result of this execution to the environment as
+the value `result`, indicating that the request has been
+handled and received a response.
+
+Environment input:
+ * handler = module()
+ * handler_opts = any()
+
+Environment output:
+ * result = ok
+
+Types
+-----
+
+None.
+
+Exports
+-------
+
+None.
diff --git a/manual/cowboy_http_handler.md b/manual/cowboy_http_handler.md
new file mode 100644
index 0000000..9d283e7
--- /dev/null
+++ b/manual/cowboy_http_handler.md
@@ -0,0 +1,57 @@
+cowboy_http_handler
+===================
+
+The `cowboy_http_handler` behaviour defines the interface used
+by plain HTTP handlers.
+
+Unless noted otherwise, the callbacks will be executed sequentially.
+
+Types
+-----
+
+None.
+
+Callbacks
+---------
+
+### init({TransportName, ProtocolName}, Req, Opts)
+ -> {ok, Req, State} | {shutdown, Req, State}
+
+> Types:
+> * TransportName = tcp | ssl | atom()
+> * ProtocolName = http | atom()
+> * Req = cowboy_req:req()
+> * Opts = any()
+> * State = any()
+>
+> Initialize the state for this request.
+>
+> The `shutdown` return value can be used to skip the `handle/2`
+> call entirely.
+
+### handle(Req, State) -> {ok, Req, State}
+
+> Types:
+> * Req = cowboy_req:req()
+> * State = any()
+>
+> Handle the request.
+>
+> This callback is where the request is handled and a response
+> should be sent. If a response is not sent, Cowboy will send
+> a `204 No Content` response automatically.
+
+### terminate(Reason, Req, State) -> ok
+
+> Types:
+> * Reason = {normal, shutdown} | {error, atom()}
+> * Req = cowboy_req:req()
+> * State = any()
+>
+> Perform any necessary cleanup of the state.
+>
+> This callback should release any resource currently in use,
+> clear any active timer and reset the process to its original
+> state, as it might be reused for future requests sent on the
+> same connection. Typical plain HTTP handlers rarely need to
+> use it.
diff --git a/manual/cowboy_loop_handler.md b/manual/cowboy_loop_handler.md
new file mode 100644
index 0000000..ccbb9b0
--- /dev/null
+++ b/manual/cowboy_loop_handler.md
@@ -0,0 +1,91 @@
+cowboy_loop_handler
+===================
+
+The `cowboy_loop_handler` behaviour defines the interface used
+by HTTP handlers that do not send a response directly, instead
+requiring a receive loop to process Erlang messages.
+
+This interface is best fit for long-polling types of requests.
+
+The `init/3` callback will always be called, followed by zero
+or more calls to `info/3`. The `terminate/3` will always be
+called last.
+
+Types
+-----
+
+None.
+
+Callbacks
+---------
+
+### init({TransportName, ProtocolName}, Req, Opts)
+ -> {loop, Req, State}
+ | {loop, Req, State, hibernate}
+ | {loop, Req, State, Timeout}
+ | {loop, Req, State, Timeout, hibernate}
+ | {shutdown, Req, State}
+
+> Types:
+> * TransportName = tcp | ssl | atom()
+> * ProtocolName = http | atom()
+> * Req = cowboy_req:req()
+> * Opts = any()
+> * State = any()
+> * Timeout = timeout()
+>
+> Initialize the state for this request.
+>
+> This callback will typically be used to register this process
+> to an event manager or a message queue in order to receive
+> the messages the handler wants to process.
+>
+> The receive loop will run for a duration of up to `Timeout`
+> milliseconds after it last received data from the socket,
+> at which point it will stop and send a `204 No Content` reply.
+> By default this value is set to `infinity`. It is recommended
+> to either set this value or ensure by any other mechanism
+> that the handler will be closed after a certain period of
+> inactivity.
+>
+> The `hibernate` option will hibernate the process until it
+> starts receiving messages.
+>
+> The `shutdown` return value can be used to skip the receive
+> loop entirely.
+
+### info(Info, Req, State) -> {ok, Req, State} | {loop, Req, State}
+ | {loop, Req, State, hibernate}
+
+> Types:
+> * Info = any()
+> * Req = cowboy_req:req()
+> * State = any()
+>
+> Handle the Erlang message received.
+>
+> This function will be called every time an Erlang message
+> has been received. The message can be any Erlang term.
+>
+> The `ok` return value can be used to stop the receive loop,
+> typically because a response has been sent.
+>
+> The `hibernate` option will hibernate the process until
+> it receives another message.
+
+### terminate(Reason, Req, State) -> ok
+
+> Types:
+> * Reason = {normal, shutdown} | {normal, timeout} | {error, closed} | {error, overflow} | {error, atom()}
+> * Req = cowboy_req:req()
+> * State = any()
+>
+> Perform any necessary cleanup of the state.
+>
+> This callback will typically unregister from any event manager
+> or message queue it registered to in `init/3`.
+>
+> This callback should release any resource currently in use,
+> clear any active timer and reset the process to its original
+> state, as it might be reused for future requests sent on the
+> same connection.
diff --git a/manual/cowboy_middleware.md b/manual/cowboy_middleware.md
new file mode 100644
index 0000000..dd28ff8
--- /dev/null
+++ b/manual/cowboy_middleware.md
@@ -0,0 +1,56 @@
+cowboy_middleware
+=================
+
+The `cowboy_middleware` behaviour defines the interface used
+by Cowboy middleware modules.
+
+Middlewares process the request sequentially in the order they
+are configured.
+
+Types
+-----
+
+### env() = [{atom(), any()}]
+
+> The environment variable.
+>
+> One is created for every request. It is passed to each
+> middleware module executed and subsequently returned,
+> optionally with its contents modified.
+
+Callbacks
+---------
+
+### execute(Req, Env)
+ -> {ok, Req, Env}
+ | {suspend, Module, Function, Args}
+ | {halt, Req}
+ | {error, StatusCode, Req}
+
+> Types:
+> * Req = cowboy_req:req()
+> * Env = env()
+> * Module = module()
+> * Function = atom()
+> * Args = [any()]
+> * StatusCode = cowboy:http_status()
+>
+> Execute the middleware.
+>
+> The `ok` return value indicates that everything went well
+> and that Cowboy should continue processing the request. A
+> response may or may not have been sent.
+>
+> The `suspend` return value will hibernate the process until
+> an Erlang message is received. Note that when resuming, any
+> previous stacktrace information will be gone.
+>
+> The `halt` return value stops Cowboy from doing any further
+> processing of the request, even if there are middlewares
+> that haven't been executed yet. The connection may be left
+> open to receive more requests from the client.
+>
+> The `error` return value sends an error response identified
+> by the `StatusCode` and then proceeds to terminate the
+> connection. Middlewares that haven't been executed yet
+> will not be called.
diff --git a/manual/cowboy_protocol.md b/manual/cowboy_protocol.md
new file mode 100644
index 0000000..86aee9d
--- /dev/null
+++ b/manual/cowboy_protocol.md
@@ -0,0 +1,65 @@
+cowboy_protocol
+===============
+
+The `cowboy_protocol` module implements HTTP/1.1 and HTTP/1.0
+as a Ranch protocol.
+
+Types
+-----
+
+### opts() = [{compress, boolean()}
+ | {env, cowboy_middleware:env()}
+ | {max_empty_lines, non_neg_integer()}
+ | {max_header_name_length, non_neg_integer()}
+ | {max_header_value_length, non_neg_integer()}
+ | {max_headers, non_neg_integer()}
+ | {max_keepalive, non_neg_integer()}
+ | {max_request_line_length, non_neg_integer()}
+ | {middlewares, [module()]}
+ | {onrequest, cowboy:onrequest_fun()}
+ | {onresponse, cowboy:onresponse_fun()}
+ | {timeout, timeout()}]
+
+> Configuration for the HTTP protocol handler.
+>
+> This configuration is passed to Cowboy when starting listeners
+> using `cowboy:start_http/4` or `cowboy:start_https/4` functions.
+>
+> It can be updated without restarting listeners using the
+> Ranch functions `ranch:get_protocol_options/1` and
+> `ranch:set_protocol_options/2`.
+
+Option descriptions
+-------------------
+
+The default value is given next to the option name.
+
+ - compress (false)
+ - When enabled, Cowboy will attempt to compress the response body.
+ - env ([{listener, Ref}])
+ - Initial middleware environment.
+ - max_empty_lines (5)
+ - Maximum number of empty lines before a request.
+ - max_header_name_length (64)
+ - Maximum length of header names.
+ - max_header_value_length (4096)
+ - Maximum length of header values.
+ - max_headers (100)
+ - Maximum number of headers allowed per request.
+ - max_keepalive (100)
+ - Maximum number of requests allowed per connection.
+ - max_request_line_length (4096)
+ - Maximum length of the request line.
+ - middlewares ([cowboy_router, cowboy_handler])
+ - List of middlewares to execute for every requests.
+ - onrequest (undefined)
+ - Fun called every time a request is received.
+ - onresponse (undefined)
+ - Fun called every time a response is sent.
+ - timeout (5000)
+ - Time in ms with no requests before Cowboy closes the connection.
+
+Exports
+-------
+
+None.
diff --git a/manual/cowboy_req.md b/manual/cowboy_req.md
new file mode 100644
index 0000000..f10120a
--- /dev/null
+++ b/manual/cowboy_req.md
@@ -0,0 +1,597 @@
+cowboy_req
+==========
+
+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, Req}`
+ * action: `{Result, Req} | {Result, Value, Req} | {error, atom()}`
+ * modification: `Req`
+ * question: `boolean()`
+
+The only exception is the `chunk/2` function which may return `ok`.
+
+Whenever `Req` is returned, you must use this returned value and
+ignore any previous you may have had. This value contains various
+state informations which are necessary for Cowboy to do some lazy
+evaluation or cache results where appropriate.
+
+Types
+-----
+
+### cookie_opts() = [{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 most of them return a new object labelled `Req2` in
+> the function descriptions below.
+
+Request related exports
+-----------------------
+
+### binding(Name, Req) -> binding(Name, Req, undefined)
+### binding(Name, Req, Default) -> {Value, Req2}
+
+> Types:
+> * Name = atom()
+> * Default = any()
+> * Value = binary() | Default
+>
+> Return the value for the given binding.
+
+### bindings(Req) -> {[{Name, Value}], Req2}
+
+> Types:
+> * Name = atom()
+> * Value = binary()
+>
+> Return all bindings.
+
+### cookie(Name, Req) -> cookie(Name, Req, undefined)
+### cookie(Name, Req, Default) -> {Value, Req2}
+
+> Types:
+> * Name = binary()
+> * Default = any()
+> * Value = binary() | Default
+>
+> Return the value for the given cookie.
+>
+> Cookie names are case sensitive.
+
+### cookies(Req) -> {[{Name, Value}], Req2}
+
+> Types:
+> * Name = binary()
+> * Value = binary()
+>
+> Return all cookies.
+
+### header(Name, Req) -> header(Name, Req, undefined)
+### header(Name, Req, Default) -> {Value, Req2}
+
+> Types:
+> * Name = binary()
+> * Default = any()
+> * Value = binary() | Default
+>
+> 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, Req2}
+
+> Types:
+> * Headers = cowboy:http_headers()
+>
+> Return all headers.
+
+### host(Req) -> {Host, Req2}
+
+> Types:
+> * Host = binary()
+>
+> Return the requested host.
+
+### host_info(Req) -> {HostInfo, Req2}
+
+> Types:
+> * HostInfo = cowboy_router:tokens() | undefined
+>
+> Return the extra tokens from matching against `...` during routing.
+
+### host_url(Req) -> {HostURL, Req2}
+
+> Types:
+> * HostURL = binary() | undefined
+>
+> Return the requested URL excluding the path component.
+>
+> This function will always return `undefined` until the
+> `cowboy_router` middleware has been executed. This includes
+> the `onrequest` hook.
+
+### meta(Name, Req) -> meta(Name, Req, undefined)
+### meta(Name, Req, Default) -> {Value, Req2}
+
+> Types:
+> * Name = atom()
+> * Default = any()
+> * Value = any()
+>
+> Return metadata about the request.
+
+### method(Req) -> {Method, Req2}
+
+> Types:
+> * Method = binary()
+>
+> Return the method.
+>
+> Methods are case sensitive. Standard methods are always uppercase.
+
+### parse_header(Name, Req) ->
+### parse_header(Name, Req, Default) -> {ok, ParsedValue, Req2}
+ | {undefined, Value, Req2} | {error, badarg}
+
+> Types:
+> * Name = binary()
+> * Default = any()
+> * ParsedValue - see below
+> * Value = any()
+>
+> Parse the given header.
+>
+> While header names are case insensitive, this function expects
+> the name to be a lowercase binary.
+>
+> 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.
+>
+> | Header name | Default value |
+> | ----------------- | ------------------ |
+> | transfer-encoding | `[<<"identity">>]` |
+> | Any other header | `undefined` |
+>
+> The parsed value differs depending on the header being parsed. The
+> following table summarizes the different types returned.
+>
+> | Header name | Type |
+> | ---------------------- | ------------------------------------------------- |
+> | 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, Params}` |
+> | 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 = [{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 other values are case insensitive and
+> will be returned as lowercase.
+>
+> The headers accept, accept-encoding and cookie headers can return
+> an empty list. Others will return `{error, badarg}` if the header
+> value is empty.
+>
+> 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.
+
+### path(Req) -> {Path, Req2}
+
+> Types:
+> * Path = binary()
+>
+> Return the requested path.
+
+### path_info(Req) -> {PathInfo, Req2}
+
+> Types:
+> * PathInfo = cowboy_router:tokens() | undefined
+>
+> Return the extra tokens from matching against `...` during routing.
+
+### peer(Req) -> {Peer, Req2}
+
+> Types:
+> * Peer = {inet:ip_address(), inet:port_number()}
+>
+> Return the client's IP address and port number.
+
+### port(Req) -> {Port, Req2}
+
+> Types:
+> * Port = inet: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, Req2}
+
+> Types:
+> * QueryString = binary()
+>
+> Return the request's query string.
+
+### qs_val(Name, Req) -> qs_val(Name, Req, undefined)
+### qs_val(Name, Req, Default) -> {Value, Req2}
+
+> Types:
+> * Name = binary()
+> * Default = any()
+> * Value = binary() | true
+>
+> Return a value from the request's query string.
+>
+> The value `true` will be returned when the name was found
+> in the query string without an associated value.
+
+### qs_vals(Req) -> {[{Name, Value}], Req2}
+
+> Types:
+> * Name = binary()
+> * Value = binary() | true
+>
+> Return the request's query string as a list of tuples.
+>
+> The value `true` will be returned when the name was found
+> in the query string without an associated value.
+
+### set_meta(Name, Value, Req) -> Req2
+
+> Types:
+> * Name = atom()
+> * Value = any()
+>
+> Set metadata about the request.
+>
+> An existing value will be overwritten.
+
+### url(Req) -> {URL, Req2}
+
+> Types:
+> * URL = binary() | undefined
+>
+> Return the requested URL.
+>
+> This function will always return `undefined` until the
+> `cowboy_router` middleware has been executed. This includes
+> the `onrequest` hook.
+
+### version(Req) -> {Version, Req2}
+
+> Types:
+> * Version = cowboy:http_version()
+>
+> Return the HTTP version used for this request.
+
+Request body related exports
+----------------------------
+
+### body(Req) -> body(8000000, Req)
+### body(MaxLength, Req) -> {ok, Data, Req2} | {error, Reason}
+
+> Types:
+> * MaxLength = non_neg_integer() | infinity
+> * Data = binary()
+> * Reason = chunked | badlength | atom()
+>
+> Return the request body.
+>
+> This function will return `{error, chunked}` if the request
+> body was sent using the chunked transfer-encoding. It will
+> also return `{error, badlength}` if the length of the body
+> exceeds the given `MaxLength`, which is 8MB by default.
+
+### body_length(Req) -> {Length, Req2}
+
+> Types:
+> * Length = non_neg_integer() | undefined
+>
+> 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(16000, Req)
+### body_qs(MaxLength, Req) -> {ok, [{Name, Value}], Req2} | {error, Reason}
+
+> Types:
+> * MaxLength = non_neg_integer() | infinity
+> * Name = binary()
+> * Value = binary() | true
+> * Reason = chunked | badlength | atom()
+>
+> 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 will return `{error, chunked}` if the request
+> body was sent using the chunked transfer-encoding. It will
+> also return `{error, badlength}` if the length of the body
+> exceeds the given `MaxLength`, which is 16KB by default.
+
+### has_body(Req) -> boolean()
+
+> Return whether the request has a body.
+
+### init_stream(TransferDecode, TransferState, ContentDecode, Req) -> {ok, Req2}
+
+> Types:
+> * TransferDecode = fun((Encoded, TransferState) -> OK | More | Done | {error, Reason})
+> * Encoded = Decoded = Rest = binary()
+> * TransferState = any()
+> * OK = {ok, Decoded, Rest, TransferState}
+> * More = more | {more, Length, Decoded, TransferState}
+> * Done = {done, TotalLength, Rest} | {done, Decoded, TotalLength, Rest}
+> * Length = TotalLength = non_neg_integer()
+> * ContentDecode = fun((Encoded) -> {ok, Decoded} | {error, Reason})
+> * Reason = atom()
+>
+> Initialize streaming of the request body.
+>
+> This function can be used to specify what function to use
+> for decoding the request body, generally specified in the
+> transfer-encoding and content-encoding request headers.
+>
+> Cowboy will properly handle chunked transfer-encoding by
+> default. You do not need to call this function if you do
+> not need to decode other encodings, `stream_body/{1,2}`
+> will perform all the required initialization when it is
+> called the first time.
+
+### skip_body(Req) -> {ok, Req2} | {error, Reason}
+
+> Types:
+> * Reason = atom()
+>
+> Skip the request body.
+>
+> This function will skip the body even if it was partially
+> read before.
+
+### stream_body(Req) -> stream_body(1000000, Req)
+### stream_body(MaxSegmentSize, Req) -> {ok, Data, Req2}
+ | {done, Req2} | {error, Reason}
+
+> Types:
+> * MaxSegmentSize = non_neg_integer()
+> * Data = binary()
+> * Reason = atom()
+>
+> Stream the request body.
+>
+> This function will return a segment of the request body
+> with a size of up to `MaxSegmentSize`, or 1MB by default.
+> This function can be called repeatedly until a `done` tuple
+> is returned, indicating the body has been fully received.
+>
+> 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. They must be specified using `init_stream/4`.
+>
+> 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.
+
+Response related exports
+------------------------
+
+### chunk(Data, Req) -> ok | {error, Reason}
+
+> Types:
+> * Data = iodata()
+> * Reason = atom()
+>
+> 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)
+### chunked_reply(StatusCode, Headers, Req) -> {ok, Req2}
+
+> Types:
+> * StatusCode = cowboy:http_status()
+> * Headers = cowboy:http_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.
+
+### delete_resp_header(Name, Req) -> Req2
+
+> Types:
+> * Name = binary()
+>
+> 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()
+
+> Types:
+> * Name = binary()
+>
+> 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)
+### reply(StatusCode, Headers, Req) - see below
+### reply(StatusCode, Headers, Body, Req) -> {ok, Req2}
+
+> Types:
+> * StatusCode = cowboy:http_status()
+> * Headers = cowboy:http_headers()
+> * Body = iodata()
+>
+> 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.
+
+### set_resp_body(Body, Req) -> Req2
+
+> Types:
+> * Body = iodata()
+>
+> 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
+### set_resp_body_fun(Length, Fun, Req) -> Req2
+
+> Types:
+> * Fun = fun((Socket, Transport) -> ok)
+> * Socket = inet:socket()
+> * Transport = module()
+> * Length = non_neg_integer()
+>
+> 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.
+>
+> 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
+
+> Types:
+> * Fun = fun((ChunkFun) -> ok)
+> * ChunkFun = fun((iodata()) -> ok | {error, atom()})
+>
+> 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
+
+> Types:
+> * Name = iodata()
+> * Value = iodata()
+> * Opts = cookie_opts()
+>
+> Set a cookie in the response.
+>
+> Cookie names are case sensitive.
+
+### set_resp_header(Name, Value, Req) -> Req2
+
+> Types:
+> * Name = binary()
+> * Value = iodata()
+>
+> Set a response header.
+>
+> You should use `set_resp_cookie/4` instead of this function
+> to set cookies.
+
+Misc. exports
+-------------
+
+### compact(Req) -> Req2
+
+> Remove any non-essential data from the `Req` object.
+>
+> Long-lived connections usually only need to manipulate the
+> `Req` object at initialization. Compacting allows saving up
+> memory by discarding extraneous information.
diff --git a/manual/cowboy_rest.md b/manual/cowboy_rest.md
new file mode 100644
index 0000000..b7890e4
--- /dev/null
+++ b/manual/cowboy_rest.md
@@ -0,0 +1,549 @@
+cowboy_rest
+===========
+
+The `cowboy_rest` module implements REST semantics on top of
+the HTTP protocol.
+
+This module cannot be described as a behaviour due to most of
+the callbacks it defines being optional. It has the same
+semantics as a behaviour otherwise.
+
+The only mandatory callback is `init/3`, needed to perform
+the protocol upgrade.
+
+Types
+-----
+
+None.
+
+Meta values
+-----------
+
+### charset
+
+> Type: binary()
+>
+> Negotiated charset.
+>
+> This value may not be defined if no charset was negotiated.
+
+### language
+
+> Type: binary()
+>
+> Negotiated language.
+>
+> This value may not be defined if no language was negotiated.
+
+### media_type
+
+> 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`.
+
+Callbacks
+---------
+
+### init({TransportName, ProtocolName}, Req, Opts)
+ -> {upgrade, protocol, cowboy_rest}
+ | {upgrade, protocol, cowboy_rest, Req, Opts}
+
+> Types:
+> * TransportName = tcp | ssl | atom()
+> * ProtocolName = http | atom()
+> * Req = cowboy_req:req()
+> * Opts = any()
+>
+> Upgrade the protocol to `cowboy_rest`.
+>
+> This is the only mandatory callback.
+
+### rest_init(Req, Opts) -> {ok, Req, State}
+
+> Types:
+> * Req = cowboy_req:req()
+> * Opts = any()
+> * State = any()
+>
+> Initialize the state for this request.
+
+### rest_terminate(Req, State) -> ok
+
+> Types:
+> * Req = cowboy_req:req()
+> * State = any()
+>
+> Perform any necessary cleanup of the state.
+>
+> This callback should release any resource currently in use,
+> clear any active timer and reset the process to its original
+> state, as it might be reused for future requests sent on the
+> same connection.
+
+### Callback(Req, State) -> {Value, Req, State} | {halt, Req, State}
+
+> Types:
+> * Callback - one of the REST callbacks described below
+> * Req = cowboy_req:req()
+> * State = any()
+> * Value - see the REST callbacks description below
+>
+> 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.
+>
+> The `halt` 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.
+
+REST callbacks description
+--------------------------
+
+### allowed_methods
+
+> * Methods: all
+> * Value type: [binary()]
+> * Default value: [<<"GET">>, <<"HEAD">>, <<"OPTIONS">>]
+>
+> Return the list of allowed methods.
+>
+> Methods are case sensitive. Standard methods are always uppercase.
+
+### allow_missing_post
+
+> * Methods: POST
+> * Value type: boolean()
+> * Default value: 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.
+
+### charsets_provided
+
+> * Methods: GET, HEAD, POST, PUT, PATCH, DELETE
+> * Value type: [binary()]
+> * Skip to the next step if undefined
+>
+> Return the list of charsets the resource provides.
+>
+> The list must be ordered 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.
+>
+> The chosen charset will be set in the `Req` object as the meta
+> value `charset`.
+>
+> While charsets are case insensitive, this callback is expected
+> to return them as lowercase binary.
+
+### content_types_accepted
+
+> * Methods: POST, PUT, PATCH
+> * No default
+>
+> Types:
+> * Value = [{binary() | {Type, SubType, Params}, AcceptResource}]
+> * Type = SubType = binary()
+> * Params = '*' | [{binary(), binary()}]
+> * AcceptResource = atom()
+>
+> Return the list of content-types the resource accepts.
+>
+> The list must be ordered 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.
+>
+> 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.
+>
+> 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.
+>
+> The `AcceptResource` value is the name of the callback that will
+> be called if the content-type matches. It is defined as follow.
+>
+> * Value type: true | {true, URL} | false
+> * No default
+>
+> Process the request body.
+>
+> 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.
+>
+> If the request body was processed successfully, `true` or
+> `{true, URL}` may be returned. If an URL is provided, the
+> response will redirect the client to the location of the
+> resource.
+>
+> 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`.
+
+### content_types_provided
+
+> * Methods: GET, HEAD
+> * Default value: [{{<<"text">>, <<"html">>, '*'}, to_html}]
+>
+> Types:
+> * Value = [{binary() | {Type, SubType, Params}, ProvideResource}]
+> * Type = SubType = binary()
+> * Params = '*' | [{binary(), binary()}]
+> * AcceptResource = atom()
+>
+> Return the list of content-types the resource provides.
+>
+> The list must be ordered 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.
+>
+> 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.
+>
+> The `ProvideResource` value is the name of the callback that will
+> be called if the content-type matches. It is defined as follow.
+>
+> * Value type: iodata() | {stream, Fun} | {stream, Len, Fun} | {chunked, ChunkedFun}
+> * No default
+>
+> Return the response body.
+>
+> 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.
+>
+> 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.
+
+### delete_completed
+
+> * Methods: DELETE
+> * Value type: boolean()
+> * Default value: true
+>
+> Return whether the delete action has been completed.
+>
+> This function should return `false` if there is no guarantee
+> that the resource gets deleted immediately 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`.
+
+### delete_resource
+
+> * Methods: DELETE
+> * Value type: boolean()
+> * Default value: false
+>
+> Delete the resource.
+>
+> The value returned indicates if the action was successful,
+> regardless of whether the resource is immediately deleted
+> from the system.
+
+### expires
+
+> * Methods: GET, HEAD
+> * Value type: calendar:datetime() | undefined
+> * Default value: undefined
+>
+> Return the date of expiration of the resource.
+>
+> This date will be sent as the value of the expires header.
+
+### forbidden
+
+> * Methods: all
+> * Value type: boolean()
+> * Default value: false
+>
+> Return whether access to the resource is forbidden.
+>
+> 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()
+> * Default value: undefined
+>
+> Return the entity tag of the resource.
+>
+> This value will be sent as the value of the etag header.
+
+### is_authorized
+
+> * Methods: all
+> * Value type: true | {false, AuthHeader}
+> * Default value: true
+>
+> Return whether the user is authorized to perform the action.
+>
+> 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.
+
+### is_conflict
+
+> * Methods: PUT
+> * Value type: boolean()
+> * Default value: false
+>
+> Return whether the put action results in a conflict.
+>
+> A `409 Conflict` response will be sent if this function
+> returns `true`.
+
+### known_content_type
+
+> * Methods: all
+> * Value type: boolean()
+> * Default value: true
+>
+> Return whether the content-type is known.
+>
+> This function determines if the server understands the
+> content-type, regardless of its use by the resource.
+
+### known_methods
+
+> * Methods: all
+> * Value type: [binary()]
+> * Default value: [<<"GET">>, <<"HEAD">>, <<"POST">>, <<"PUT">>, <<"PATCH">>, <<"DELETE">>, <<"OPTIONS">>]
+>
+> Return the list of known methods.
+>
+> The full list of methods known by the server should be
+> 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()]
+> * Skip to the next step if undefined
+>
+> Return the list of languages the resource provides.
+>
+> The list must be ordered in order of preference.
+>
+> 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.
+>
+> The chosen language will be set in the `Req` object as the meta
+> value `language`.
+>
+> While languages are case insensitive, this callback is expected
+> to return them as lowercase binary.
+
+### last_modified
+
+> * Methods: GET, HEAD, POST, PUT, PATCH, DELETE
+> * Value type: calendar:datetime()
+> * Default value: undefined
+>
+> Return the date of last modification of the resource.
+>
+> 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.
+
+### malformed_request
+
+> * Methods: all
+> * Value type: boolean()
+> * Default value: false
+>
+> Return whether the request is malformed.
+>
+> Cowboy has already performed all the necessary checks
+> by the time this function is called, so few resources
+> are expected to implement it.
+>
+> The check is to be done on the request itself, not on
+> the request body, which is processed later.
+
+### moved_permanently
+
+> * Methods: GET, HEAD, POST, PUT, PATCH, DELETE
+> * Value type: {true, URL} | false
+> * Default value: 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.
+
+### moved_temporarily
+
+> * Methods: GET, HEAD, POST, PATCH, DELETE
+> * Value type: {true, URL} | false
+> * Default value: false
+>
+> Return whether the resource was temporarily moved.
+>
+> If it was, its new URL is also returned and sent in the
+> location header in the response.
+
+### multiple_choices
+
+> * Methods: GET, HEAD, POST, PUT, PATCH, DELETE
+> * Value type: boolean()
+> * Default value: false
+>
+> Return whether there are multiple representations of the resource.
+>
+> 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)`.
+
+### options
+
+> * Methods: OPTIONS
+> * Value type: ok
+> * Default value: ok
+>
+> Handle a request for information.
+>
+> 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.
+
+### previously_existed
+
+> * Methods: GET, HEAD, POST, PATCH, DELETE
+> * Value type: boolean()
+> * Default value: false
+>
+> Return whether the resource existed previously.
+
+### resource_exists
+
+> * Methods: GET, HEAD, POST, PUT, PATCH, DELETE
+> * Value type: boolean()
+> * Default value: true
+>
+> Return whether the resource exists.
+>
+> If it exists, conditional headers will be tested before
+> attempting to perform the action. Otherwise, Cowboy will
+> check if the resource previously existed first.
+
+### service_available
+
+> * Methods: all
+> * Value type: boolean()
+> * Default value: true
+>
+> Return whether the service is available.
+>
+> This function can be used to test that all relevant backend
+> systems are up and able to handle requests.
+>
+> A `503 Service Unavailable` response will be sent if this
+> function returns `false`.
+
+### uri_too_long
+
+> * Methods: all
+> * Value type: boolean()
+> * Default value: false
+>
+> Return whether the requested URI is too long.
+>
+> Cowboy has already performed all the necessary checks
+> by the time this function is called, so few resources
+> are expected to implement it.
+>
+> A `414 Request-URI Too Long` response will be sent if this
+> function returns `true`.
+
+### valid_content_headers
+
+> * Methods: all
+> * Value type: boolean()
+> * Default value: true
+>
+> Return whether the content-* headers are valid.
+>
+> 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.
+>
+> A `501 Not Implemented` response will be sent if this
+> function returns `false`.
+
+### valid_entity_length
+
+> * Methods: all
+> * Value type: boolean()
+> * Default value: true
+>
+> Return whether the request body length is within acceptable boundaries.
+>
+> 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: []
+>
+> Return the list of 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 will automatically add the accept, accept-language and
+> accept-charset headers to the list if the respective functions
+> were defined in the resource.
+>
+> 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.
diff --git a/manual/cowboy_router.md b/manual/cowboy_router.md
new file mode 100644
index 0000000..1c6dc04
--- /dev/null
+++ b/manual/cowboy_router.md
@@ -0,0 +1,68 @@
+cowboy_router
+=============
+
+The `cowboy_router` middleware maps the requested host and
+path to the handler to be used for processing the request.
+It uses the dispatch rules compiled from the routes given
+to the `compile/1` function for this purpose. It adds the
+handler name and options to the environment as the values
+`handler` and `handler_opts` respectively.
+
+Environment input:
+ * dispatch = dispatch_rules()
+
+Environment output:
+ * handler = module()
+ * handler_opts = any()
+
+Types
+-----
+
+### bindings() = [{atom(), binary()}]
+
+> List of bindings found during routing.
+
+### constraints() = [IntConstraint | FunConstraint]
+
+> Types:
+> * IntConstraint = {atom(), int}
+> * FunConstraint = {atom(), function, Fun}
+> * Fun = fun((binary()) -> true | {true, any()} | false)
+>
+> List of constraints to apply to the bindings.
+>
+> The int constraint will convert the binding to an integer.
+> The fun constraint allows writing custom code for checking
+> the bindings. Returning a new value from that fun allows
+> replacing the current binding with a new value.
+
+### dispatch_rules() - opaque to the user
+
+> Rules for dispatching request used by Cowboy.
+
+### routes() = [{Host, Paths} | {Host, constraints(), Paths}]
+
+> Types:
+> * Host = Path = '_' | iodata()
+> * Paths = [{Path, Handler, Opts} | {Path, constraints(), Handler, Opts}]
+> * Handler = module()
+> * Opts = any()
+>
+> Human readable list of routes mapping hosts and paths to handlers.
+>
+> The syntax for routes is defined in the user guide.
+
+### tokens() = [binary()]
+
+> List of host_info and path_info tokens found during routing.
+
+Exports
+-------
+
+### compile(Routes) -> Dispatch
+
+> Types:
+> * Routes = routes()
+> * Dispatch = dispatch_rules()
+>
+> Compile the routes for use by Cowboy.
diff --git a/manual/cowboy_sub_protocol.md b/manual/cowboy_sub_protocol.md
new file mode 100644
index 0000000..a8ecae1
--- /dev/null
+++ b/manual/cowboy_sub_protocol.md
@@ -0,0 +1,34 @@
+cowboy_sub_protocol
+===================
+
+The `cowboy_sub_protocol` behaviour defines the interface used
+by modules that implement a protocol on top of HTTP.
+
+Types
+-----
+
+None.
+
+Callbacks
+---------
+
+### upgrade(Req, Env, Handler, Opts)
+ -> {ok, Req, Env}
+ | {suspend, Module, Function, Args}
+ | {halt, Req}
+ | {error, StatusCode, Req}
+
+> Types:
+> * Req = cowboy_req:req()
+> * Env = env()
+> * Handler = module()
+> * Opts = any()
+> * Module = module()
+> * Function = atom()
+> * Args = [any()]
+> * StatusCode = cowboy:http_status()
+>
+> Upgrade the protocol.
+>
+> Please refer to the `cowboy_middleware` manual for a
+> description of the return values.
diff --git a/manual/cowboy_websocket.md b/manual/cowboy_websocket.md
new file mode 100644
index 0000000..ae3ca1b
--- /dev/null
+++ b/manual/cowboy_websocket.md
@@ -0,0 +1,34 @@
+cowboy_websocket
+================
+
+The `cowboy_websocket` module implements the Websocket protocol.
+
+The callbacks for websocket handlers are defined in the manual
+for the `cowboy_websocket_handler` behaviour.
+
+Types
+-----
+
+### close_code() = 1000..4999
+
+> Reason for closing the connection.
+
+### frame() = close | ping | pong
+ | {text | binary | close | ping | pong, iodata()}
+ | {close, close_code(), iodata()}
+
+> Frames that can be sent to the client.
+
+Meta values
+-----------
+
+### websocket_version
+
+> Type: 7 | 8 | 13
+>
+> The version of the Websocket protocol being used.
+
+Exports
+-------
+
+None.
diff --git a/manual/cowboy_websocket_handler.md b/manual/cowboy_websocket_handler.md
new file mode 100644
index 0000000..f0480b1
--- /dev/null
+++ b/manual/cowboy_websocket_handler.md
@@ -0,0 +1,131 @@
+cowboy_websocket_handler
+========================
+
+The `cowboy_websocket_handler` behaviour defines the interface used
+by Websocket handlers.
+
+The `init/3` and `websocket_init/3` callbacks will always be called,
+followed by zero or more calls to `websocket_handle/3` and
+`websocket_info/3`. The `websocket_terminate/3` will always
+be called last.
+
+Types
+-----
+
+None.
+
+Callbacks
+---------
+
+### init({TransportName, ProtocolName}, Req, Opts)
+ -> {upgrade, protocol, cowboy_websocket}
+ | {upgrade, protocol, cowboy_websocket, Req, Opts}
+
+> Types:
+> * TransportName = tcp | ssl | atom()
+> * ProtocolName = http | atom()
+> * Req = cowboy_req:req()
+> * Opts = any()
+>
+> Upgrade the protocol to `cowboy_websocket`.
+
+### websocket_init(TransportName, Req, Opts)
+ -> {ok, Req, State}
+ | {ok, Req, State, hibernate}
+ | {ok, Req, State, Timeout}
+ | {ok, Req, State, Timeout, hibernate}
+ | {shutdown, Req}
+
+> Types:
+> * TransportName = tcp | ssl | atom()
+> * Req = cowboy_req:req()
+> * Opts = any()
+> * State = any()
+> * Timeout = timeout()
+>
+> Initialize the state for this session.
+>
+> This function is called before the upgrade to Websocket occurs.
+> It can be used to negotiate Websocket protocol extensions
+> with the client. It will typically be used to register this process
+> to an event manager or a message queue in order to receive
+> the messages the handler wants to process.
+>
+> The connection will stay up for a duration of up to `Timeout`
+> milliseconds after it last received data from the socket,
+> at which point it will stop and close the connection.
+> By default this value is set to `infinity`. It is recommended
+> to either set this value or ensure by any other mechanism
+> that the handler will be closed after a certain period of
+> inactivity.
+>
+> The `hibernate` option will hibernate the process until it
+> starts receiving either data from the Websocket connection
+> or Erlang messages.
+>
+> The `shutdown` return value can be used to close the connection
+> before upgrading to Websocket.
+
+### websocket_handle(InFrame, Req, State)
+ -> {ok, Req, State}
+ | {ok, Req, State, hibernate}
+ | {reply, OutFrame | [OutFrame], Req, State}
+ | {reply, OutFrame | [OutFrame], Req, State, hibernate}
+ | {shutdown, Req, State}
+
+> Types:
+> * InFrame = {text | binary | ping | pong, binary()}
+> * Req = cowboy_req:req()
+> * State = any()
+> * OutFrame = cowboy_websocket:frame()
+>
+> Handle the data received from the Websocket connection.
+>
+> This function will be called every time data is received
+> from the Websocket connection.
+>
+> The `shutdown` return value can be used to close the
+> connection. A close reply will also result in the connection
+> being closed.
+>
+> The `hibernate` option will hibernate the process until
+> it receives new data from the Websocket connection or an
+> Erlang message.
+
+### websocket_info(Info, Req, State)
+ -> {ok, Req, State}
+ | {ok, Req, State, hibernate}
+ | {reply, OutFrame | [OutFrame], Req, State}
+ | {reply, OutFrame | [OutFrame], Req, State, hibernate}
+ | {shutdown, Req, State}
+
+> Types:
+> * Info = any()
+> * Req = cowboy_req:req()
+> * State = any()
+> * OutFrame = cowboy_websocket:frame()
+>
+> Handle the Erlang message received.
+>
+> This function will be called every time an Erlang message
+> has been received. The message can be any Erlang term.
+>
+> The `shutdown` return value can be used to close the
+> connection. A close reply will also result in the connection
+> being closed.
+>
+> The `hibernate` option will hibernate the process until
+> it receives another message or new data from the Websocket
+> connection.
+
+### websocket_terminate(Reason, Req, State) -> ok
+
+> Types:
+> * Reason = {normal, shutdown | timeout} | {remote, closed} | {remote, cowboy_websocket:close_code(), binary()} | {error, badencoding | badframe | closed | atom()}
+> * Req = cowboy_req:req()
+> * State = any()
+>
+> Perform any necessary cleanup of the state.
+>
+> The connection will be closed and the process stopped right
+> after this call.
diff --git a/manual/toc.md b/manual/toc.md
new file mode 100644
index 0000000..d05696e
--- /dev/null
+++ b/manual/toc.md
@@ -0,0 +1,18 @@
+Cowboy Function Reference
+=========================
+
+The function reference documents the public interface of Cowboy.
+
+ * [The Cowboy Application](cowboy_app.md)
+ * [cowboy](cowboy.md)
+ * [cowboy_handler](cowboy_handler.md)
+ * [cowboy_http_handler](cowboy_http_handler.md)
+ * [cowboy_loop_handler](cowboy_loop_handler.md)
+ * [cowboy_middleware](cowboy_middleware.md)
+ * [cowboy_protocol](cowboy_protocol.md)
+ * [cowboy_req](cowboy_req.md)
+ * [cowboy_rest](cowboy_rest.md)
+ * [cowboy_router](cowboy_router.md)
+ * [cowboy_sub_protocol](cowboy_sub_protocol.md)
+ * [cowboy_websocket](cowboy_websocket.md)
+ * [cowboy_websocket_handler](cowboy_websocket_handler.md)