Skip to content

Commit fabab35

Browse files
committed
feat: header-wise max_header_value_lenght
1 parent aadc095 commit fabab35

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

doc/src/manual/cowboy_http.asciidoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ Maximum length of header names.
141141

142142
max_header_value_length (4096)::
143143

144-
Maximum length of header values.
144+
Maximum length of header values. Value can be an integer (same value for all headers)
145+
or a function (enables header-wise limitation).
145146

146147
max_headers (100)::
147148

src/cowboy_http.erl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
max_authority_length => non_neg_integer(),
4545
max_empty_lines => non_neg_integer(),
4646
max_header_name_length => non_neg_integer(),
47-
max_header_value_length => non_neg_integer(),
47+
max_header_value_length => non_neg_integer() | fun((HeaderName::binary()) -> non_neg_integer()),
4848
max_headers => non_neg_integer(),
4949
max_keepalive => non_neg_integer(),
5050
max_method_length => non_neg_integer(),
@@ -703,8 +703,8 @@ parse_hd_before_value(<< $\s, Rest/bits >>, S, H, N) ->
703703
parse_hd_before_value(<< $\t, Rest/bits >>, S, H, N) ->
704704
parse_hd_before_value(Rest, S, H, N);
705705
parse_hd_before_value(Buffer, State=#state{opts=Opts, in_state=PS}, H, N) ->
706-
MaxLength = maps:get(max_header_value_length, Opts, 4096),
707-
case match_eol(Buffer, 0) of
706+
MaxLength = get_max_header_value_len(Opts, N),
707+
case match_eol(Buffer, 0) of
708708
nomatch when byte_size(Buffer) > MaxLength ->
709709
error_terminate(431, State#state{in_state=PS#ps_header{headers=H}},
710710
{connection_error, limit_reached,
@@ -715,6 +715,13 @@ parse_hd_before_value(Buffer, State=#state{opts=Opts, in_state=PS}, H, N) ->
715715
parse_hd_value(Buffer, State, H, N, <<>>)
716716
end.
717717

718+
get_max_header_value_len(#{max_header_value_length:=Max}, _HeaderName) when is_integer(Max) ->
719+
Max;
720+
get_max_header_value_len(#{max_header_value_length:=MaxFun}, HeaderName) ->
721+
MaxFun(HeaderName);
722+
get_max_header_value_len(_Opts, _HeaderName) ->
723+
4096.
724+
718725
parse_hd_value(<< $\r, $\n, Rest/bits >>, S, Headers0, Name, SoFar) ->
719726
Value = clean_value_ws_end(SoFar, byte_size(SoFar) - 1),
720727
Headers = case maps:get(Name, Headers0, undefined) of

0 commit comments

Comments
 (0)