diff --git a/doc/src/manual/cowboy_http.asciidoc b/doc/src/manual/cowboy_http.asciidoc index 96a55853..22f116af 100644 --- a/doc/src/manual/cowboy_http.asciidoc +++ b/doc/src/manual/cowboy_http.asciidoc @@ -17,32 +17,34 @@ as a Ranch protocol. [source,erlang] ---- opts() :: #{ - active_n => pos_integer(), - alpn_default_protocol => http | http2, - chunked => boolean(), - connection_type => worker | supervisor, - dynamic_buffer => false | {pos_integer(), pos_integer()}, - hibernate => boolean(), - http10_keepalive => boolean(), - idle_timeout => timeout(), - inactivity_timeout => timeout(), - initial_stream_flow_size => non_neg_integer(), - linger_timeout => timeout(), - logger => module(), - 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(), - max_skip_body_length => non_neg_integer(), - protocols => [http | http2], - proxy_header => boolean(), - request_timeout => timeout(), - reset_idle_timeout_on_send => boolean(), - sendfile => boolean(), - stream_handlers => [module()] + active_n => pos_integer(), + alpn_default_protocol => http | http2, + chunked => boolean(), + connection_type => worker | supervisor, + dynamic_buffer => false | {pos_integer(), pos_integer()}, + hibernate => boolean(), + http10_keepalive => boolean(), + idle_timeout => timeout(), + inactivity_timeout => timeout(), + initial_stream_flow_size => non_neg_integer(), + linger_timeout => timeout(), + logger => module(), + max_empty_lines => non_neg_integer(), + max_header_name_length => non_neg_integer(), + max_header_value_length => non_neg_integer(), + max_authorization_header_value_length => non_neg_integer(), + max_cookie_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(), + max_skip_body_length => non_neg_integer(), + protocols => [http | http2], + proxy_header => boolean(), + request_timeout => timeout(), + reset_idle_timeout_on_send => boolean(), + sendfile => boolean(), + stream_handlers => [module()] } ---- @@ -143,6 +145,14 @@ max_header_value_length (4096):: Maximum length of header values. +max_authorization_header_value_length (value of max_header_value_length):: + +Maximum length of the `authorization` header value. + +max_cookie_header_value_length (value of max_header_value_length):: + +Maximum length of the `cookie` header value. + max_headers (100):: Maximum number of headers allowed per request. diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index a2cf6c91..fda6e9b6 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -703,7 +703,7 @@ parse_hd_before_value(<< $\s, Rest/bits >>, S, H, N) -> parse_hd_before_value(<< $\t, Rest/bits >>, S, H, N) -> parse_hd_before_value(Rest, S, H, N); parse_hd_before_value(Buffer, State=#state{opts=Opts, in_state=PS}, H, N) -> - MaxLength = maps:get(max_header_value_length, Opts, 4096), + MaxLength = max_header_value_length(N, Opts), case match_eol(Buffer, 0) of nomatch when byte_size(Buffer) > MaxLength -> error_terminate(431, State#state{in_state=PS#ps_header{headers=H}}, @@ -715,6 +715,15 @@ parse_hd_before_value(Buffer, State=#state{opts=Opts, in_state=PS}, H, N) -> parse_hd_value(Buffer, State, H, N, <<>>) end. +max_header_value_length(<<"authorization">>, #{max_authorization_header_value_length:=Max}) -> + Max; +max_header_value_length(<<"cookie">>, #{max_cookie_header_value_length:=Max}) -> + Max; +max_header_value_length(_, #{max_header_value_length:=Max}) -> + Max; +max_header_value_length(_, _) -> + 4096. + parse_hd_value(<< $\r, $\n, Rest/bits >>, S, Headers0, Name, SoFar) -> Value = clean_value_ws_end(SoFar, byte_size(SoFar) - 1), Headers = case maps:get(Name, Headers0, undefined) of