mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 20:30:23 +00:00
Document body reading in auto mode
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.
This commit is contained in:
parent
c1490d7d55
commit
e4a78aaeb1
8 changed files with 137 additions and 21 deletions
|
@ -74,18 +74,34 @@ only up to 1MB for up to 5 seconds:
|
|||
#{length => 1000000, period => 5000}).
|
||||
----
|
||||
|
||||
You may also disable the length limit:
|
||||
|
||||
[source,erlang]
|
||||
{ok, Data, Req} = cowboy_req:read_body(Req0, #{length => infinity}).
|
||||
|
||||
This makes the function wait 15 seconds and return with
|
||||
whatever arrived during that period. This is not
|
||||
recommended for public facing applications.
|
||||
|
||||
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
|
||||
|
|
|
@ -120,8 +120,8 @@ request's URI.
|
|||
[source,erlang]
|
||||
----
|
||||
read_body_opts() :: #{
|
||||
length => non_neg_integer(),
|
||||
period => non_neg_integer(),
|
||||
length => non_neg_integer() | auto,
|
||||
period => non_neg_integer() | infinity,
|
||||
timeout => timeout()
|
||||
}
|
||||
----
|
||||
|
@ -130,6 +130,10 @@ Body reading options.
|
|||
|
||||
The defaults are function-specific.
|
||||
|
||||
Auto mode can be enabled by setting `length` to `auto`
|
||||
and `period` to `infinity`. The period cannot be set
|
||||
to `infinity` when auto mode isn't used.
|
||||
|
||||
=== req()
|
||||
|
||||
[source,erlang]
|
||||
|
|
|
@ -36,6 +36,22 @@ The atom `ok` is always returned. It can be safely ignored.
|
|||
|
||||
== Examples
|
||||
|
||||
.Read the body using auto mode
|
||||
[source,erlang]
|
||||
----
|
||||
read_body_auto_async(Req) ->
|
||||
read_body_auto_async(Req, make_ref(), <<>>).
|
||||
|
||||
read_body_auto_async(Req, Ref, Acc) ->
|
||||
cowboy_req:cast({read_body, self(), Ref, auto, infinity}, Req),
|
||||
receive
|
||||
{request_body, Ref, nofin, Data} ->
|
||||
read_body_auto_async(Req, Ref, <<Acc/binary, Data/binary>>);
|
||||
{request_body, Ref, fin, _BodyLen, Data} ->
|
||||
{ok, <<Acc/binary, Data/binary>>, Req}
|
||||
end.
|
||||
----
|
||||
|
||||
.Increase the HTTP/1.1 idle timeout
|
||||
[source,erlang]
|
||||
----
|
||||
|
|
|
@ -68,6 +68,13 @@ The `timeout` option is a safeguard in case the connection
|
|||
process becomes unresponsive. The function will crash if no
|
||||
message was received in that interval. The timeout should be
|
||||
larger than the period. It defaults to the period + 1 second.
|
||||
+
|
||||
Auto mode can be enabled by setting the `length` to `auto` and
|
||||
the `period` to `infinity`. When auto mode is used, Cowboy will
|
||||
send data to the handler as soon as it receives it, regardless
|
||||
of its size. It will wait indefinitely until data is available.
|
||||
Auto mode's main purpose is asynchronous body reading using
|
||||
link:man:cowboy_req:cast(3)[cowboy_req:cast(3)].
|
||||
|
||||
== Return value
|
||||
|
||||
|
@ -86,6 +93,9 @@ body has been read.
|
|||
|
||||
== Changelog
|
||||
|
||||
* *2.11*: The `length` option now accepts `auto` and the
|
||||
period now accepts `infinity`. This adds support for
|
||||
reading the body in auto mode.
|
||||
* *2.0*: Function introduced. Replaces `body/1,2`.
|
||||
|
||||
== Examples
|
||||
|
|
|
@ -45,8 +45,49 @@ The default stream handler spawns the request process
|
|||
and receives its exit signal when it terminates. It
|
||||
will stop the stream once its receives it.
|
||||
|
||||
// @todo It also implements the read_body mechanism.
|
||||
// Note that cowboy_stream_h sends the 100-continue automatically.
|
||||
Because this stream handler converts events from the
|
||||
request process into commands, other stream handlers
|
||||
may not work properly if they are executed after the
|
||||
default stream handler. Always be mindful of in which
|
||||
order stream handlers will get executed.
|
||||
|
||||
=== Request body
|
||||
|
||||
The default stream handler implements the `read_body`
|
||||
mechanism. In addition to reading the body, the handler
|
||||
will automatically handle the `expect: 100-continue`
|
||||
header and send a 100 Continue response.
|
||||
|
||||
Normally one would use
|
||||
link:man:cowboy_req:read_body(3)[cowboy_req:read_body(3)]
|
||||
to read the request body. The default stream handler
|
||||
will buffer data until the amount gets larger than the
|
||||
requested length before sending it. Alternatively, it
|
||||
will send whatever data it has when the period timeout
|
||||
triggers. Depending on the protocol, the flow control
|
||||
window is updated to allow receiving data for the
|
||||
requested length.
|
||||
|
||||
The default stream handler also comes with an automatic
|
||||
mode for reading the request body. This can be used by
|
||||
sending the event message `{read_body, Pid, Ref, auto, infinity}`
|
||||
using link:man:cowboy_req:cast(3)[cowboy_req:cast(3)].
|
||||
The default stream handler will then send data as soon
|
||||
as some becomes available using one of these two
|
||||
messages depending on whether body reading was completed:
|
||||
|
||||
* `{request_body, Ref, nofin, Data}`
|
||||
* `{request_body, Ref, fin, BodyLen, Data}`
|
||||
|
||||
Depending on the protocol, Cowboy will update the flow
|
||||
control window using the size of the data that was read.
|
||||
|
||||
Auto mode automatically gets disabled after data has
|
||||
been sent to the handler. Therefore in order to continue
|
||||
reading data a `read_body` event message must be sent
|
||||
after each `request_body` message.
|
||||
|
||||
=== Response
|
||||
|
||||
In addition it returns a command for any event message
|
||||
looking like one of the following commands: `inform`,
|
||||
|
@ -54,14 +95,9 @@ looking like one of the following commands: `inform`,
|
|||
`switch_protocol`. This is what allows the request
|
||||
process to send a response.
|
||||
|
||||
// @todo Add set_options, which updates options dynamically.
|
||||
|
||||
Because this stream handler converts events from the
|
||||
request process into commands, other stream handlers
|
||||
may not work properly if they are executed
|
||||
|
||||
== Changelog
|
||||
|
||||
* *2.11*: Introduce body reading using auto mode.
|
||||
* *2.0*: Module introduced.
|
||||
|
||||
== See also
|
||||
|
@ -71,4 +107,5 @@ link:man:cowboy_stream(3)[cowboy_stream(3)],
|
|||
link:man:cowboy_compress_h(3)[cowboy_compress_h(3)],
|
||||
link:man:cowboy_decompress_h(3)[cowboy_decompress_h(3)],
|
||||
link:man:cowboy_metrics_h(3)[cowboy_metrics_h(3)],
|
||||
link:man:cowboy_tracer_h(3)[cowboy_tracer_h(3)]
|
||||
link:man:cowboy_tracer_h(3)[cowboy_tracer_h(3)],
|
||||
link:man:cowboy_req:cast(3)[cowboy_req:cast(3)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue