mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 20:30:23 +00:00

It is now tested both via cowboy_req:read_body and via cowboy_req:cast. Removes a bad example from the guide of body reading with period of infinity, which does not work.
146 lines
3.9 KiB
Text
146 lines
3.9 KiB
Text
[[req_body]]
|
|
== Reading the request body
|
|
|
|
The request body can be read using the Req object.
|
|
|
|
Cowboy will not attempt to read the body until requested.
|
|
You need to call the body reading functions in order to
|
|
retrieve it.
|
|
|
|
Cowboy will not cache the body, it is therefore only
|
|
possible to read it once.
|
|
|
|
You are not required to read it, however. If a body is
|
|
present and was not read, Cowboy will either cancel or
|
|
skip its download, depending on the protocol.
|
|
|
|
Cowboy provides functions for reading the body raw,
|
|
and read and parse form urlencoded or xref:multipart[multipart bodies].
|
|
The latter is covered in its own chapter.
|
|
|
|
=== Request body presence
|
|
|
|
Not all requests come with a body. You can check for
|
|
the presence of a request body with this function:
|
|
|
|
[source,erlang]
|
|
cowboy_req:has_body(Req).
|
|
|
|
It returns `true` if there is a body; `false` otherwise.
|
|
|
|
In practice, this function is rarely used. When the
|
|
method is `POST`, `PUT` or `PATCH`, the request body
|
|
is often required by the application, which should
|
|
just attempt to read it directly.
|
|
|
|
=== Request body length
|
|
|
|
You can obtain the length of the body:
|
|
|
|
[source,erlang]
|
|
Length = cowboy_req:body_length(Req).
|
|
|
|
Note that the length may not be known in advance. In
|
|
that case `undefined` will be returned. This can happen
|
|
with HTTP/1.1's chunked transfer-encoding, or HTTP/2
|
|
when no content-length was provided.
|
|
|
|
Cowboy will update the body length in the Req object
|
|
once the body has been read completely. A length will
|
|
always be returned when attempting to call this function
|
|
after reading the body completely.
|
|
|
|
=== Reading the body
|
|
|
|
You can read the entire body with one function call:
|
|
|
|
[source,erlang]
|
|
{ok, Data, Req} = cowboy_req:read_body(Req0).
|
|
|
|
Cowboy returns an `ok` tuple when the body has been
|
|
read fully.
|
|
|
|
By default, Cowboy will attempt to read up to 8MB
|
|
of data, for up to 15 seconds. The call will return
|
|
once Cowboy has read at least 8MB of data, or at
|
|
the end of the 15 seconds period.
|
|
|
|
These values can be customized. For example, to read
|
|
only up to 1MB for up to 5 seconds:
|
|
|
|
[source,erlang]
|
|
----
|
|
{ok, Data, Req} = cowboy_req:read_body(Req0,
|
|
#{length => 1000000, period => 5000}).
|
|
----
|
|
|
|
These two options can effectively be used to control
|
|
the rate of transmission of the request body.
|
|
|
|
It is also possible to asynchronously read the request
|
|
body using auto mode:
|
|
|
|
[source,erlang]
|
|
----
|
|
Ref = make_ref(),
|
|
cowboy_req:cast({read_body, self(), Ref, auto, infinity}, Req).
|
|
----
|
|
|
|
Cowboy will wait indefinitely for data and then send a
|
|
`request_body` message as soon as it has data available,
|
|
regardless of length.
|
|
|
|
[source,erlang]
|
|
----
|
|
receive
|
|
{request_body, Ref, nofin, Data} ->
|
|
do_something(Data);
|
|
{request_body, Ref, fin, _BodyLen, Data} ->
|
|
do_something(Data)
|
|
end.
|
|
----
|
|
|
|
Asynchronous reading of data pairs well with loop handlers.
|
|
|
|
=== Streaming the body
|
|
|
|
When the body is too large, the first call will return
|
|
a `more` tuple instead of `ok`. You can call the
|
|
function again to read more of the body, reading
|
|
it one chunk at a time.
|
|
|
|
[source,erlang]
|
|
----
|
|
read_body_to_console(Req0) ->
|
|
case cowboy_req:read_body(Req0) of
|
|
{ok, Data, Req} ->
|
|
io:format("~s", [Data]),
|
|
Req;
|
|
{more, Data, Req} ->
|
|
io:format("~s", [Data]),
|
|
read_body_to_console(Req)
|
|
end.
|
|
----
|
|
|
|
The `length` and `period` options can also be used.
|
|
They need to be passed for every call.
|
|
|
|
=== Reading a form urlencoded body
|
|
|
|
Cowboy provides a convenient function for reading and
|
|
parsing bodies sent as application/x-www-form-urlencoded.
|
|
|
|
[source,erlang]
|
|
{ok, KeyValues, Req} = cowboy_req:read_urlencoded_body(Req0).
|
|
|
|
This function returns a list of key/values, exactly like
|
|
the function `cowboy_req:parse_qs/1`.
|
|
|
|
The defaults for this function are different. Cowboy will
|
|
read for up to 64KB and up to 5 seconds. They can be modified:
|
|
|
|
[source,erlang]
|
|
----
|
|
{ok, KeyValues, Req} = cowboy_req:read_urlencoded_body(Req0,
|
|
#{length => 4096, period => 3000}).
|
|
----
|