aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2017-02-05 15:10:00 +0100
committerLoïc Hoguin <[email protected]>2017-02-05 15:10:00 +0100
commit98c614ee0b04c41174e33427ae0dab1cc4f6ab20 (patch)
tree33b10e59d3ac70ee9e47b88c7ba63429214644e9
parent4cbdfdd293c687212f9ce64e608de838ec74a592 (diff)
downloadcowboy-98c614ee0b04c41174e33427ae0dab1cc4f6ab20.tar.gz
cowboy-98c614ee0b04c41174e33427ae0dab1cc4f6ab20.tar.bz2
cowboy-98c614ee0b04c41174e33427ae0dab1cc4f6ab20.zip
Add missing human-readable errors for HTTP/1.1
-rw-r--r--src/cowboy_http.erl38
1 files changed, 19 insertions, 19 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl
index 1f32b6a..9716a63 100644
--- a/src/cowboy_http.erl
+++ b/src/cowboy_http.erl
@@ -305,10 +305,10 @@ after_parse({more, State, Buffer}) ->
%% Empty lines must be using \r\n.
parse_request(<< $\n, _/bits >>, State, _) ->
error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'Empty lines between requests must use the CRLF line terminator. (RFC7230 3.5)'});
parse_request(<< $\s, _/bits >>, State, _) ->
error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'The request-line must not begin with a space. (RFC7230 3.1.1, RFC7230 3.5)'});
%% We limit the length of the Request-line to MaxLength to avoid endlessly
%% reading from the socket and eventually crashing.
parse_request(Buffer, State=#state{opts=Opts, in_streamid=InStreamID}, EmptyLines) ->
@@ -317,12 +317,12 @@ parse_request(Buffer, State=#state{opts=Opts, in_streamid=InStreamID}, EmptyLine
case match_eol(Buffer, 0) of
nomatch when byte_size(Buffer) > MaxLength ->
error_terminate(414, State, {connection_error, limit_reached,
- ''}); %% @todo
+ 'The request-line length is larger than configuration allows. (RFC7230 3.1.1)'});
nomatch ->
{more, State#state{in_state=#ps_request_line{empty_lines=EmptyLines}}, Buffer};
1 when EmptyLines =:= MaxEmptyLines ->
error_terminate(400, State, {connection_error, limit_reached,
- ''}); %% @todo
+ 'More empty lines were received than configuration allows. (RFC7230 3.5)'});
1 ->
<< _:16, Rest/bits >> = Buffer,
parse_request(Rest, State, EmptyLines + 1);
@@ -356,7 +356,7 @@ parse_method(_, State, _, 0) ->
parse_method(<< C, Rest/bits >>, State, SoFar, Remaining) ->
case C of
$\r -> error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'The method name must not be followed with a line break. (RFC7230 3.1.1)'});
$\s -> parse_uri(Rest, State, SoFar);
_ when ?IS_TOKEN(C) -> parse_method(Rest, State, << SoFar/binary, C >>, Remaining - 1);
_ -> error_terminate(400, State, {connection_error, protocol_error,
@@ -380,7 +380,7 @@ parse_uri(_, State, _) ->
parse_uri_skip_host(<< C, Rest/bits >>, State, Method) ->
case C of
$\r -> error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'The request-target must not be followed by a line break. (RFC7230 3.1.1)'});
$/ -> parse_uri_path(Rest, State, Method, <<"/">>);
$\s -> parse_version(Rest, State, Method, <<"/">>, <<>>);
$? -> parse_uri_query(Rest, State, Method, <<"/">>, <<>>);
@@ -391,7 +391,7 @@ parse_uri_skip_host(<< C, Rest/bits >>, State, Method) ->
parse_uri_path(<< C, Rest/bits >>, State, Method, SoFar) ->
case C of
$\r -> error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'The request-target must not be followed by a line break. (RFC7230 3.1.1)'});
$\s -> parse_version(Rest, State, Method, SoFar, <<>>);
$? -> parse_uri_query(Rest, State, Method, SoFar, <<>>);
$# -> skip_uri_fragment(Rest, State, Method, SoFar, <<>>);
@@ -401,7 +401,7 @@ parse_uri_path(<< C, Rest/bits >>, State, Method, SoFar) ->
parse_uri_query(<< C, Rest/bits >>, State, M, P, SoFar) ->
case C of
$\r -> error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'The request-target must not be followed by a line break. (RFC7230 3.1.1)'});
$\s -> parse_version(Rest, State, M, P, SoFar);
$# -> skip_uri_fragment(Rest, State, M, P, SoFar);
_ -> parse_uri_query(Rest, State, M, P, << SoFar/binary, C >>)
@@ -410,7 +410,7 @@ parse_uri_query(<< C, Rest/bits >>, State, M, P, SoFar) ->
skip_uri_fragment(<< C, Rest/bits >>, State, M, P, Q) ->
case C of
$\r -> error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'The request-target must not be followed by a line break. (RFC7230 3.1.1)'});
$\s -> parse_version(Rest, State, M, P, Q);
_ -> skip_uri_fragment(Rest, State, M, P, Q)
end.
@@ -425,10 +425,10 @@ parse_version(<< "HTTP/1.", _, C, _/bits >>, State, _, _, _) when C =:= $\s; C =
'Whitespace is not allowed after the HTTP version. (RFC7230 3.1.1)'});
parse_version(<< C, _/bits >>, State, _, _, _) when C =:= $\s; C =:= $\t ->
error_terminate(400, State, {connection_error, protocol_error,
- 'The separator between request target and version must be a single SP.'});
+ 'The separator between request target and version must be a single SP. (RFC7230 3.1.1)'});
parse_version(_, State, _, _, _) ->
error_terminate(505, State, {connection_error, protocol_error,
- ''}). %% @todo
+ 'Unsupported HTTP version. (RFC7230 2.6)'}).
parse_headers(Rest, State, M, P, Q, V) ->
%% @todo Figure out the parse states.
@@ -449,10 +449,10 @@ parse_header(Buffer, State=#state{opts=Opts, in_state=PS}, Headers) ->
case match_colon(Buffer, 0) of
nomatch when byte_size(Buffer) > MaxLength ->
error_terminate(431, State, {connection_error, limit_reached,
- ''}); %% @todo
+ 'A header name is larger than configuration allows. (RFC7230 3.2.5, RFC6585 5)'});
nomatch when NumHeaders >= MaxHeaders ->
- error_terminate(400, State, {connection_error, limit_reached,
- ''}); %% @todo
+ error_terminate(431, State, {connection_error, limit_reached,
+ 'The number of headers is larger than configuration allows. (RFC7230 3.2.5, RFC6585 5)'});
nomatch ->
{more, State#state{in_state=PS#ps_header{headers=Headers}}, Buffer};
_ ->
@@ -470,7 +470,7 @@ parse_hd_name(<< $:, Rest/bits >>, State, H, SoFar) ->
parse_hd_before_value(Rest, State, H, SoFar);
parse_hd_name(<< C, _/bits >>, State, _, <<>>) when ?IS_WS(C) ->
error_terminate(400, State, {connection_error, protocol_error,
- ''}); %% @todo
+ 'Whitespace is not allowed between the header name and the colon. (RFC7230 3.2)'});
parse_hd_name(<< C, Rest/bits >>, State, H, SoFar) when ?IS_WS(C) ->
parse_hd_name_ws(Rest, State, H, SoFar);
parse_hd_name(<< C, Rest/bits >>, State, H, SoFar) ->
@@ -492,7 +492,7 @@ parse_hd_before_value(Buffer, State=#state{opts=Opts, in_state=PS}, H, N) ->
case match_eol(Buffer, 0) of
nomatch when byte_size(Buffer) > MaxLength ->
error_terminate(431, State, {connection_error, limit_reached,
- ''}); %% @todo
+ 'A header value is larger than configuration allows. (RFC7230 3.2.5, RFC6585 5)'});
nomatch ->
{more, State#state{in_state=PS#ps_header{headers=H, name=N}}, Buffer};
_ ->
@@ -551,7 +551,7 @@ request(Buffer, State=#state{transport=Transport, in_streamid=StreamID,
undefined when Version =:= 'HTTP/1.1' ->
%% @todo Might want to not close the connection on this and next one.
error_terminate(400, State, {stream_error, StreamID, protocol_error,
- ''}); %% @todo
+ 'HTTP/1.1 requests must include a host header. (RFC7230 5.4)'});
undefined ->
request(Buffer, State, Headers, <<>>, default_port(Transport:secure()));
RawHost ->
@@ -562,7 +562,7 @@ request(Buffer, State=#state{transport=Transport, in_streamid=StreamID,
request(Buffer, State, Headers, Host, Port)
catch _:_ ->
error_terminate(400, State, {stream_error, StreamID, protocol_error,
- ''}) %% @todo
+ 'The host header is invalid. (RFC7230 5.4)'})
end
end.
@@ -587,7 +587,7 @@ request(Buffer, State0=#state{ref=Ref, transport=Transport, peer=Peer, in_stream
cow_http_hd:parse_content_length(BinLength)
catch _:_ ->
error_terminate(400, State0, {stream_error, StreamID, protocol_error,
- ''}) %% @todo
+ 'The content-length header is invalid. (RFC7230 3.3.2)'})
%% @todo Err should terminate here...
end,
{true, Length, fun cow_http_te:stream_identity/2, {0, Length}};