diff options
author | Loïc Hoguin <[email protected]> | 2011-10-19 20:35:55 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2011-10-19 20:35:55 +0200 |
commit | fe5f0ca539fe883f397c97a5793f86e2de4a34f3 (patch) | |
tree | e5d1fd2627572d11b16b221a53d9c58eb620b20f /src | |
parent | 97df2a2d797818771aedff281c153d082470f7d2 (diff) | |
download | cowboy-fe5f0ca539fe883f397c97a5793f86e2de4a34f3.tar.gz cowboy-fe5f0ca539fe883f397c97a5793f86e2de4a34f3.tar.bz2 cowboy-fe5f0ca539fe883f397c97a5793f86e2de4a34f3.zip |
Add a max_line_length to the HTTP protocol
Allows to limit the size of request and header lines, thus preventing
Cowboy from infinitely reading from the socket and never finding an
end of line.
Defaults to 4096 bytes.
Diffstat (limited to 'src')
-rw-r--r-- | src/cowboy_http_protocol.erl | 16 |
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. |