aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2011-04-09 15:28:41 +0200
committerLoïc Hoguin <[email protected]>2011-04-09 15:28:41 +0200
commit6ec20b736ea0a8e8a2a216457273e4dd00b2f1d2 (patch)
tree2094288d1d69702ddd944aa73b96c9e36778cb25
parentc79df567bec9187f6ad27e4c6f4049dad730f0f2 (diff)
downloadcowboy-6ec20b736ea0a8e8a2a216457273e4dd00b2f1d2.tar.gz
cowboy-6ec20b736ea0a8e8a2a216457273e4dd00b2f1d2.tar.bz2
cowboy-6ec20b736ea0a8e8a2a216457273e4dd00b2f1d2.zip
Limit the number of empty lines to allow before the request-line.
Defaults to 5. Prevents someone from indefinitely sending empty lines.
-rw-r--r--src/cowboy_http_protocol.erl12
-rw-r--r--test/http_SUITE.erl1
2 files changed, 10 insertions, 3 deletions
diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl
index 36150b6..b0fef0d 100644
--- a/src/cowboy_http_protocol.erl
+++ b/src/cowboy_http_protocol.erl
@@ -24,6 +24,8 @@
transport :: module(),
dispatch :: dispatch(),
handler :: {Handler::module(), Opts::term()},
+ req_empty_lines = 0 :: integer(),
+ max_empty_lines :: integer(),
timeout :: timeout(),
connection = keepalive :: keepalive | close
}).
@@ -41,9 +43,10 @@ start_link(Socket, Transport, Opts) ->
-spec init(Socket::socket(), Transport::module(), Opts::term()) -> ok.
init(Socket, Transport, Opts) ->
Dispatch = proplists:get_value(dispatch, Opts, []),
+ MaxEmptyLines = proplists:get_value(max_empty_lines, Opts, 5),
Timeout = proplists:get_value(timeout, Opts, 5000),
wait_request(#state{socket=Socket, transport=Transport,
- dispatch=Dispatch, timeout=Timeout}).
+ dispatch=Dispatch, max_empty_lines=MaxEmptyLines, timeout=Timeout}).
-spec wait_request(State::#state{}) -> ok.
wait_request(State=#state{socket=Socket, transport=Transport, timeout=T}) ->
@@ -78,8 +81,11 @@ request({http_request, Method, '*', Version},
State#state{connection=ConnAtom});
request({http_request, _Method, _URI, _Version}, State) ->
error_terminate(501, State);
-request({http_error, "\r\n"}, State) ->
- wait_request(State);
+request({http_error, "\r\n"},
+ State=#state{req_empty_lines=N, max_empty_lines=N}) ->
+ error_terminate(400, State);
+request({http_error, "\r\n"}, State=#state{req_empty_lines=N}) ->
+ wait_request(State#state{req_empty_lines=N + 1});
request({http_error, _Any}, State) ->
error_terminate(400, State).
diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl
index 1bcdcc6..1d2ebb0 100644
--- a/test/http_SUITE.erl
+++ b/test/http_SUITE.erl
@@ -98,6 +98,7 @@ raw(Config) ->
Tests = [
{"\r\n\r\n\r\n\r\n\r\nGET / HTTP/1.1\r\nHost: localhost\r\n\r\n", 200},
{"Garbage\r\n\r\n", 400},
+ {"\r\n\r\n\r\n\r\n\r\n\r\n", 400},
{"GET / HTTP/1.1\r\nHost: dev-extend.eu\r\n\r\n", 400},
{"", 408},
{"\r\n", 408},