aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2016-12-21 15:47:44 +0100
committerLoïc Hoguin <[email protected]>2016-12-21 15:47:44 +0100
commitba14cf783820deb52ea0a810dd457ee179d7e30d (patch)
treef71d6ffe63e46c6d0a46088beb773c5661982562
parentf57dd51e0f233df60c670009d83fb37058b765f2 (diff)
downloadcowboy-ba14cf783820deb52ea0a810dd457ee179d7e30d.tar.gz
cowboy-ba14cf783820deb52ea0a810dd457ee179d7e30d.tar.bz2
cowboy-ba14cf783820deb52ea0a810dd457ee179d7e30d.zip
Add man pages for the reply functions
-rw-r--r--doc/src/manual/cowboy_req.asciidoc4
-rw-r--r--doc/src/manual/cowboy_req.delete_resp_header.asciidoc55
-rw-r--r--doc/src/manual/cowboy_req.has_resp_body.asciidoc48
-rw-r--r--doc/src/manual/cowboy_req.has_resp_header.asciidoc54
-rw-r--r--doc/src/manual/cowboy_req.header.asciidoc2
-rw-r--r--doc/src/manual/cowboy_req.push.asciidoc98
-rw-r--r--doc/src/manual/cowboy_req.reply.asciidoc115
-rw-r--r--doc/src/manual/cowboy_req.set_resp_body.asciidoc90
-rw-r--r--doc/src/manual/cowboy_req.set_resp_cookie.asciidoc115
-rw-r--r--doc/src/manual/cowboy_req.set_resp_header.asciidoc78
-rw-r--r--doc/src/manual/cowboy_req.stream_body.asciidoc77
-rw-r--r--doc/src/manual/cowboy_req.stream_reply.asciidoc107
12 files changed, 840 insertions, 3 deletions
diff --git a/doc/src/manual/cowboy_req.asciidoc b/doc/src/manual/cowboy_req.asciidoc
index c7c0e58..bca270b 100644
--- a/doc/src/manual/cowboy_req.asciidoc
+++ b/doc/src/manual/cowboy_req.asciidoc
@@ -73,8 +73,8 @@ Response:
* link:man:cowboy_req:set_resp_body(3)[cowboy_req:set_resp_body(3)] - Set the response body
* link:man:cowboy_req:has_resp_body(3)[cowboy_req:has_resp_body(3)] - Is there a response body?
* link:man:cowboy_req:reply(3)[cowboy_req:reply(3)] - Send the response
-* link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)] - Send the response and stream its body
-* link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)] - Send a chunk of the response body
+* link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)] - Send the response headers
+* link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)] - Stream the response body
* link:man:cowboy_req:push(3)[cowboy_req:push(3)] - Push a resource to the client
== Types
diff --git a/doc/src/manual/cowboy_req.delete_resp_header.asciidoc b/doc/src/manual/cowboy_req.delete_resp_header.asciidoc
new file mode 100644
index 0000000..7a32d70
--- /dev/null
+++ b/doc/src/manual/cowboy_req.delete_resp_header.asciidoc
@@ -0,0 +1,55 @@
+= cowboy_req:delete_resp_header(3)
+
+== Name
+
+cowboy_req:delete_resp_header - Delete a response header
+
+== Description
+
+[source,erlang]
+----
+delete_resp_header(Name, Req :: cowboy_req:req()) -> Req
+
+Name :: binary() %% lowercase; case insensitive
+----
+
+Delete the given response header.
+
+The header name must be given as a lowercase binary string.
+While header names are case insensitive, Cowboy requires them
+to be given as lowercase to function properly.
+
+== Arguments
+
+Name::
+
+Header name as a lowercase binary string.
+
+Req::
+
+The Req object.
+
+== Return value
+
+A new Req object is returned.
+
+The returned Req object must be used from that point onward,
+otherwise the header will still be sent in the response.
+
+== Changelog
+
+* *1.0*: Function introduced.
+
+== Examples
+
+.Remove the content-type header from the response
+[source,erlang]
+----
+Req = cowboy_req:delete_resp_header(<<"content-type">>, Req0),
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_header(3)[cowboy_req:set_resp_header(3)],
+link:man:cowboy_req:has_resp_header(3)[cowboy_req:has_resp_header(3)]
diff --git a/doc/src/manual/cowboy_req.has_resp_body.asciidoc b/doc/src/manual/cowboy_req.has_resp_body.asciidoc
new file mode 100644
index 0000000..d6b9068
--- /dev/null
+++ b/doc/src/manual/cowboy_req.has_resp_body.asciidoc
@@ -0,0 +1,48 @@
+= cowboy_req:has_resp_body(3)
+
+== Name
+
+cowboy_req:has_resp_body - Is there a response body?
+
+== Description
+
+[source,erlang]
+----
+has_resp_body(Req :: cowboy_req:req()) -> boolean()
+----
+
+Return whether a response body has been set.
+
+== Arguments
+
+Req::
+
+The Req object.
+
+== Return value
+
+A boolean indicating whether a response body has been set.
+
+This function will return `false` when an empty response
+body has been set.
+
+== Changelog
+
+* *1.0*: Function introduced.
+
+== Examples
+
+.Check whether a body has been set
+[source,erlang]
+----
+false = cowboy_req:has_resp_body(Req0),
+Req1 = cowboy_req:set_resp_body(<<"Hello!">>, Req0),
+true = cowboy_req:has_resp_body(Req1),
+Req = cowboy_req:set_resp_body(<<>>, Req1),
+false = cowboy_req:has_resp_body(Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_body(3)[cowboy_req:set_resp_body(3)]
diff --git a/doc/src/manual/cowboy_req.has_resp_header.asciidoc b/doc/src/manual/cowboy_req.has_resp_header.asciidoc
new file mode 100644
index 0000000..d6ada37
--- /dev/null
+++ b/doc/src/manual/cowboy_req.has_resp_header.asciidoc
@@ -0,0 +1,54 @@
+= cowboy_req:has_resp_header(3)
+
+== Name
+
+cowboy_req:has_resp_header - Is the given response header set?
+
+== Description
+
+[source,erlang]
+----
+has_resp_header(Name, Req :: cowboy_req:req()) -> boolean()
+
+Name :: binary() %% lowercase; case insensitive
+----
+
+Return whether the given response header has been set.
+
+The header name must be given as a lowercase binary string.
+While header names are case insensitive, Cowboy requires them
+to be given as lowercase to function properly.
+
+== Arguments
+
+Name::
+
+Header name as a lowercase binary string.
+
+Req::
+
+The Req object.
+
+== Return value
+
+A boolean indicating whether the given response header has been set.
+
+== Changelog
+
+* *1.0*: Function introduced.
+
+== Examples
+
+.Check whether the content-type header has been set
+[source,erlang]
+----
+false = cowboy_req:has_resp_header(<<"content-type">>, Req0),
+Req = cowboy_req:set_resp_header(<<"content-type">>, <<"text/html">>, Req0),
+true = cowboy_req:has_resp_header(<<"content-type">>, Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_header(3)[cowboy_req:set_resp_header(3)],
+link:man:cowboy_req:delete_resp_header(3)[cowboy_req:delete_resp_header(3)]
diff --git a/doc/src/manual/cowboy_req.header.asciidoc b/doc/src/manual/cowboy_req.header.asciidoc
index d0d2052..f53890f 100644
--- a/doc/src/manual/cowboy_req.header.asciidoc
+++ b/doc/src/manual/cowboy_req.header.asciidoc
@@ -11,7 +11,7 @@ cowboy_req:header - HTTP header
header(Name, Req) -> header(Name, Req, undefined)
header(Name, Req, Default) -> binary() | Default
-Name :: binary()
+Name :: binary() %% lowercase; case insensitive
Req :: cowboy_req:req()
Default :: any()
----
diff --git a/doc/src/manual/cowboy_req.push.asciidoc b/doc/src/manual/cowboy_req.push.asciidoc
new file mode 100644
index 0000000..200561f
--- /dev/null
+++ b/doc/src/manual/cowboy_req.push.asciidoc
@@ -0,0 +1,98 @@
+= cowboy_req:push(3)
+
+== Name
+
+cowboy_req:push - Push a resource to the client
+
+== Description
+
+[source,erlang]
+----
+push(Path, Headers, Req :: cowboy_req:req())
+ -> push(Path, Headers, Req, #{})
+
+push(Path, Headers, Req :: cowboy_req:req(), Opts)
+ -> ok
+
+Path :: iodata() %% case sensitive
+Headers :: cowboy:http_headers()
+Opts :: cowboy_req:push_opts()
+----
+
+Push a resource to the client.
+
+Cowboy handles push requests the same way as if they came
+from the client, including the creation of a request handling
+process, routing and middlewares and so on.
+
+This function does nothing when the HTTP/1.1 protocol is
+used. You may call it safely without first checking whether
+the connection uses HTTP/2.
+
+The header names must be given as lowercase binary strings.
+While header names are case insensitive, Cowboy requires them
+to be given as lowercase to function properly.
+
+Note that the headers must be the headers the client is expected
+to send if it were to perform the request. They are therefore
+request headers, and not response headers.
+
+By default, Cowboy will use the GET method, an empty query string,
+and take the scheme, host and port directly from the current
+request's URI. You can override them by passing options.
+
+It is not possible to push resources after sending a response.
+Any attempt will result in an error.
+
+== Arguments
+
+Path::
+
+The status code for the response.
+
+Headers::
+
+The response headers.
+
+Header names must be given as lowercase binary strings.
+
+Req::
+
+The Req object.
+
+Opts::
+
+Customize the HTTP method or the URI scheme, host, port
+or query string.
+
+== Return value
+
+The atom `ok` is always returned. It can be safely ignored.
+
+== Changelog
+
+* *2.0*: Function introduced.
+
+== Examples
+
+.Push a resource
+[source,erlang]
+----
+cowboy_req:push("/static/style.css", #{
+ <<"accept">> => <<"text/css">>
+}, Req),
+----
+
+.Push a resource with a custom host
+[source,erlang]
+----
+cowboy_req:push("/static/style.css", #{
+ <<"accept">> => <<"text/css">>
+}, #{host => <<"cdn.example.org">>}, Req),
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:reply(3)[cowboy_req:reply(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
diff --git a/doc/src/manual/cowboy_req.reply.asciidoc b/doc/src/manual/cowboy_req.reply.asciidoc
new file mode 100644
index 0000000..35403f8
--- /dev/null
+++ b/doc/src/manual/cowboy_req.reply.asciidoc
@@ -0,0 +1,115 @@
+= cowboy_req:reply(3)
+
+== Name
+
+cowboy_req:reply - Send the response
+
+== Description
+
+[source,erlang]
+----
+reply(Status, Req :: cowboy_req:req())
+ -> reply(StatusCode, #{}, Req)
+
+reply(Status, Headers, Req :: cowboy_req:req())
+ -> Req
+
+reply(Status, Headers, Body, Req :: cowboy_req:req())
+ -> Req
+
+Status :: cowboy:http_status()
+Headers :: cowboy:http_headers()
+Body :: cowboy_req:resp_body()
+----
+
+Send the response.
+
+The header names must be given as lowercase binary strings.
+While header names are case insensitive, Cowboy requires them
+to be given as lowercase to function properly.
+
+Cowboy does not allow duplicate header names. Headers set
+by this function may overwrite those set by `set_resp_header/3`.
+
+Use link:man:cowboy_req:set_resp_cookie(3)[cowboy_req:set_resp_cookie(3)]
+instead of this function to set cookies.
+
+The `reply/2,3` functions will send the body set previously,
+if any. The `reply/4` function always sends the given body,
+overriding any previously set.
+
+You do not need to set the content-length header when
+sending a response body. Cowboy takes care of it automatically.
+You should however provide a content-type header.
+
+No further data can be transmitted after this function
+returns. This includes the push mechanism. Attempting to
+send two replies, or to push resources after a reply has
+been sent, will result in an error.
+
+== Arguments
+
+Status::
+
+The status code for the response.
+
+Headers::
+
+The response headers.
+
+Header names must be given as lowercase binary strings.
+
+Body::
+
+The body can be either a binary value, an iolist or a
+`sendfile` tuple telling Cowboy to send the contents of
+a file.
+
+Req::
+
+The Req object.
+
+== Return value
+
+A new Req object is returned.
+
+The returned Req object should be used from that point onward
+as it contains updated information about the state of the request.
+
+== Changelog
+
+* *2.0*: Only the Req is returned, it is no longer wrapped in a tuple.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Reply
+[source,erlang]
+----
+Req = cowboy_req:reply(404, Req0).
+----
+
+.Reply with custom headers
+[source,erlang]
+----
+Req = cowboy_req:reply(401, #{
+ <<"www-authenticate">> => <<"Basic realm=\"erlang.org\"">>
+}, Req0).
+----
+
+.Reply with custom headers and a body
+[source,erlang]
+----
+Req = cowboy_req:reply(200, #{
+ <<"content-type">> => <<"text/plain">>
+}, "Hello world!", Req0).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_cookie(3)[cowboy_req:set_resp_cookie(3)],
+link:man:cowboy_req:set_resp_header(3)[cowboy_req:set_resp_header(3)],
+link:man:cowboy_req:set_resp_body(3)[cowboy_req:set_resp_body(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)],
+link:man:cowboy_req:push(3)[cowboy_req:push(3)]
diff --git a/doc/src/manual/cowboy_req.set_resp_body.asciidoc b/doc/src/manual/cowboy_req.set_resp_body.asciidoc
new file mode 100644
index 0000000..5537dae
--- /dev/null
+++ b/doc/src/manual/cowboy_req.set_resp_body.asciidoc
@@ -0,0 +1,90 @@
+= cowboy_req:set_resp_body(3)
+
+== Name
+
+cowboy_req:set_resp_body - Set the response body
+
+== Description
+
+[source,erlang]
+----
+set_resp_body(Body, Req :: cowboy_req:req())
+ -> Req
+
+Body :: cowboy_req:resp_body()
+----
+
+Set the response body.
+
+The response body will be sent when a reply is initiated.
+Note that the functions `stream_reply/2,3` and `reply/4`
+will override the body set by this function.
+
+This function can also be used to remove a response body
+that was set previously. To do so, simply call this function
+with an empty body.
+
+== Arguments
+
+Body::
+
+The body can be either a binary value, an iolist or a
+`sendfile` tuple telling Cowboy to send the contents of
+a file.
+
+Req::
+
+The Req object.
+
+== Return value
+
+A new Req object is returned.
+
+The returned Req object must be used from that point onward,
+otherwise the body will not be sent in the response.
+
+== Changelog
+
+* *2.0*: The function now accepts a `sendfile` tuple.
+* *2.0*: The `set_resp_body_fun/2,3` functions were removed.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Set the response body
+[source,erlang]
+----
+Req = cowboy_req:set_resp_body(<<"Hello world!">>, Req0).
+----
+
+.Set the response body as an iolist
+[source,erlang]
+----
+Req = cowboy_req:set_resp_body([
+ "<html><head><title>",
+ page_title(),
+ "</title></head><body>",
+ page_body(),
+ "</body></html>"
+], Req0).
+----
+
+.Tell Cowboy to send data from a file
+[source,erlang]
+----
+{ok, #file_info{size=Size}} = file:read_file_info(Filename),
+Req = cowboy_req:set_resp_body({sendfile, 0, Size, Filename}, Req0).
+----
+
+.Clear any previously set response body
+[source,erlang]
+----
+Req = cowboy_req:set_resp_body(<<>>, Req0).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_header(3)[cowboy_req:set_resp_header(3)],
+link:man:cowboy_req:reply(3)[cowboy_req:reply(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
diff --git a/doc/src/manual/cowboy_req.set_resp_cookie.asciidoc b/doc/src/manual/cowboy_req.set_resp_cookie.asciidoc
new file mode 100644
index 0000000..75126b1
--- /dev/null
+++ b/doc/src/manual/cowboy_req.set_resp_cookie.asciidoc
@@ -0,0 +1,115 @@
+= cowboy_req:set_resp_cookie(3)
+
+== Name
+
+cowboy_req:set_resp_cookie - Set a cookie
+
+== Description
+
+[source,erlang]
+----
+set_resp_cookie(Name, Value, Req :: cowboy_req:req())
+ -> set_resp_cookie(Name, Value, [], Req)
+
+set_resp_cookie(Name, Value, Opts, Req :: cowboy_req:req())
+ -> Req
+
+Name :: iodata() %% case sensitive
+Value :: iodata() %% case sensitive
+Opts :: cow_cookie:cookie_opts()
+----
+
+// @todo I am not particularly happy about the fact that the name is iodata().
+
+Set a cookie to be sent with the response.
+
+Note that cookie names are case sensitive.
+
+== Arguments
+
+Name::
+
+Cookie name.
+
+Value::
+
+Cookie value.
+
+Opts::
+
+Optional cookie options.
+
+Req::
+
+The Req object.
+
+== Return value
+
+A new Req object is returned.
+
+The returned Req object must be used from that point onward,
+otherwise the cookie will not be sent in the response.
+
+== Changelog
+
+* *2.0*: `set_resp_cookie/3` introduced as an alias to `set_resp_cookie/4` with no options.
+* *1.0*: Function introduced.
+
+== Examples
+
+.Set a session cookie
+[source,erlang]
+----
+SessionID = base64:encode(crypto:strong_rand_bytes(32)),
+Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, Req0).
+----
+
+.Set a cookie with an expiration time
+[source,erlang]
+----
+Req = cowboy_req:set_resp_cookie(<<"lang">>, <<"fr-FR">>, [
+ {max_age, 3600}
+], Req0).
+----
+
+.Delete a cookie
+[source,erlang]
+----
+Req = cowboy_req:set_resp_cookie(<<"sessionid">>, <<>>, [
+ {max_age, 0}
+], Req0).
+----
+
+.Set a cookie for a specific domain and path
+[source,erlang]
+----
+Req = cowboy_req:set_resp_cookie(<<"inaccount">>, <<"1">>, [
+ {domain, "my.example.org"},
+ {path, "/account"}
+], Req0).
+----
+
+.Restrict a cookie to HTTPS
+[source,erlang]
+----
+SessionID = base64:encode(crypto:strong_rand_bytes(32)),
+Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, [
+ {secure, true}
+], Req0).
+----
+
+.Restrict a cookie to HTTP
+[source,erlang]
+----
+SessionID = base64:encode(crypto:strong_rand_bytes(32)),
+Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, [
+ {http_only, true}
+], Req0).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_header(3)[cowboy_req:set_resp_header(3)],
+link:man:cowboy_req:reply(3)[cowboy_req:reply(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
diff --git a/doc/src/manual/cowboy_req.set_resp_header.asciidoc b/doc/src/manual/cowboy_req.set_resp_header.asciidoc
new file mode 100644
index 0000000..8540187
--- /dev/null
+++ b/doc/src/manual/cowboy_req.set_resp_header.asciidoc
@@ -0,0 +1,78 @@
+= cowboy_req:set_resp_header(3)
+
+== Name
+
+cowboy_req:set_resp_header - Set a response header
+
+== Description
+
+[source,erlang]
+----
+set_resp_header(Name, Value, Req :: cowboy_req:req())
+ -> Req
+
+Name :: binary() %% lowercase; case insensitive
+Value :: iodata() %% case depends on header
+----
+
+Set a header to be sent with the response.
+
+The header name must be given as a lowercase binary string.
+While header names are case insensitive, Cowboy requires them
+to be given as lowercase to function properly.
+
+Cowboy does not allow duplicate header names. Headers set
+by this function may be overwritten by those set from the
+reply functions.
+
+Use link:man:cowboy_req:set_resp_cookie(3)[cowboy_req:set_resp_cookie(3)]
+instead of this function to set cookies.
+
+== Arguments
+
+Name::
+
+Header name as a lowercase binary string.
+
+Value::
+
+Header value.
+
+Req::
+
+The Req object.
+
+== Return value
+
+A new Req object is returned.
+
+The returned Req object must be used from that point onward,
+otherwise the header will not be sent in the response.
+
+== Changelog
+
+* *1.0*: Function introduced.
+
+== Examples
+
+.Set a header in the response
+[source,erlang]
+----
+Req = cowboy_req:set_resp_header(<<"allow">>, "GET", Req0).
+----
+
+.Construct a header using iolists
+[source,erlang]
+----
+Req = cowboy_req:set_resp_header(<<"allow">>,
+ [allowed_methods(), ", OPTIONS"], Req0).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_cookie(3)[cowboy_req:set_resp_cookie(3)],
+link:man:cowboy_req:has_resp_header(3)[cowboy_req:has_resp_header(3)],
+link:man:cowboy_req:delete_resp_header(3)[cowboy_req:delete_resp_header(3)],
+link:man:cowboy_req:reply(3)[cowboy_req:reply(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
diff --git a/doc/src/manual/cowboy_req.stream_body.asciidoc b/doc/src/manual/cowboy_req.stream_body.asciidoc
new file mode 100644
index 0000000..e0dbd59
--- /dev/null
+++ b/doc/src/manual/cowboy_req.stream_body.asciidoc
@@ -0,0 +1,77 @@
+= cowboy_req:stream_body(3)
+
+== Name
+
+cowboy_req:stream_body - Stream the response body
+
+== Description
+
+[source,erlang]
+----
+stream_body(Data, IsFin, Req :: cowboy_req:req()) -> ok
+
+Data :: iodata()
+IsFin :: fin | nofin
+----
+
+Stream the response body.
+
+This function may be called as many times as needed after
+initiating a response using the
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
+function.
+
+The second argument indicates if this call is the final
+call. Use the `nofin` value until you know no more data
+will be sent. The final call should use `fin` (possibly
+with an empty data value).
+
+Note that not using `fin` for the final call is not an
+error; Cowboy will take care of it when the request
+handler terminates if needed. Depending on the resource
+it may however be more efficient to do it as early as
+possible.
+
+You do not need to handle HEAD requests specifically as
+Cowboy will ensure no data is sent when you call this function.
+
+== Arguments
+
+Data::
+
+The data to be sent.
+
+IsFin::
+
+A flag indicating whether this is the final piece of data
+to be sent.
+
+Req::
+
+The Req object.
+
+== Return value
+
+The atom `ok` is always returned. It can be safely ignored.
+
+== Changelog
+
+* *2.0*: Function introduced. Replaces `chunk/2`.
+
+== Examples
+
+.Stream the response body
+[source,erlang]
+----
+Req = cowboy_req:stream_reply(200, #{
+ <<"content-type">> => <<"text/plain">>
+}, Req0),
+cowboy_req:stream_body(<<"Hello\n">>, nofin, Req),
+timer:sleep(1000),
+cowboy_req:stream_body(<<"World!\n">>, fin, Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:stream_reply(3)[cowboy_req:stream_reply(3)]
diff --git a/doc/src/manual/cowboy_req.stream_reply.asciidoc b/doc/src/manual/cowboy_req.stream_reply.asciidoc
new file mode 100644
index 0000000..9d3ef92
--- /dev/null
+++ b/doc/src/manual/cowboy_req.stream_reply.asciidoc
@@ -0,0 +1,107 @@
+= cowboy_req:stream_reply(3)
+
+== Name
+
+cowboy_req:stream_reply - Send the response headers
+
+== Description
+
+[source,erlang]
+----
+stream_reply(Status, Req :: cowboy_req:req())
+ -> stream_reply(StatusCode, #{}, Req)
+
+stream_reply(Status, Headers, Req :: cowboy_req:req())
+ -> Req
+
+Status :: cowboy:http_status()
+Headers :: cowboy:http_headers()
+----
+
+Send the response headers.
+
+The header names must be given as lowercase binary strings.
+While header names are case insensitive, Cowboy requires them
+to be given as lowercase to function properly.
+
+Cowboy does not allow duplicate header names. Headers set
+by this function may overwrite those set by `set_resp_header/3`.
+
+Use link:man:cowboy_req:set_resp_cookie(3)[cowboy_req:set_resp_cookie(3)]
+instead of this function to set cookies.
+
+If a response body was set before calling this function,
+it will not be sent.
+
+Use link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)]
+to stream the response body.
+
+You may want to set the content-length header when using
+this function, if it is known in advance. This will allow
+clients using HTTP/2 and HTTP/1.0 to process the response
+more efficiently.
+
+The streaming method varies depending on the protocol being
+used. HTTP/2 will use the usual DATA frames. HTTP/1.1 will
+use chunked transfer-encoding. HTTP/1.0 will send the body
+unmodified and close the connection at the end if no
+content-length was set.
+
+It is not possible to push resources after this function
+returns. Any attempt will result in an error.
+
+== Arguments
+
+Status::
+
+The status code for the response.
+
+Headers::
+
+The response headers.
+
+Header names must be given as lowercase binary strings.
+
+Req::
+
+The Req object.
+
+== Return value
+
+A new Req object is returned.
+
+The returned Req object must be used from that point onward
+in order to be able to stream the response body.
+
+== Changelog
+
+* *2.0*: Only the Req is returned, it is no longer wrapped in a tuple.
+* *2.0*: Function introduced. Replaces `chunked_reply/1,2`.
+
+== Examples
+
+.Initiate the response
+[source,erlang]
+----
+Req = cowboy_req:stream_reply(200, Req0).
+----
+
+.Stream the response with custom headers
+[source,erlang]
+----
+Req = cowboy_req:stream_reply(200, #{
+ <<"content-type">> => <<"text/plain">>
+}, Req0),
+cowboy_req:stream_body(<<"Hello\n">>, nofin, Req),
+timer:sleep(1000),
+cowboy_req:stream_body(<<"World!\n">>, fin, Req).
+----
+
+== See also
+
+link:man:cowboy_req(3)[cowboy_req(3)],
+link:man:cowboy_req:set_resp_cookie(3)[cowboy_req:set_resp_cookie(3)],
+link:man:cowboy_req:set_resp_header(3)[cowboy_req:set_resp_header(3)],
+link:man:cowboy_req:reply(3)[cowboy_req:reply(3)],
+link:man:cowboy_req:stream_body(3)[cowboy_req:stream_body(3)],
+link:man:cowboy_req:push(3)[cowboy_req:push(3)]