diff options
author | Loïc Hoguin <[email protected]> | 2016-08-31 17:10:57 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2016-08-31 17:10:57 +0200 |
commit | aea877d1a49951165856a46b702cafd2356a26b5 (patch) | |
tree | 3d93dd3f44178cb6c62c1219b8cbb9bb9e808e16 /docs | |
parent | 535795ce51750412439e205b14779f107d81a5e5 (diff) | |
download | ninenines.eu-aea877d1a49951165856a46b702cafd2356a26b5.tar.gz ninenines.eu-aea877d1a49951165856a46b702cafd2356a26b5.tar.bz2 ninenines.eu-aea877d1a49951165856a46b702cafd2356a26b5.zip |
Update documentation
Diffstat (limited to 'docs')
-rw-r--r-- | docs/en/cowboy/2.0/guide/resp.asciidoc | 363 | ||||
-rw-r--r-- | docs/en/cowboy/2.0/guide/resp/index.html | 343 | ||||
-rw-r--r-- | docs/en/cowboy/2.0/guide/ws_handlers.asciidoc | 30 | ||||
-rw-r--r-- | docs/en/cowboy/2.0/guide/ws_handlers/index.html | 30 | ||||
-rw-r--r-- | docs/en/cowboy/2.0/manual/cowboy_websocket/index.html | 28 |
5 files changed, 505 insertions, 289 deletions
diff --git a/docs/en/cowboy/2.0/guide/resp.asciidoc b/docs/en/cowboy/2.0/guide/resp.asciidoc index 1ffdfbd5..b8ba7d5a 100644 --- a/docs/en/cowboy/2.0/guide/resp.asciidoc +++ b/docs/en/cowboy/2.0/guide/resp.asciidoc @@ -1,201 +1,318 @@ [[resp]] == Sending a response -The Req object also allows you to send a response. +The response must be sent using the Req object. -You can only send one response. Any other attempt will -trigger a crash. The response may be sent in one go or -with its body streamed by chunks of arbitrary size. +Cowboy provides two different ways of sending responses: +either directly or by streaming the body. Response headers +and body may be set in advance. The response is sent as +soon as one of the reply or stream reply function is +called. -You can also set headers or the response body in advance -and Cowboy will use them when you finally do reply. +Cowboy also provides a simplified interface for sending +files. It can also send only specific parts of a file. + +While only one response is allowed for every request, +HTTP/2 introduced a mechanism that allows the server +to push additional resources related to the response. +This chapter also describes how this feature works in +Cowboy. === Reply -You can send a reply with no particular headers or body. -Cowboy will make sure to send the mandatory headers with -the response. +Cowboy provides three functions for sending the entire reply, +depending on whether you need to set headers and body. In all +cases, Cowboy will add any headers required by the protocol +(for example the date header will always be sent). + +When you need to set only the status code, +use `cowboy_req:reply/2`: [source,erlang] -Req2 = cowboy_req:reply(200, Req). +Req = cowboy_req:reply(200, Req0). -You can define headers to be sent with the response. Note -that header names must be lowercase. Again, Cowboy will -make sure to send the mandatory headers with the response. +When you need to set response headers at the same time, +use `cowboy_req:reply/3`: [source,erlang] ---- -Req2 = cowboy_req:reply(303, [ - {<<"location">>, <<"http://ninenines.eu">>} -], Req). +Req = cowboy_req:reply(303, #{ + <<"location">> => <<"http://ninenines.eu">> +}, Req0). ---- -You can override headers that Cowboy would send otherwise. -Any header set by the user will be used over the ones set -by Cowboy. For example, you can advertise yourself as a -different server. +Note that the header name must always be a lowercase +binary. + +When you also need to set the response body, +use `cowboy_req:reply/4`: [source,erlang] ---- -Req2 = cowboy_req:reply(200, [ - {<<"server">>, <<"yaws">>} -], Req). +Req = cowboy_req:reply(200, #{ + <<"content-type">> => <<"text/plain">> +}, "Hello world!", Req0). ---- -We also saw earlier how to force close the connection by -overriding the connection header. +You should always set the content-type header when the +response has a body. There is however no need to set +the content-length header; Cowboy does it automatically. -Finally, you can also send a body with the response. Cowboy -will automatically set the content-length header if you do. -We recommend that you set the content-type header so the -client may know how to read the body. +The response body and the header values must be either +a binary or an iolist. An iolist is a list containing +binaries, characters, strings or other iolists. This +allows you to build a response from different parts +without having to do any concatenation: [source,erlang] ---- -Req2 = cowboy_req:reply(200, [ - {<<"content-type">>, <<"text/plain">>} -], "Hello world!", Req). +Title = "Hello world!", +Body = <<"Hats off!">>, +Req = cowboy_req:reply(200, #{ + <<"content-type">> => <<"text/html">> +}, ["<html><head><title>", Title, "</title></head>", + "<body><p>", Body, "</p></body></html>"], Req0). ---- -Here is the same example but sending HTML this time. +This method of building responses is more efficient than +concatenating. Behind the scenes, each element of the list +is simply a pointer, and those pointers are used directly +when writing to the socket. -[source,erlang] ----- -Req2 = cowboy_req:reply(200, [ - {<<"content-type">>, <<"text/html">>} -], "<html><head>Hello world!</head><body><p>Hats off!</p></body></html>", Req). ----- +=== Stream reply -Note that the reply is sent immediately. +Cowboy provides two functions for initiating a response, +and an additional function for streaming the response body. +Cowboy will add any required headers to the response. -=== Chunked reply +// @todo For HTTP/1.1 Cowboy should probably not use chunked transfer-encoding if the content-length is set. -You can also stream the response body. First, you need to -initiate the reply by sending the response status code. -Then you can send the body in chunks of arbitrary size. +When you need to set only the status code, +use `cowboy_req:stream_reply/2`: [source,erlang] -Req2 = cowboy_req:chunked_reply(200, Req), -cowboy_req:chunk("Hello...", Req2), -cowboy_req:chunk("chunked...", Req2), -cowboy_req:chunk("world!!", Req2). +---- +Req = cowboy_req:stream_reply(200, Req0), -You should make sure to match on `ok` as an error may be -returned. +cowboy_req:stream_body("Hello...", nofin, Req), +cowboy_req:stream_body("chunked...", nofin, Req), +cowboy_req:stream_body("world!!", fin, Req). +---- + +The second argument to `cowboy_req:stream_body/3` indicates +whether this data terminates the body. Use `fin` for the +final flag, and `nofin` otherwise. -While it is possible to send a chunked response without -a content-type header, it is still recommended. You can -set this header or any other just like for normal replies. +This snippet does not set a content-type header. This is +not recommended. All responses with a body should have +a content-type. The header can be set beforehand, or +using the `cowboy_req:stream_reply/3`: [source,erlang] ---- -Req2 = cowboy_req:chunked_reply(200, [ - {<<"content-type">>, <<"text/html">>} -], Req), -cowboy_req:chunk("<html><head>Hello world!</head>", Req2), -cowboy_req:chunk("<body><p>Hats off!</p></body></html>", Req2). +Req = cowboy_req:stream_reply(200, #{ + <<"content-type">> => <<"text/html">> +}, Req0), + +cowboy_req:stream_body("<html><head>Hello world!</head>", nofin, Req), +cowboy_req:stream_body("<body><p>Hats off!</p></body></html>", fin, Req). ---- -Note that the reply and each chunk following it are sent -immediately. +HTTP provides a few different ways to stream response bodies. +Cowboy will select the most appropriate one based on the HTTP +version and the request and response headers. + +While not required by any means, it is recommended that you +set the content-length header in the response if you know it +in advance. This will ensure that the best response method +is selected and help clients understand when the response +is fully received. + +// @todo Document trailers here. === Preset response headers -You can define response headers in advance. They will be -merged into the headers given in the reply call. Headers -in the reply call override preset response headers which -override the default Cowboy headers. +Cowboy provides functions to set response headers without +immediately sending them. They are stored in the Req object +and sent as part of the response when a reply function is +called. + +To set response headers: [source,erlang] -Req2 = cowboy_req:set_resp_header(<<"allow">>, "GET", Req). +Req = cowboy_req:set_resp_header(<<"allow">>, "GET", Req0). + +Header names must be a lowercase binary. -You can check if a response header has already been set. -This will only check the response headers that you set, -and not the ones Cowboy will add when actually sending -the reply. +Do not use this function for setting cookies. Refer to +the xref:cookies[Cookies] chapter for more information. + +To check if a response header has already been set: [source,erlang] cowboy_req:has_resp_header(<<"allow">>, Req). -It will return `true` if the header is defined, and `false` -otherwise. +It returns `true` if the header was set, `false` otherwise. -Finally, you can also delete a preset response header if -needed. If you do, it will not be sent. +To delete a response header that was set previously: [source,erlang] -Req2 = cowboy_req:delete_resp_header(<<"allow">>, Req). +Req = cowboy_req:delete_resp_header(<<"allow">>, Req0). -=== Preset response body +=== Overriding headers -You can set the response body in advance. Note that this -body will be ignored if you then choose to send a chunked -reply, or if you send a reply with an explicit body. +As Cowboy provides different ways of setting response +headers and body, clashes may occur, so it's important +to understand what happens when a header is set twice. -[source,erlang] -Req2 = cowboy_req:set_resp_body("Hello world!", Req). +Headers come from five different origins: + +* Protocol-specific headers (for example HTTP/1.1's connection header) +* Other required headers (for example the date header) +* Preset headers +* Headers given to the reply function +* Set-cookie headers + +Cowboy does not allow overriding protocol-specific headers. + +Set-cookie headers will always be appended at the end of +the list of headers before sending the response. + +Headers given to the reply function will always override +preset headers and required headers. If a header is found +in two or three of these, then the one in the reply function +is picked and the others are dropped. -You can also set a fun that will be called when it is time -to send the body. There are three different ways of doing -that. +Similarly, preset headers will always override required +headers. -If you know the length of the body that needs to be sent, -you should specify it, as it will help clients determine -the remaining download time and allow them to inform the -user. +To illustrate, look at the following snippet. Cowboy by +default sends the server header with the value "Cowboy". +We can override it: [source,erlang] ---- -F = fun (Socket, Transport) -> - Transport:send(Socket, "Hello world!") -end, -Req2 = cowboy_req:set_resp_body_fun(12, F, Req). +Req = cowboy_req:reply(200, #{ + <<"server">> => <<"yaws">> +}, Req0). ---- -If you do not know the length of the body, you should use -a chunked response body fun instead. +=== Preset response body + +Cowboy provides functions to set the response body without +immediately sending it. It is stored in the Req object and +sent when the reply function is called. + +To set the response body: [source,erlang] ----- -F = fun (SendChunk) -> - Body = lists:duplicate(random:uniform(1024, $a)), - SendChunk(Body) -end, -Req2 = cowboy_req:set_resp_body_fun(chunked, F, Req). ----- +Req = cowboy_req:set_resp_body("Hello world!", Req0). + +// @todo Yeah we probably should add that function that +// also sets the content-type at the same time... -Finally, you can also send data on the socket directly, -without knowing the length in advance. Cowboy may be -forced to close the connection at the end of the response -though depending on the protocol capabilities. +To check if a response body has already been set: + +[source,erlang] +cowboy_req:has_resp_body(Req). + +It returns `true` if the body was set and is non-empty, +`false` otherwise. + +// @todo We probably should also have a function that +// properly removes the response body, including any +// content-* headers. + +The preset response body is only sent if the reply function +used is `cowboy_req:reply/2` or `cowboy_req:reply/3`. + +=== Sending files + +Cowboy provides a shortcut for sending files. When +using `cowboy_req:reply/4`, or when presetting the +response header, you can give a `sendfile` tuple to +Cowboy: + +[source,erlang] +{sendfile, Offset, Length, Filename} + +Depending on the values for `Offset` or `Length`, the +entire file may be sent, or just a part of it. + +The length is required even for sending the entire file. +Cowboy sends it in the content-length header. + +To send a file while replying: [source,erlang] ---- -F = fun (Socket, Transport) -> - Body = lists:duplicate(random:uniform(1024, $a)), - Transport:send(Socket, Body) -end, -Req2 = cowboy_req:set_resp_body_fun(F, Req). +Req = cowboy_req:reply(200, #{ + <<"content-type">> => "image/png" +}, {sendfile, 0, 12345, "path/to/logo.png"}, Req0). ---- -=== Sending files +// @todo An example of presetting a file would be useful, +// but let's wait for the function that can set the +// content-type at the same time. + +// @todo What about streaming many files? For example +// it should be possible to build a tar file on the fly +// while still using sendfile. Another example could be +// proper support for multipart byte ranges. Yet another +// example would be automatic concatenation of CSS or JS +// files. + +=== Push + +The HTTP/2 protocol introduced the ability to push resources +related to the one sent in the response. Cowboy provides two +functions for that purpose: `cowboy_req:push/3,4`. + +Push is only available for HTTP/2. Cowboy will automatically +ignore push requests if the protocol doesn't support it. + +The push function must be called before any of the reply +functions. Doing otherwise will result in a crash. + +To push a resource, you need to provide the same information +as a client performing a request would. This includes the +HTTP method, the URI and any necessary request headers. -You can send files directly from disk without having to -read them. Cowboy will use the `sendfile` syscall when -possible, which means that the file is sent to the socket -directly from the kernel, which is a lot more performant -than doing it from userland. +Cowboy by default only requires you to give the path to +the resource and the request headers. The rest of the URI +is taken from the current request (excluding the query +string, set to empty) and the method is GET by default. -Again, it is recommended to set the size of the file if it -can be known in advance. +The following snippet pushes a CSS file that is linked to +in the response: [source,erlang] ---- -F = fun (Socket, Transport) -> - Transport:sendfile(Socket, "priv/styles.css") -end, -Req2 = cowboy_req:set_resp_body_fun(FileSize, F, Req). +cowboy_req:push("/static/style.css", #{ + <<"accept">> => <<"text/css">> +}, Req0), +Req = cowboy_req:reply(200, #{ + <<"content-type">> => <<"text/html">> +}, ["<html><head><title>My web page</title>", + "<link rel='stylesheet' type='text/css' href='/static/style.css'>", + "<body><p>Welcome to Erlang!</p></body></html>"], Req0). ---- -Please see the Ranch guide for more information about -sending files. +To override the method, scheme, host, port or query string, +simply pass in a fourth argument. The following snippet +uses a different host name: + +[source,erlang] +---- +cowboy_req:push("/static/style.css", #{ + <<"accept">> => <<"text/css">> +}, #{host => <<"cdn.example.org">>}, Req), +---- + +Pushed resources don't have to be files. As long as the push +request is cacheable, safe and does not include a body, the +resource can be pushed. + +Under the hood, Cowboy handles pushed requests the same as +normal requests: a different process is created which will +ultimately send a response to the client. diff --git a/docs/en/cowboy/2.0/guide/resp/index.html b/docs/en/cowboy/2.0/guide/resp/index.html index 424a97d3..b87b1efa 100644 --- a/docs/en/cowboy/2.0/guide/resp/index.html +++ b/docs/en/cowboy/2.0/guide/resp/index.html @@ -69,219 +69,320 @@ <h1 class="lined-header"><span>Sending a response</span></h1> -<div class="paragraph"><p>The Req object also allows you to send a response.</p></div>
-<div class="paragraph"><p>You can only send one response. Any other attempt will
-trigger a crash. The response may be sent in one go or
-with its body streamed by chunks of arbitrary size.</p></div>
-<div class="paragraph"><p>You can also set headers or the response body in advance
-and Cowboy will use them when you finally do reply.</p></div>
+<div class="paragraph"><p>The response must be sent using the Req object.</p></div>
+<div class="paragraph"><p>Cowboy provides two different ways of sending responses:
+either directly or by streaming the body. Response headers
+and body may be set in advance. The response is sent as
+soon as one of the reply or stream reply function is
+called.</p></div>
+<div class="paragraph"><p>Cowboy also provides a simplified interface for sending
+files. It can also send only specific parts of a file.</p></div>
+<div class="paragraph"><p>While only one response is allowed for every request,
+HTTP/2 introduced a mechanism that allows the server
+to push additional resources related to the response.
+This chapter also describes how this feature works in
+Cowboy.</p></div>
<div class="sect1">
<h2 id="_reply">Reply</h2>
<div class="sectionbody">
-<div class="paragraph"><p>You can send a reply with no particular headers or body.
-Cowboy will make sure to send the mandatory headers with
-the response.</p></div>
+<div class="paragraph"><p>Cowboy provides three functions for sending the entire reply,
+depending on whether you need to set headers and body. In all
+cases, Cowboy will add any headers required by the protocol
+(for example the date header will always be sent).</p></div>
+<div class="paragraph"><p>When you need to set only the status code,
+use <code>cowboy_req:reply/2</code>:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>You can define headers to be sent with the response. Note
-that header names must be lowercase. Again, Cowboy will
-make sure to send the mandatory headers with the response.</p></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>When you need to set response headers at the same time,
+use <code>cowboy_req:reply/3</code>:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">303</span>, [
- {<span style="color: #990000"><<</span><span style="color: #FF0000">"location"</span><span style="color: #990000">>></span>, <span style="color: #990000"><<</span><span style="color: #FF0000">"http://ninenines.eu"</span><span style="color: #990000">>></span>}
-], <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>You can override headers that Cowboy would send otherwise.
-Any header set by the user will be used over the ones set
-by Cowboy. For example, you can advertise yourself as a
-different server.</p></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">303</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"location"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"http://ninenines.eu"</span><span style="color: #990000">>></span>
+}, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>Note that the header name must always be a lowercase
+binary.</p></div>
+<div class="paragraph"><p>When you also need to set the response body,
+use <code>cowboy_req:reply/4</code>:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, [
- {<span style="color: #990000"><<</span><span style="color: #FF0000">"server"</span><span style="color: #990000">>></span>, <span style="color: #990000"><<</span><span style="color: #FF0000">"yaws"</span><span style="color: #990000">>></span>}
-], <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>We also saw earlier how to force close the connection by
-overriding the connection header.</p></div>
-<div class="paragraph"><p>Finally, you can also send a body with the response. Cowboy
-will automatically set the content-length header if you do.
-We recommend that you set the content-type header so the
-client may know how to read the body.</p></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"text/plain"</span><span style="color: #990000">>></span>
+}, <span style="color: #FF0000">"Hello world!"</span>, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>You should always set the content-type header when the
+response has a body. There is however no need to set
+the content-length header; Cowboy does it automatically.</p></div>
+<div class="paragraph"><p>The response body and the header values must be either
+a binary or an iolist. An iolist is a list containing
+binaries, characters, strings or other iolists. This
+allows you to build a response from different parts
+without having to do any concatenation:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, [
- {<span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span>, <span style="color: #990000"><<</span><span style="color: #FF0000">"text/plain"</span><span style="color: #990000">>></span>}
-], <span style="color: #FF0000">"Hello world!"</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>Here is the same example but sending HTML this time.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, [
- {<span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span>, <span style="color: #990000"><<</span><span style="color: #FF0000">"text/html"</span><span style="color: #990000">>></span>}
-], <span style="color: #FF0000">"<html><head>Hello world!</head><body><p>Hats off!</p></body></html>"</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>Note that the reply is sent immediately.</p></div>
+<pre><tt><span style="color: #009900">Title</span> <span style="color: #990000">=</span> <span style="color: #FF0000">"Hello world!"</span>,
+<span style="color: #009900">Body</span> <span style="color: #990000">=</span> <span style="color: #990000"><<</span><span style="color: #FF0000">"Hats off!"</span><span style="color: #990000">>></span>,
+<span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"text/html"</span><span style="color: #990000">>></span>
+}, [<span style="color: #FF0000">"<html><head><title>"</span>, <span style="color: #009900">Title</span>, <span style="color: #FF0000">"</title></head>"</span>,
+ <span style="color: #FF0000">"<body><p>"</span>, <span style="color: #009900">Body</span>, <span style="color: #FF0000">"</p></body></html>"</span>], <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>This method of building responses is more efficient than
+concatenating. Behind the scenes, each element of the list
+is simply a pointer, and those pointers are used directly
+when writing to the socket.</p></div>
</div>
</div>
<div class="sect1">
-<h2 id="_chunked_reply">Chunked reply</h2>
+<h2 id="_stream_reply">Stream reply</h2>
<div class="sectionbody">
-<div class="paragraph"><p>You can also stream the response body. First, you need to
-initiate the reply by sending the response status code.
-Then you can send the body in chunks of arbitrary size.</p></div>
+<div class="paragraph"><p>Cowboy provides two functions for initiating a response,
+and an additional function for streaming the response body.
+Cowboy will add any required headers to the response.</p></div>
+<div class="paragraph"><p>When you need to set only the status code,
+use <code>cowboy_req:stream_reply/2</code>:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:chunked_reply</span></span>(<span style="color: #993399">200</span>, <span style="color: #009900">Req</span>),
-<span style="font-weight: bold"><span style="color: #000000">cowboy_req:chunk</span></span>(<span style="color: #FF0000">"Hello..."</span>, <span style="color: #009900">Req2</span>),
-<span style="font-weight: bold"><span style="color: #000000">cowboy_req:chunk</span></span>(<span style="color: #FF0000">"chunked..."</span>, <span style="color: #009900">Req2</span>),
-<span style="font-weight: bold"><span style="color: #000000">cowboy_req:chunk</span></span>(<span style="color: #FF0000">"world!!"</span>, <span style="color: #009900">Req2</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>You should make sure to match on <code>ok</code> as an error may be
-returned.</p></div>
-<div class="paragraph"><p>While it is possible to send a chunked response without
-a content-type header, it is still recommended. You can
-set this header or any other just like for normal replies.</p></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:stream_reply</span></span>(<span style="color: #993399">200</span>, <span style="color: #009900">Req0</span>),
+
+<span style="font-weight: bold"><span style="color: #000000">cowboy_req:stream_body</span></span>(<span style="color: #FF0000">"Hello..."</span>, <span style="color: #FF6600">nofin</span>, <span style="color: #009900">Req</span>),
+<span style="font-weight: bold"><span style="color: #000000">cowboy_req:stream_body</span></span>(<span style="color: #FF0000">"chunked..."</span>, <span style="color: #FF6600">nofin</span>, <span style="color: #009900">Req</span>),
+<span style="font-weight: bold"><span style="color: #000000">cowboy_req:stream_body</span></span>(<span style="color: #FF0000">"world!!"</span>, <span style="color: #FF6600">fin</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>The second argument to <code>cowboy_req:stream_body/3</code> indicates
+whether this data terminates the body. Use <code>fin</code> for the
+final flag, and <code>nofin</code> otherwise.</p></div>
+<div class="paragraph"><p>This snippet does not set a content-type header. This is
+not recommended. All responses with a body should have
+a content-type. The header can be set beforehand, or
+using the <code>cowboy_req:stream_reply/3</code>:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:chunked_reply</span></span>(<span style="color: #993399">200</span>, [
- {<span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span>, <span style="color: #990000"><<</span><span style="color: #FF0000">"text/html"</span><span style="color: #990000">>></span>}
-], <span style="color: #009900">Req</span>),
-<span style="font-weight: bold"><span style="color: #000000">cowboy_req:chunk</span></span>(<span style="color: #FF0000">"<html><head>Hello world!</head>"</span>, <span style="color: #009900">Req2</span>),
-<span style="font-weight: bold"><span style="color: #000000">cowboy_req:chunk</span></span>(<span style="color: #FF0000">"<body><p>Hats off!</p></body></html>"</span>, <span style="color: #009900">Req2</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>Note that the reply and each chunk following it are sent
-immediately.</p></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:stream_reply</span></span>(<span style="color: #993399">200</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"text/html"</span><span style="color: #990000">>></span>
+}, <span style="color: #009900">Req0</span>),
+
+<span style="font-weight: bold"><span style="color: #000000">cowboy_req:stream_body</span></span>(<span style="color: #FF0000">"<html><head>Hello world!</head>"</span>, <span style="color: #FF6600">nofin</span>, <span style="color: #009900">Req</span>),
+<span style="font-weight: bold"><span style="color: #000000">cowboy_req:stream_body</span></span>(<span style="color: #FF0000">"<body><p>Hats off!</p></body></html>"</span>, <span style="color: #FF6600">fin</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>HTTP provides a few different ways to stream response bodies.
+Cowboy will select the most appropriate one based on the HTTP
+version and the request and response headers.</p></div>
+<div class="paragraph"><p>While not required by any means, it is recommended that you
+set the content-length header in the response if you know it
+in advance. This will ensure that the best response method
+is selected and help clients understand when the response
+is fully received.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_preset_response_headers">Preset response headers</h2>
<div class="sectionbody">
-<div class="paragraph"><p>You can define response headers in advance. They will be
-merged into the headers given in the reply call. Headers
-in the reply call override preset response headers which
-override the default Cowboy headers.</p></div>
+<div class="paragraph"><p>Cowboy provides functions to set response headers without
+immediately sending them. They are stored in the Req object
+and sent as part of the response when a reply function is
+called.</p></div>
+<div class="paragraph"><p>To set response headers:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_header</span></span>(<span style="color: #990000"><<</span><span style="color: #FF0000">"allow"</span><span style="color: #990000">>></span>, <span style="color: #FF0000">"GET"</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>You can check if a response header has already been set.
-This will only check the response headers that you set,
-and not the ones Cowboy will add when actually sending
-the reply.</p></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_header</span></span>(<span style="color: #990000"><<</span><span style="color: #FF0000">"allow"</span><span style="color: #990000">>></span>, <span style="color: #FF0000">"GET"</span>, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>Header names must be a lowercase binary.</p></div>
+<div class="paragraph"><p>Do not use this function for setting cookies. Refer to
+the <a href="../cookies">Cookies</a> chapter for more information.</p></div>
+<div class="paragraph"><p>To check if a response header has already been set:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-weight: bold"><span style="color: #000000">cowboy_req:has_resp_header</span></span>(<span style="color: #990000"><<</span><span style="color: #FF0000">"allow"</span><span style="color: #990000">>></span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>It will return <code>true</code> if the header is defined, and <code>false</code>
-otherwise.</p></div>
-<div class="paragraph"><p>Finally, you can also delete a preset response header if
-needed. If you do, it will not be sent.</p></div>
+<div class="paragraph"><p>It returns <code>true</code> if the header was set, <code>false</code> otherwise.</p></div>
+<div class="paragraph"><p>To delete a response header that was set previously:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:delete_resp_header</span></span>(<span style="color: #990000"><<</span><span style="color: #FF0000">"allow"</span><span style="color: #990000">>></span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:delete_resp_header</span></span>(<span style="color: #990000"><<</span><span style="color: #FF0000">"allow"</span><span style="color: #990000">>></span>, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_overriding_headers">Overriding headers</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>As Cowboy provides different ways of setting response
+headers and body, clashes may occur, so it’s important
+to understand what happens when a header is set twice.</p></div>
+<div class="paragraph"><p>Headers come from five different origins:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Protocol-specific headers (for example HTTP/1.1’s connection header)
+</p>
+</li>
+<li>
+<p>
+Other required headers (for example the date header)
+</p>
+</li>
+<li>
+<p>
+Preset headers
+</p>
+</li>
+<li>
+<p>
+Headers given to the reply function
+</p>
+</li>
+<li>
+<p>
+Set-cookie headers
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>Cowboy does not allow overriding protocol-specific headers.</p></div>
+<div class="paragraph"><p>Set-cookie headers will always be appended at the end of
+the list of headers before sending the response.</p></div>
+<div class="paragraph"><p>Headers given to the reply function will always override
+preset headers and required headers. If a header is found
+in two or three of these, then the one in the reply function
+is picked and the others are dropped.</p></div>
+<div class="paragraph"><p>Similarly, preset headers will always override required
+headers.</p></div>
+<div class="paragraph"><p>To illustrate, look at the following snippet. Cowboy by
+default sends the server header with the value "Cowboy".
+We can override it:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"server"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"yaws"</span><span style="color: #990000">>></span>
+}, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
</div>
</div>
<div class="sect1">
<h2 id="_preset_response_body">Preset response body</h2>
<div class="sectionbody">
-<div class="paragraph"><p>You can set the response body in advance. Note that this
-body will be ignored if you then choose to send a chunked
-reply, or if you send a reply with an explicit body.</p></div>
+<div class="paragraph"><p>Cowboy provides functions to set the response body without
+immediately sending it. It is stored in the Req object and
+sent when the reply function is called.</p></div>
+<div class="paragraph"><p>To set the response body:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_body</span></span>(<span style="color: #FF0000">"Hello world!"</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>You can also set a fun that will be called when it is time
-to send the body. There are three different ways of doing
-that.</p></div>
-<div class="paragraph"><p>If you know the length of the body that needs to be sent,
-you should specify it, as it will help clients determine
-the remaining download time and allow them to inform the
-user.</p></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_body</span></span>(<span style="color: #FF0000">"Hello world!"</span>, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>To check if a response body has already been set:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">F</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">fun</span></span> (<span style="color: #009900">Socket</span>, <span style="color: #009900">Transport</span>) <span style="color: #990000">-></span>
- <span style="color: #009900">Transport</span><span style="color: #990000">:</span><span style="font-weight: bold"><span style="color: #000000">send</span></span>(<span style="color: #009900">Socket</span>, <span style="color: #FF0000">"Hello world!"</span>)
-<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>,
-<span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_body_fun</span></span>(<span style="color: #993399">12</span>, <span style="color: #009900">F</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>If you do not know the length of the body, you should use
-a chunked response body fun instead.</p></div>
+<pre><tt><span style="font-weight: bold"><span style="color: #000000">cowboy_req:has_resp_body</span></span>(<span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>It returns <code>true</code> if the body was set and is non-empty,
+<code>false</code> otherwise.</p></div>
+<div class="paragraph"><p>The preset response body is only sent if the reply function
+used is <code>cowboy_req:reply/2</code> or <code>cowboy_req:reply/3</code>.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_sending_files">Sending files</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Cowboy provides a shortcut for sending files. When
+using <code>cowboy_req:reply/4</code>, or when presetting the
+response header, you can give a <code>sendfile</code> tuple to
+Cowboy:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">F</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">fun</span></span> (<span style="color: #009900">SendChunk</span>) <span style="color: #990000">-></span>
- <span style="color: #009900">Body</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">lists:duplicate</span></span>(<span style="font-weight: bold"><span style="color: #000000">random:uniform</span></span>(<span style="color: #993399">1024</span>, <span style="color: #FF0000">$a</span>)),
- <span style="color: #009900">SendChunk</span>(<span style="color: #009900">Body</span>)
-<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>,
-<span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_body_fun</span></span>(<span style="color: #FF6600">chunked</span>, <span style="color: #009900">F</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>Finally, you can also send data on the socket directly,
-without knowing the length in advance. Cowboy may be
-forced to close the connection at the end of the response
-though depending on the protocol capabilities.</p></div>
+<pre><tt>{<span style="color: #FF6600">sendfile</span>, <span style="color: #009900">Offset</span>, <span style="color: #009900">Length</span>, <span style="color: #009900">Filename</span>}</tt></pre></div></div>
+<div class="paragraph"><p>Depending on the values for <code>Offset</code> or <code>Length</code>, the
+entire file may be sent, or just a part of it.</p></div>
+<div class="paragraph"><p>The length is required even for sending the entire file.
+Cowboy sends it in the content-length header.</p></div>
+<div class="paragraph"><p>To send a file while replying:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">F</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">fun</span></span> (<span style="color: #009900">Socket</span>, <span style="color: #009900">Transport</span>) <span style="color: #990000">-></span>
- <span style="color: #009900">Body</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">lists:duplicate</span></span>(<span style="font-weight: bold"><span style="color: #000000">random:uniform</span></span>(<span style="color: #993399">1024</span>, <span style="color: #FF0000">$a</span>)),
- <span style="color: #009900">Transport</span><span style="color: #990000">:</span><span style="font-weight: bold"><span style="color: #000000">send</span></span>(<span style="color: #009900">Socket</span>, <span style="color: #009900">Body</span>)
-<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>,
-<span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_body_fun</span></span>(<span style="color: #009900">F</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<pre><tt><span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #FF0000">"image/png"</span>
+}, {<span style="color: #FF6600">sendfile</span>, <span style="color: #993399">0</span>, <span style="color: #993399">12345</span>, <span style="color: #FF0000">"path/to/logo.png"</span>}, <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
</div>
</div>
<div class="sect1">
-<h2 id="_sending_files">Sending files</h2>
+<h2 id="_push">Push</h2>
<div class="sectionbody">
-<div class="paragraph"><p>You can send files directly from disk without having to
-read them. Cowboy will use the <code>sendfile</code> syscall when
-possible, which means that the file is sent to the socket
-directly from the kernel, which is a lot more performant
-than doing it from userland.</p></div>
-<div class="paragraph"><p>Again, it is recommended to set the size of the file if it
-can be known in advance.</p></div>
+<div class="paragraph"><p>The HTTP/2 protocol introduced the ability to push resources
+related to the one sent in the response. Cowboy provides two
+functions for that purpose: <code>cowboy_req:push/3,4</code>.</p></div>
+<div class="paragraph"><p>Push is only available for HTTP/2. Cowboy will automatically
+ignore push requests if the protocol doesn’t support it.</p></div>
+<div class="paragraph"><p>The push function must be called before any of the reply
+functions. Doing otherwise will result in a crash.</p></div>
+<div class="paragraph"><p>To push a resource, you need to provide the same information
+as a client performing a request would. This includes the
+HTTP method, the URI and any necessary request headers.</p></div>
+<div class="paragraph"><p>Cowboy by default only requires you to give the path to
+the resource and the request headers. The rest of the URI
+is taken from the current request (excluding the query
+string, set to empty) and the method is GET by default.</p></div>
+<div class="paragraph"><p>The following snippet pushes a CSS file that is linked to
+in the response:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.8
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #000000">cowboy_req:push</span></span>(<span style="color: #FF0000">"/static/style.css"</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"accept"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"text/css"</span><span style="color: #990000">>></span>
+}, <span style="color: #009900">Req0</span>),
+<span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:reply</span></span>(<span style="color: #993399">200</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"content-type"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"text/html"</span><span style="color: #990000">>></span>
+}, [<span style="color: #FF0000">"<html><head><title>My web page</title>"</span>,
+ <span style="color: #FF0000">"<link rel='stylesheet' type='text/css' href='/static/style.css'>"</span>,
+ <span style="color: #FF0000">"<body><p>Welcome to Erlang!</p></body></html>"</span>], <span style="color: #009900">Req0</span>)<span style="color: #990000">.</span></tt></pre></div></div>
+<div class="paragraph"><p>To override the method, scheme, host, port or query string,
+simply pass in a fourth argument. The following snippet
+uses a different host name:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">F</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">fun</span></span> (<span style="color: #009900">Socket</span>, <span style="color: #009900">Transport</span>) <span style="color: #990000">-></span>
- <span style="color: #009900">Transport</span><span style="color: #990000">:</span><span style="font-weight: bold"><span style="color: #000000">sendfile</span></span>(<span style="color: #009900">Socket</span>, <span style="color: #FF0000">"priv/styles.css"</span>)
-<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>,
-<span style="color: #009900">Req2</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:set_resp_body_fun</span></span>(<span style="color: #009900">FileSize</span>, <span style="color: #009900">F</span>, <span style="color: #009900">Req</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>Please see the Ranch guide for more information about
-sending files.</p></div>
+<pre><tt><span style="font-weight: bold"><span style="color: #000000">cowboy_req:push</span></span>(<span style="color: #FF0000">"/static/style.css"</span>, #{
+ <span style="color: #990000"><<</span><span style="color: #FF0000">"accept"</span><span style="color: #990000">>></span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"text/css"</span><span style="color: #990000">>></span>
+}, #{<span style="color: #0000FF">host</span> <span style="color: #990000">=></span> <span style="color: #990000"><<</span><span style="color: #FF0000">"cdn.example.org"</span><span style="color: #990000">>></span>}, <span style="color: #009900">Req</span>),</tt></pre></div></div>
+<div class="paragraph"><p>Pushed resources don’t have to be files. As long as the push
+request is cacheable, safe and does not include a body, the
+resource can be pushed.</p></div>
+<div class="paragraph"><p>Under the hood, Cowboy handles pushed requests the same as
+normal requests: a different process is created which will
+ultimately send a response to the client.</p></div>
</div>
</div>
diff --git a/docs/en/cowboy/2.0/guide/ws_handlers.asciidoc b/docs/en/cowboy/2.0/guide/ws_handlers.asciidoc index b280fd86..1411ab6c 100644 --- a/docs/en/cowboy/2.0/guide/ws_handlers.asciidoc +++ b/docs/en/cowboy/2.0/guide/ws_handlers.asciidoc @@ -69,14 +69,14 @@ init(Req, State) -> %% Register process here... {cowboy_websocket, Req, State}. -websocket_info(post_init, Req, State) -> +websocket_info(post_init, State) -> %% Perform post_init initialization here... - {ok, Req, State}. + {ok, State}. ---- === Handling frames from the client -Cowboy will call `websocket_handle/3` whenever a text, binary, +Cowboy will call `websocket_handle/2` whenever a text, binary, ping or pong frame arrives from the client. Note that in the case of ping and pong frames, no action is expected as Cowboy automatically replies to ping frames. @@ -89,15 +89,15 @@ ignores all others. [source,erlang] ---- -websocket_handle(Frame = {text, _}, Req, State) -> - {reply, Frame, Req, State}; -websocket_handle(_Frame, Req, State) -> - {ok, Req, State}. +websocket_handle(Frame = {text, _}, State) -> + {reply, Frame, State}; +websocket_handle(_Frame, State) -> + {ok, State}. ---- === Handling Erlang messages -Cowboy will call `websocket_info/3` whenever an Erlang message +Cowboy will call `websocket_info/2` whenever an Erlang message arrives. The handler can decide to send frames to the socket, stop @@ -108,10 +108,10 @@ and ignores all others. [source,erlang] ---- -websocket_info({log, Text}, Req, State) -> - {reply, {text, Text}, Req, State}; -websocket_info(_Info, Req, State) -> - {ok, Req, State}. +websocket_info({log, Text}, State) -> + {reply, {text, Text}, State}; +websocket_info(_Info, State) -> + {ok, State}. ---- === Sending frames to the socket @@ -126,13 +126,13 @@ tuple. [source,erlang] ---- -websocket_info(hello_world, Req, State) -> +websocket_info(hello_world, State) -> {reply, [ {text, "Hello"}, {text, <<"world!">>}, {binary, <<0:8000>>} - ], Req, State}; -%% More websocket_info/3 clauses here... + ], State}; +%% More websocket_info/2 clauses here... ---- Note that the payload for text and binary frames is of type diff --git a/docs/en/cowboy/2.0/guide/ws_handlers/index.html b/docs/en/cowboy/2.0/guide/ws_handlers/index.html index 2b0e30a2..29feb4a1 100644 --- a/docs/en/cowboy/2.0/guide/ws_handlers/index.html +++ b/docs/en/cowboy/2.0/guide/ws_handlers/index.html @@ -134,15 +134,15 @@ http://www.gnu.org/software/src-highlite --> <span style="font-style: italic"><span style="color: #9A1900">%% Register process here...</span></span>
{<span style="color: #FF6600">cowboy_websocket</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}<span style="color: #990000">.</span>
-<span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>(<span style="color: #FF6600">post_init</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
+<span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>(<span style="color: #FF6600">post_init</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
<span style="font-style: italic"><span style="color: #9A1900">%% Perform post_init initialization here...</span></span>
- {<span style="color: #FF6600">ok</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}<span style="color: #990000">.</span></tt></pre></div></div>
+ {<span style="color: #FF6600">ok</span>, <span style="color: #009900">State</span>}<span style="color: #990000">.</span></tt></pre></div></div>
</div>
</div>
<div class="sect1">
<h2 id="_handling_frames_from_the_client">Handling frames from the client</h2>
<div class="sectionbody">
-<div class="paragraph"><p>Cowboy will call <code>websocket_handle/3</code> whenever a text, binary,
+<div class="paragraph"><p>Cowboy will call <code>websocket_handle/2</code> whenever a text, binary,
ping or pong frame arrives from the client. Note that in the
case of ping and pong frames, no action is expected as Cowboy
automatically replies to ping frames.</p></div>
@@ -155,16 +155,16 @@ ignores all others.</p></div> by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #000000">websocket_handle</span></span>(<span style="color: #009900">Frame</span> <span style="color: #990000">=</span> {<span style="color: #FF6600">text</span>, <span style="color: #990000">_</span>}, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
- {<span style="color: #FF6600">reply</span>, <span style="color: #009900">Frame</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>};
-<span style="font-weight: bold"><span style="color: #000000">websocket_handle</span></span>(<span style="color: #009900">_Frame</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
- {<span style="color: #FF6600">ok</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}<span style="color: #990000">.</span></tt></pre></div></div>
+<pre><tt><span style="font-weight: bold"><span style="color: #000000">websocket_handle</span></span>(<span style="color: #009900">Frame</span> <span style="color: #990000">=</span> {<span style="color: #FF6600">text</span>, <span style="color: #990000">_</span>}, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
+ {<span style="color: #FF6600">reply</span>, <span style="color: #009900">Frame</span>, <span style="color: #009900">State</span>};
+<span style="font-weight: bold"><span style="color: #000000">websocket_handle</span></span>(<span style="color: #009900">_Frame</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
+ {<span style="color: #FF6600">ok</span>, <span style="color: #009900">State</span>}<span style="color: #990000">.</span></tt></pre></div></div>
</div>
</div>
<div class="sect1">
<h2 id="_handling_erlang_messages">Handling Erlang messages</h2>
<div class="sectionbody">
-<div class="paragraph"><p>Cowboy will call <code>websocket_info/3</code> whenever an Erlang message
+<div class="paragraph"><p>Cowboy will call <code>websocket_info/2</code> whenever an Erlang message
arrives.</p></div>
<div class="paragraph"><p>The handler can decide to send frames to the socket, stop
or just continue without sending anything.</p></div>
@@ -175,10 +175,10 @@ and ignores all others.</p></div> by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>({<span style="font-weight: bold"><span style="color: #000080">log</span></span>, <span style="color: #009900">Text</span>}, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
- {<span style="color: #FF6600">reply</span>, {<span style="color: #FF6600">text</span>, <span style="color: #009900">Text</span>}, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>};
-<span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>(<span style="color: #009900">_Info</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
- {<span style="color: #FF6600">ok</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}<span style="color: #990000">.</span></tt></pre></div></div>
+<pre><tt><span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>({<span style="font-weight: bold"><span style="color: #000080">log</span></span>, <span style="color: #009900">Text</span>}, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
+ {<span style="color: #FF6600">reply</span>, {<span style="color: #FF6600">text</span>, <span style="color: #009900">Text</span>}, <span style="color: #009900">State</span>};
+<span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>(<span style="color: #009900">_Info</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
+ {<span style="color: #FF6600">ok</span>, <span style="color: #009900">State</span>}<span style="color: #990000">.</span></tt></pre></div></div>
</div>
</div>
<div class="sect1">
@@ -195,13 +195,13 @@ tuple.</p></div> by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>(<span style="color: #FF6600">hello_world</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
+<pre><tt><span style="font-weight: bold"><span style="color: #000000">websocket_info</span></span>(<span style="color: #FF6600">hello_world</span>, <span style="color: #009900">State</span>) <span style="color: #990000">-></span>
{<span style="color: #FF6600">reply</span>, [
{<span style="color: #FF6600">text</span>, <span style="color: #FF0000">"Hello"</span>},
{<span style="color: #FF6600">text</span>, <span style="color: #990000"><<</span><span style="color: #FF0000">"world!"</span><span style="color: #990000">>></span>},
{<span style="font-weight: bold"><span style="color: #000080">binary</span></span>, <span style="color: #990000"><<</span><span style="color: #993399">0</span><span style="color: #990000">:</span><span style="color: #993399">8000</span><span style="color: #990000">>></span>}
- ], <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>};
-<span style="font-style: italic"><span style="color: #9A1900">%% More websocket_info/3 clauses here...</span></span></tt></pre></div></div>
+ ], <span style="color: #009900">State</span>};
+<span style="font-style: italic"><span style="color: #9A1900">%% More websocket_info/2 clauses here...</span></span></tt></pre></div></div>
<div class="paragraph"><p>Note that the payload for text and binary frames is of type
<code>iodata()</code>, meaning it can be either a <code>binary()</code> or an
<code>iolist()</code>.</p></div>
diff --git a/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html b/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html index 8359987a..abba7a1c 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html @@ -83,7 +83,7 @@ be implemented by handlers. The <code>init/2</code> and <code>terminate/3</code>
callbacks are common to all handler types and are documented
in the manual for the <a href="cowboy_handler.asciidoc">cowboy_handler</a> module.</p></div>
-<div class="paragraph"><p>The <code>websocket_handle/3</code> and <code>websocket_info/3</code> callbacks are
+<div class="paragraph"><p>The <code>websocket_handle/2</code> and <code>websocket_info/2</code> callbacks are
specific to Websocket handlers and will be called as many times
as necessary until the Websocket connection is closed.</p></div>
<div class="paragraph"><p>The <code>init/2</code> callback can be used to negotiate Websocket protocol
@@ -224,20 +224,19 @@ timeout <h2 id="_callbacks">Callbacks</h2>
<div class="sectionbody">
<div class="sect2">
-<h3 id="_websocket_handle_inframe_req_state_8594_ret">websocket_handle(InFrame, Req, State) → Ret</h3>
+<h3 id="_websocket_handle_inframe_state_8594_ret">websocket_handle(InFrame, State) → Ret</h3>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Ret</span> <span style="color: #990000">=</span> {<span style="color: #FF6600">ok</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}
- | {<span style="color: #FF6600">ok</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
- | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}
- | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
- | {<span style="color: #FF6600">stop</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}
+<pre><tt><span style="color: #009900">Ret</span> <span style="color: #990000">=</span> {<span style="color: #FF6600">ok</span>, <span style="color: #009900">State</span>}
+ | {<span style="color: #FF6600">ok</span>, <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
+ | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">State</span>}
+ | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
+ | {<span style="color: #FF6600">stop</span>, <span style="color: #009900">State</span>}
<span style="color: #009900">InFrame</span> <span style="color: #990000">=</span> {<span style="color: #FF6600">text</span> | <span style="font-weight: bold"><span style="color: #000080">binary</span></span> | <span style="color: #FF6600">ping</span> | <span style="color: #FF6600">pong</span>, <span style="font-weight: bold"><span style="color: #000080">binary</span></span>()}
-<span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:req</span></span>()
<span style="color: #009900">State</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">any</span></span>()
<span style="color: #009900">OutFrame</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cow_ws:frame</span></span>()</tt></pre></div></div>
<div class="paragraph"><p>Handle the data received from the Websocket connection.</p></div>
@@ -251,20 +250,19 @@ it receives new data from the Websocket connection or an Erlang message.</p></div>
</div>
<div class="sect2">
-<h3 id="_websocket_info_info_req_state_8594_ret">websocket_info(Info, Req, State) → Ret</h3>
+<h3 id="_websocket_info_info_state_8594_ret">websocket_info(Info, State) → Ret</h3>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Ret</span> <span style="color: #990000">=</span> {<span style="color: #FF6600">ok</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}
- | {<span style="color: #FF6600">ok</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
- | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}
- | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
- | {<span style="color: #FF6600">stop</span>, <span style="color: #009900">Req</span>, <span style="color: #009900">State</span>}
+<pre><tt><span style="color: #009900">Ret</span> <span style="color: #990000">=</span> {<span style="color: #FF6600">ok</span>, <span style="color: #009900">State</span>}
+ | {<span style="color: #FF6600">ok</span>, <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
+ | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">State</span>}
+ | {<span style="color: #FF6600">reply</span>, <span style="color: #009900">OutFrame</span> | [<span style="color: #009900">OutFrame</span>], <span style="color: #009900">State</span>, <span style="color: #FF6600">hibernate</span>}
+ | {<span style="color: #FF6600">stop</span>, <span style="color: #009900">State</span>}
<span style="color: #009900">Info</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">any</span></span>()
-<span style="color: #009900">Req</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cowboy_req:req</span></span>()
<span style="color: #009900">State</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">any</span></span>()
<span style="color: #009900">OutFrame</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">cow_ws:frame</span></span>()</tt></pre></div></div>
<div class="paragraph"><p>Handle the Erlang message received.</p></div>
|