aboutsummaryrefslogtreecommitdiffstats
path: root/guide/req_body.md
diff options
context:
space:
mode:
Diffstat (limited to 'guide/req_body.md')
-rw-r--r--guide/req_body.md145
1 files changed, 71 insertions, 74 deletions
diff --git a/guide/req_body.md b/guide/req_body.md
index d573505..5e07fbe 100644
--- a/guide/req_body.md
+++ b/guide/req_body.md
@@ -11,6 +11,12 @@ Cowboy will not attempt to read the body until you do.
If handler execution ends without reading it, Cowboy
will simply skip it.
+Cowboy provides different ways to read the request body.
+You can read it directly, stream it, but also read and
+parse in a single call for form urlencoded formats or
+multipart. All of these except multipart are covered in
+this chapter. Multipart is covered later on in the guide.
+
Check for request body
----------------------
@@ -46,124 +52,115 @@ chunked bodies by using the stream functions.
Reading the body
----------------
-If a content-length header was sent with the request,
-you can read the whole body directly.
+You can read the whole body directly in one call.
``` erlang
{ok, Body, Req2} = cowboy_req:body(Req).
```
-If no content-length header is available, Cowboy will
-return the `{error, chunked}` tuple. You will need to
-stream the request body instead.
-
-By default, Cowboy will reject all body sizes above 8MB,
-to prevent an attacker from needlessly filling up memory.
-You can override this limit however.
+By default, Cowboy will attempt to read up to a
+size of 8MB. You can override this limit as needed.
``` erlang
-{ok, Body, Req2} = cowboy_req:body(100000000, Req).
+{ok, Body, Req2} = cowboy_req:body(Req, [{length, 100000000}]).
```
You can also disable it.
``` erlang
-{ok, Body, Req2} = cowboy_req:body(infinity, Req).
+{ok, Body, Req2} = cowboy_req:body(Req, [{length, infinity}]).
```
It is recommended that you do not disable it for public
facing websites.
-Reading a body sent from an HTML form
--------------------------------------
+If the body is larger than the limit, then Cowboy will return
+a `more` tuple instead, allowing you to stream it if you
+would like to.
-You can directly obtain a list of key/value pairs if the
-body was sent using the application/x-www-form-urlencoded
-content-type.
+Streaming the body
+------------------
-``` erlang
-{ok, KeyValues, Req2} = cowboy_req:body_qs(Req).
-```
+You can stream the request body by chunks.
-You can then retrieve an individual value from that list.
+Cowboy returns a `more` tuple when there is more body to
+be read, and an `ok` tuple for the last chunk. This allows
+you to loop over all chunks.
``` erlang
-{_, Lang} = lists:keyfind(lang, 1, KeyValues).
+body_to_console(Req) ->
+ case cowboy_req:body(Req) of
+ {ok, Data, Req2} ->
+ io:format("~s", [Data]),
+ Req2;
+ {more, Data, Req2} ->
+ io:format("~s", [Data]),
+ body_to_console(Req2)
+ end.
```
-You should not attempt to match on the list as the order
-of the values is undefined.
+You can of course set the `length` option to configure the
+size of chunks.
-By default Cowboy will reject bodies with a size above
-16KB when using this function. You can override this limit.
+Rate of data transmission
+-------------------------
-``` erlang
-{ok, KeyValues, Req2} = cowboy_req:body_qs(500000, Req).
-```
+You can control the rate of data transmission by setting
+options when calling body functions. This applies not only
+to the functions described in this chapter, but also to
+the multipart functions.
-You can also disable it by passing the atom `infinity`,
-although it is not recommended.
+The `read_length` option defines the maximum amount of data
+to be received from the socket at once, in bytes.
-Streaming the body
-------------------
+The `read_timeout` option defines the time Cowboy waits
+before that amount is received, in milliseconds.
-You can stream the request body by chunks.
+Transfer and content decoding
+-----------------------------
-``` erlang
-{ok, Chunk, Req2} = cowboy_req:stream_body(Req).
-```
+Cowboy will by default decode the chunked transfer-encoding
+if any. It will not decode any content-encoding by default.
-By default, Cowboy will attempt to read chunks of up to
-1MB in size. The chunks returned by this function will
-often be smaller, however. You can also change this limit.
+The first time you call a body function you can set the
+`transfer_decode` and `content_decode` options. If the body
+was already started being read these options are simply
+ignored.
+
+The following example shows how to set both options.
``` erlang
-{ok, Chunk, Req2} = cowboy_req:stream_body(500000, Req).
+{ok, Req2} = cowboy_req:body(Req, [
+ {transfer_decode, fun transfer_decode/2, TransferState},
+ {content_decode, fun content_decode/1}
+]).
```
-When Cowboy finishes reading the body, any subsequent call
-will return `{done, Req2}`. You can thus write a recursive
-function to read the whole body and perform an action on
-all chunks, for example printing them to the console.
+Reading a form urlencoded body
+------------------------------
+
+You can directly obtain a list of key/value pairs if the
+body was sent using the application/x-www-form-urlencoded
+content-type.
``` erlang
-body_to_console(Req) ->
- case cowboy_req:stream_body(Req) of
- {ok, Chunk, Req2} ->
- io:format("~s", [Chunk]),
- body_to_console(Req2);
- {done, Req2} ->
- Req2
- end.
+{ok, KeyValues, Req2} = cowboy_req:body_qs(Req).
```
-Advanced streaming
-------------------
-
-Cowboy will by default decode the chunked transfer-encoding
-if any. It will not decode any content-encoding by default.
-
-Before starting to stream, you can configure the functions
-that will be used for decoding both transfer-encoding and
-content-encoding.
+You can then retrieve an individual value from that list.
``` erlang
-{ok, Req2} = cowboy_req:init_stream(fun transfer_decode/2,
- TransferStartState, fun content_decode/1, Req).
+{_, Lang} = lists:keyfind(lang, 1, KeyValues).
```
-Note that you do not need to call this function generally,
-as Cowboy will happily initialize the stream on its own.
-
-Skipping the body
------------------
+You should not attempt to match on the list as the order
+of the values is undefined.
-If you do not need the body, or if you started streaming
-the body but do not need the rest of it, you can skip it.
+By default Cowboy will reject bodies with a size above
+64KB when using this function. You can override this limit
+by setting the `length` option.
``` erlang
-{ok, Req2} = cowboy_req:skip_body(Req).
+{ok, KeyValues, Req2} = cowboy_req:body_qs(Req,
+ [{length, 2000000}]).
```
-
-You do not have to call this function though, as Cowboy will
-do it automatically when handler execution ends.