diff options
author | Loïc Hoguin <[email protected]> | 2019-10-05 13:04:21 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2019-10-05 13:04:21 +0200 |
commit | c50d6aa09c9028dca3365516d30f1242cfd43306 (patch) | |
tree | 15a830f48a396df30f48e1746dfd0a572abc7fc8 /test/ws_SUITE.erl | |
parent | 618c001291a8d822809a7add87d31a44eafc1e4b (diff) | |
download | cowboy-c50d6aa09c9028dca3365516d30f1242cfd43306.tar.gz cowboy-c50d6aa09c9028dca3365516d30f1242cfd43306.tar.bz2 cowboy-c50d6aa09c9028dca3365516d30f1242cfd43306.zip |
Don't discard data following a Websocket upgrade request
While the protocol does not allow sending data before
receiving a successful Websocket upgrade response, we
do not want to discard that data if it does come in.
Diffstat (limited to 'test/ws_SUITE.erl')
-rw-r--r-- | test/ws_SUITE.erl | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/test/ws_SUITE.erl b/test/ws_SUITE.erl index 4e35ec7..c99830c 100644 --- a/test/ws_SUITE.erl +++ b/test/ws_SUITE.erl @@ -304,6 +304,18 @@ do_ws_deflate_opts_z(Path, Config) -> {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. +ws_first_frame_with_handshake(Config) -> + doc("Client sends the first frame immediately with the handshake. " + "This is invalid according to the protocol but we still want " + "to accept it if the handshake is successful."), + Mask = 16#37fa213d, + MaskedHello = do_mask(<<"Hello">>, Mask, <<>>), + {ok, Socket, _} = do_handshake("/ws_echo", "", + <<1:1, 0:3, 1:4, 1:1, 5:7, Mask:32, MaskedHello/binary>>, + Config), + {ok, <<1:1, 0:3, 1:4, 0:1, 5:7, "Hello">>} = gen_tcp:recv(Socket, 0, 6000), + ok. + ws_init_return_ok(Config) -> doc("Handler does nothing."), {ok, Socket, _} = do_handshake("/ws_init?ok", Config), @@ -636,9 +648,12 @@ ws_webkit_deflate_single_bytes(Config) -> %% Internal. do_handshake(Path, Config) -> - do_handshake(Path, "", Config). + do_handshake(Path, "", "", Config). do_handshake(Path, ExtraHeaders, Config) -> + do_handshake(Path, ExtraHeaders, "", Config). + +do_handshake(Path, ExtraHeaders, ExtraData, Config) -> {ok, Socket} = gen_tcp:connect("localhost", config(port, Config), [binary, {active, false}]), ok = gen_tcp:send(Socket, [ @@ -650,10 +665,16 @@ do_handshake(Path, ExtraHeaders, Config) -> "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" "Upgrade: websocket\r\n", ExtraHeaders, - "\r\n"]), + "\r\n", + ExtraData]), {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), {ok, {http_response, {1, 1}, 101, _}, Rest} = erlang:decode_packet(http, Handshake, []), - [Headers, <<>>] = do_decode_headers(erlang:decode_packet(httph, Rest, []), []), + [Headers, Data] = do_decode_headers(erlang:decode_packet(httph, Rest, []), []), + %% Queue extra data back, if any. We don't want to receive it yet. + case Data of + <<>> -> ok; + _ -> gen_tcp:unrecv(Socket, Data) + end, {_, "Upgrade"} = lists:keyfind('Connection', 1, Headers), {_, "websocket"} = lists:keyfind('Upgrade', 1, Headers), {_, "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="} = lists:keyfind("sec-websocket-accept", 1, Headers), |