aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/manual/cowboy_http.asciidoc57
-rw-r--r--doc/src/manual/cowboy_http2.asciidoc25
-rw-r--r--src/cowboy_http.erl48
-rw-r--r--src/cowboy_http2.erl19
-rw-r--r--src/cowboy_stream_h.erl2
5 files changed, 98 insertions, 53 deletions
diff --git a/doc/src/manual/cowboy_http.asciidoc b/doc/src/manual/cowboy_http.asciidoc
index 949fa88..45d5464 100644
--- a/doc/src/manual/cowboy_http.asciidoc
+++ b/doc/src/manual/cowboy_http.asciidoc
@@ -11,25 +11,30 @@ as a Ranch protocol.
== Options
+// @todo Might be worth moving cowboy_clear/tls/stream_h options
+// to their respective manual, when they are added.
+
[source,erlang]
----
opts() :: #{
- env := cowboy_middleware:env(),
- idle_timeout := timeout(),
- max_empty_lines := non_neg_integer(),
- max_header_name_length := non_neg_integer(),
- max_header_value_length := non_neg_integer(),
- max_headers := non_neg_integer(),
- max_keepalive := non_neg_integer(),
- max_method_length := non_neg_integer(),
- max_request_line_length := non_neg_integer(),
- middlewares := [module()],
- request_timeout := timeout()
+ connection_type => worker | supervisor,
+ env => cowboy_middleware:env(),
+ idle_timeout => timeout(),
+ inactivity_timeout => timeout(),
+ max_empty_lines => non_neg_integer(),
+ max_header_name_length => non_neg_integer(),
+ max_header_value_length => non_neg_integer(),
+ max_headers => non_neg_integer(),
+ max_keepalive => non_neg_integer(),
+ max_method_length => non_neg_integer(),
+ max_request_line_length => non_neg_integer(),
+ middlewares => [module()],
+ request_timeout => timeout(),
+ shutdown_timeout => timeout(),
+ stream_handlers => [module()]
}
----
-// @todo Document the shutdown option.
-
Configuration for the HTTP/1.1 protocol.
This configuration is passed to Cowboy when starting listeners
@@ -41,12 +46,18 @@ Ranch functions `ranch:get_protocol_options/1` and
The default value is given next to the option name:
+connection_type (supervisor)::
+ Whether the connection process also acts as a supervisor.
+
env (#{})::
Middleware environment.
idle_timeout (60000)::
Time in ms with no data received before Cowboy closes the connection.
+inactivity_timeout (300000)::
+ Time in ms with nothing received at all before Cowboy closes the connection.
+
max_empty_lines (5)::
Maximum number of empty lines before a request.
@@ -62,24 +73,34 @@ max_headers (100)::
max_keepalive (100)::
Maximum number of requests allowed per connection.
-max_request_line_length (8000)::
- Maximum length of the request line.
-
max_method_length (32)::
Maximum length of the method.
+max_request_line_length (8000)::
+ Maximum length of the request line.
+
middlewares ([cowboy_router, cowboy_handler])::
Middlewares to run for every request.
request_timeout (5000)::
Time in ms with no requests before Cowboy closes the connection.
+shutdown_timeout (5000)::
+ Time in ms Cowboy will wait for child processes to shut down before killing them.
+
+stream_handlers ([cowboy_stream_h])::
+ Ordered list of stream handlers that will handle all stream events.
+
== Changelog
+* *2.0*: The `timeout` option was renamed `request_timeout`.
+* *2.0*: The `idle_timeout`, `inactivity_timeout` and `shutdown_timeout` options were added.
* *2.0*: The `max_method_length` option was added.
-* *2.0*: The `env` option is now a map instead of a proplist.
* *2.0*: The `max_request_line_length` default was increased from 4096 to 8000.
-* *2.0*: The `compress` option was temporarily removed.
+* *2.0*: The `connection_type` option was added.
+* *2.0*: The `env` option is now a map instead of a proplist.
+* *2.0*: The `stream_handlers` option was added.
+* *2.0*: The `compress` option was removed in favor of the `cowboy_compress_h` stream handler.
* *2.0*: Options are now a map instead of a proplist.
* *2.0*: Protocol introduced. Replaces `cowboy_protocol`.
diff --git a/doc/src/manual/cowboy_http2.asciidoc b/doc/src/manual/cowboy_http2.asciidoc
index d82bc76..d966459 100644
--- a/doc/src/manual/cowboy_http2.asciidoc
+++ b/doc/src/manual/cowboy_http2.asciidoc
@@ -11,12 +11,19 @@ as a Ranch protocol.
== Options
+// @todo Might be worth moving cowboy_clear/tls/stream_h options
+// to their respective manual, when they are added.
+
[source,erlang]
----
opts() :: #{
- env := cowboy_middleware:env(),
- middlewares := [module()],
- preface_timeout := timeout()
+ connection_type => worker | supervisor,
+ env => cowboy_middleware:env(),
+ inactivity_timeout => timeout(),
+ middlewares => [module()],
+ preface_timeout => timeout(),
+ shutdown_timeout => timeout(),
+ stream_handlers => [module()]
}
----
@@ -31,15 +38,27 @@ Ranch functions `ranch:get_protocol_options/1` and
The default value is given next to the option name:
+connection_type (supervisor)::
+ Whether the connection process also acts as a supervisor.
+
env (#{})::
Middleware environment.
+inactivity_timeout (300000)::
+ Time in ms with nothing received at all before Cowboy closes the connection.
+
middlewares ([cowboy_router, cowboy_handler])::
Middlewares to run for every request.
preface_timeout (5000)::
Time in ms Cowboy is willing to wait for the connection preface.
+shutdown_timeout (5000)::
+ Time in ms Cowboy will wait for child processes to shut down before killing them.
+
+stream_handlers ([cowboy_stream_h])::
+ Ordered list of stream handlers that will handle all stream events.
+
== Changelog
* *2.0*: Protocol introduced.
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl
index 9c2bf30..52b856f 100644
--- a/src/cowboy_http.erl
+++ b/src/cowboy_http.erl
@@ -20,18 +20,23 @@
-export([system_terminate/4]).
-export([system_code_change/4]).
-%% @todo map
--type opts() :: [{compress, boolean()}
- | {env, cowboy_middleware:env()}
- | {max_empty_lines, non_neg_integer()}
- | {max_header_name_length, non_neg_integer()}
- | {max_header_value_length, non_neg_integer()}
- | {max_headers, non_neg_integer()}
- | {max_keepalive, non_neg_integer()}
- | {max_request_line_length, non_neg_integer()}
- | {middlewares, [module()]}
- | {onresponse, cowboy:onresponse_fun()}
- | {timeout, timeout()}].
+-type opts() :: #{
+ connection_type => worker | supervisor,
+ env => cowboy_middleware:env(),
+ idle_timeout => timeout(),
+ inactivity_timeout => timeout(),
+ max_empty_lines => non_neg_integer(),
+ max_header_name_length => non_neg_integer(),
+ max_header_value_length => non_neg_integer(),
+ max_headers => non_neg_integer(),
+ max_keepalive => non_neg_integer(),
+ max_method_length => non_neg_integer(),
+ max_request_line_length => non_neg_integer(),
+ middlewares => [module()],
+ request_timeout => timeout(),
+ shutdown_timeout => timeout(),
+ stream_handlers => [module()]
+}.
-export_type([opts/0]).
-record(ps_request_line, {
@@ -131,17 +136,7 @@ init(Parent, Ref, Socket, Transport, Opts) ->
end.
%% @todo Send a response depending on in_state and whether one was already sent.
-
-%% @todo
-%% Timeouts:
-%% - waiting for new request (if no stream is currently running)
-%% -> request_timeout: for whole request/headers, set at init/when we set ps_request_line{} state
-%% - waiting for new request, or body (when a stream is currently running)
-%% -> idle_timeout: amount of time we wait without receiving any data
-%% - if we skip the body, skip only for a specific duration
-%% -> skip_body_timeout: also have a skip_body_length
-%% - global
-%% -> inactivity_timeout: max time to wait without anything happening before giving up
+%% @todo If we skip the body, skip for a specific duration.
before_loop(State=#state{socket=Socket, transport=Transport}, Buffer) ->
%% @todo disable this when we get to the body, until the stream asks for it?
@@ -149,9 +144,10 @@ before_loop(State=#state{socket=Socket, transport=Transport}, Buffer) ->
Transport:setopts(Socket, [{active, once}]),
loop(State, Buffer).
-loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
+loop(State=#state{parent=Parent, socket=Socket, transport=Transport, opts=Opts,
timer=TimerRef, children=Children, streams=Streams}, Buffer) ->
{OK, Closed, Error} = Transport:messages(),
+ InactivityTimeout = maps:get(inactivity_timeout, Opts, 300000),
receive
%% Socket messages.
{OK, Socket, Data} ->
@@ -199,9 +195,7 @@ loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
Msg ->
error_logger:error_msg("Received stray message ~p.~n", [Msg]),
loop(State, Buffer)
- %% @todo Configurable timeout. This should be a global inactivity timeout
- %% that triggers when really nothing happens (ie something went really wrong).
- after 300000 ->
+ after InactivityTimeout ->
terminate(State, {internal_error, timeout, 'No message or data received before timeout.'})
end.
diff --git a/src/cowboy_http2.erl b/src/cowboy_http2.erl
index a280c5f..e6e8a8b 100644
--- a/src/cowboy_http2.erl
+++ b/src/cowboy_http2.erl
@@ -22,6 +22,17 @@
-export([system_terminate/4]).
-export([system_code_change/4]).
+-type opts() :: #{
+ connection_type => worker | supervisor,
+ env => cowboy_middleware:env(),
+ inactivity_timeout => timeout(),
+ middlewares => [module()],
+ preface_timeout => timeout(),
+ shutdown_timeout => timeout(),
+ stream_handlers => [module()]
+}.
+-export_type([opts/0]).
+
-record(stream, {
id = undefined :: cowboy_stream:streamid(),
%% Stream handlers and their state.
@@ -41,7 +52,7 @@
ref :: ranch:ref(),
socket = undefined :: inet:socket(),
transport :: module(),
- opts = #{} :: map(),
+ opts = #{} :: opts(),
%% Remote address and port for the connection.
peer = undefined :: {inet:ip_address(), inet:port_number()},
@@ -151,9 +162,10 @@ before_loop(State, Buffer) ->
loop(State, Buffer).
loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
- children=Children, parse_state=PS}, Buffer) ->
+ opts=Opts, children=Children, parse_state=PS}, Buffer) ->
Transport:setopts(Socket, [{active, once}]),
{OK, Closed, Error} = Transport:messages(),
+ InactivityTimeout = maps:get(inactivity_timeout, Opts, 300000),
receive
%% Socket messages.
{OK, Socket, Data} ->
@@ -198,8 +210,7 @@ loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
Msg ->
error_logger:error_msg("Received stray message ~p.", [Msg]),
loop(State, Buffer)
- %% @todo Configurable timeout.
- after 60000 ->
+ after InactivityTimeout ->
terminate(State, {internal_error, timeout, 'No message or data received before timeout.'})
end.
diff --git a/src/cowboy_stream_h.erl b/src/cowboy_stream_h.erl
index ec32ff0..5d64e8d 100644
--- a/src/cowboy_stream_h.erl
+++ b/src/cowboy_stream_h.erl
@@ -46,7 +46,7 @@
init(_StreamID, Req=#{ref := Ref}, Opts) ->
Env = maps:get(env, Opts, #{}),
Middlewares = maps:get(middlewares, Opts, [cowboy_router, cowboy_handler]),
- Shutdown = maps:get(shutdown, Opts, 5000),
+ Shutdown = maps:get(shutdown_timeout, Opts, 5000),
Pid = proc_lib:spawn_link(?MODULE, proc_lib_hack, [Req, Env, Middlewares]),
{[{spawn, Pid, Shutdown}], #state{ref=Ref, pid=Pid}}.