aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http_protocol.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/cowboy_http_protocol.erl')
-rw-r--r--src/cowboy_http_protocol.erl16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl
index 33c6333..b91101a 100644
--- a/src/cowboy_http_protocol.erl
+++ b/src/cowboy_http_protocol.erl
@@ -46,6 +46,7 @@
handler :: {module(), any()},
req_empty_lines = 0 :: integer(),
max_empty_lines :: integer(),
+ max_line_length :: integer(),
timeout :: timeout(),
buffer = <<>> :: binary(),
hibernate = false :: boolean(),
@@ -68,17 +69,22 @@ start_link(ListenerPid, Socket, Transport, Opts) ->
init(ListenerPid, Socket, Transport, Opts) ->
Dispatch = proplists:get_value(dispatch, Opts, []),
MaxEmptyLines = proplists:get_value(max_empty_lines, Opts, 5),
+ MaxLineLength = proplists:get_value(max_line_length, Opts, 4096),
Timeout = proplists:get_value(timeout, Opts, 5000),
receive shoot -> ok end,
wait_request(#state{listener=ListenerPid, socket=Socket, transport=Transport,
- dispatch=Dispatch, max_empty_lines=MaxEmptyLines, timeout=Timeout}).
+ dispatch=Dispatch, max_empty_lines=MaxEmptyLines,
+ max_line_length=MaxLineLength, timeout=Timeout}).
%% @private
-spec parse_request(#state{}) -> ok | none().
-%% @todo Use decode_packet options to limit length?
-parse_request(State=#state{buffer=Buffer}) ->
+%% We limit the length of the Request-line to MaxLength to avoid endlessly
+%% reading from the socket and eventually crashing.
+parse_request(State=#state{buffer=Buffer, max_line_length=MaxLength}) ->
case erlang:decode_packet(http_bin, Buffer, []) of
{ok, Request, Rest} -> request(Request, State#state{buffer=Rest});
+ {more, _Length} when byte_size(Buffer) > MaxLength ->
+ error_terminate(413, State);
{more, _Length} -> wait_request(State);
{error, _Reason} -> error_terminate(400, State)
end.
@@ -123,9 +129,11 @@ request({http_error, _Any}, State) ->
error_terminate(400, State).
-spec parse_header(#http_req{}, #state{}) -> ok | none().
-parse_header(Req, State=#state{buffer=Buffer}) ->
+parse_header(Req, State=#state{buffer=Buffer, max_line_length=MaxLength}) ->
case erlang:decode_packet(httph_bin, Buffer, []) of
{ok, Header, Rest} -> header(Header, Req, State#state{buffer=Rest});
+ {more, _Length} when byte_size(Buffer) > MaxLength ->
+ error_terminate(413, State);
{more, _Length} -> wait_header(Req, State);
{error, _Reason} -> error_terminate(400, State)
end.