diff options
author | Loïc Hoguin <[email protected]> | 2016-03-13 11:18:27 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2016-03-13 11:26:26 +0100 |
commit | 2620d65fdef81dc88916a2b76764a3cf700a7cc1 (patch) | |
tree | f4b590ff51e0aa9b0cea641481d16d0e0df31604 /src/cowboy_http.erl | |
parent | 4e6a4ee53f8453c900c5439100a249ebb278deda (diff) | |
download | cowboy-2620d65fdef81dc88916a2b76764a3cf700a7cc1.tar.gz cowboy-2620d65fdef81dc88916a2b76764a3cf700a7cc1.tar.bz2 cowboy-2620d65fdef81dc88916a2b76764a3cf700a7cc1.zip |
Fix more HTTP/2 handshake test cases
Diffstat (limited to 'src/cowboy_http.erl')
-rw-r--r-- | src/cowboy_http.erl | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index 1582770..4608839 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -489,9 +489,13 @@ parse_hd_before_value(Buffer, State=#state{opts=Opts, in_state=PS}, H, N) -> parse_hd_value(Buffer, State, H, N, <<>>) end. -parse_hd_value(<< $\r, $\n, Rest/bits >>, S, Headers, Name, SoFar) -> - %% @todo What to do about duplicate header names. - parse_header(Rest, S, Headers#{Name => clean_value_ws_end(SoFar, byte_size(SoFar) - 1)}); +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 + undefined -> Headers0#{Name => Value}; + Value0 -> Headers0#{Name => << Value0/binary, ", ", Value/binary >>} + end, + parse_header(Rest, S, Headers); parse_hd_value(<< C, Rest/bits >>, S, H, N, SoFar) -> parse_hd_value(Rest, S, H, N, << SoFar/binary, C >>). @@ -641,8 +645,8 @@ request(Buffer, State0=#state{ref=Ref, transport=Transport, in_streamid=StreamID set_request_timeout(State0#state{in_streamid=StreamID + 1, in_state=#ps_request_line{}}) end, {request, Req, State, Buffer}; - {true, SettingsPayload} -> - http2_upgrade(State0, Buffer, SettingsPayload, Req) + {true, HTTP2Settings} -> + http2_upgrade(State0, Buffer, HTTP2Settings, Req) end. %% HTTP/2 upgrade. @@ -650,15 +654,12 @@ request(Buffer, State0=#state{ref=Ref, transport=Transport, in_streamid=StreamID is_http2_upgrade(#{<<"connection">> := Conn, <<"upgrade">> := Upgrade, <<"http2-settings">> := HTTP2Settings}, 'HTTP/1.1') -> Conns = cow_http_hd:parse_connection(Conn), - io:format(user, "CONNS ~p~n", [Conns]), case {lists:member(<<"upgrade">>, Conns), lists:member(<<"http2-settings">>, Conns)} of {true, true} -> Protocols = cow_http_hd:parse_upgrade(Upgrade), - io:format(user, "PROTOCOLS ~p~n", [Protocols]), case lists:member(<<"h2c">>, Protocols) of true -> - SettingsPayload = cow_http_hd:parse_http2_settings(HTTP2Settings), - {true, SettingsPayload}; + {true, HTTP2Settings}; false -> false end; @@ -683,20 +684,26 @@ http2_upgrade(State=#state{parent=Parent, ref=Ref, socket=Socket, transport=Tran end. http2_upgrade(State=#state{parent=Parent, ref=Ref, socket=Socket, transport=Transport, - opts=Opts, handler=Handler}, Buffer, SettingsPayload, Req) -> + opts=Opts, handler=Handler}, Buffer, HTTP2Settings, Req) -> %% @todo %% However if the client sent a body, we need to read the body in full %% and if we can't do that, return a 413 response. Some options are in order. %% Always half-closed stream coming from this side. - Transport:send(Socket, cow_http:response(101, 'HTTP/1.1', maps:to_list(#{ - <<"connection">> => <<"Upgrade">>, - <<"upgrade">> => <<"h2c">> - }))), + try cow_http_hd:parse_http2_settings(HTTP2Settings) of + Settings -> + Transport:send(Socket, cow_http:response(101, 'HTTP/1.1', maps:to_list(#{ + <<"connection">> => <<"Upgrade">>, + <<"upgrade">> => <<"h2c">> + }))), - %% @todo Possibly redirect the request if it was https. - _ = cancel_request_timeout(State), - cowboy_http2:init(Parent, Ref, Socket, Transport, Opts, Handler, Buffer, SettingsPayload, Req). + %% @todo Possibly redirect the request if it was https. + _ = cancel_request_timeout(State), + cowboy_http2:init(Parent, Ref, Socket, Transport, Opts, Handler, Buffer, Settings, Req) + catch _:_ -> + error_terminate(400, State, {connection_error, protocol_error, + 'The HTTP2-Settings header contains a base64 SETTINGS payload. (RFC7540 3.2, RFC7540 3.2.1)'}) + end. %% Request body parsing. |