diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/http_SUITE.erl | 51 | ||||
-rw-r--r-- | test/websocket_handler.erl | 29 |
2 files changed, 76 insertions, 4 deletions
diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl index 30ec709..da43536 100644 --- a/test/http_SUITE.erl +++ b/test/http_SUITE.erl @@ -19,7 +19,7 @@ -export([all/0, groups/0, init_per_suite/1, end_per_suite/1, init_per_group/2, end_per_group/2]). %% ct. -export([headers_dupe/1, pipeline/1, raw/1]). %% http. --export([http_200/1, http_404/1]). %% http and https. +-export([http_200/1, http_404/1, websocket/1]). %% http and https. %% ct. @@ -28,7 +28,7 @@ all() -> groups() -> BaseTests = [http_200, http_404], - [{http, [], [headers_dupe, pipeline, raw] ++ BaseTests}, + [{http, [], [headers_dupe, pipeline, raw, websocket] ++ BaseTests}, {https, [], BaseTests}]. init_per_suite(Config) -> @@ -77,6 +77,7 @@ end_per_group(https, _Config) -> init_http_dispatch() -> [ {["localhost"], [ + {["websocket"], websocket_handler, []}, {["headers", "dupe"], http_handler, [{headers, [{"Connection", "close"}]}]}, {[], http_handler, []} @@ -92,8 +93,8 @@ headers_dupe(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), - ok = gen_tcp:send(Socket, - "GET /headers/dupe HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n"), + ok = gen_tcp:send(Socket, "GET /headers/dupe HTTP/1.1\r\n" + "Host: localhost\r\nConnection: keep-alive\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {_Start, _Length} = binary:match(Data, <<"Connection: close">>), nomatch = binary:match(Data, <<"Connection: keep-alive">>), @@ -160,6 +161,48 @@ raw(Config) -> [{Packet, StatusCode} = raw_req(Packet, Config) || {Packet, StatusCode} <- Tests]. +websocket(Config) -> + {port, Port} = lists:keyfind(port, 1, Config), + {ok, Socket} = gen_tcp:connect("localhost", Port, + [binary, {active, false}, {packet, raw}]), + ok = gen_tcp:send(Socket, [ + "GET /websocket HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: Upgrade\r\n" + "Upgrade: WebSocket\r\n" + "Origin: http://localhost\r\n" + "Sec-Websocket-Key1: Y\" 4 1Lj!957b8@0H756!i\r\n" + "Sec-Websocket-Key2: 1711 M;4\\74 80<6\r\n" + "\r\n", <<15,245,8,18,2,204,133,33>>]), + {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), + {ok, {http_response, {1, 1}, 101, "WebSocket Protocol Handshake"}, Rest} + = erlang:decode_packet(http, Handshake, []), + [Headers, Body] = websocket_headers(erlang:decode_packet(httph, Rest, []), []), + {'Connection', "Upgrade"} = lists:keyfind('Connection', 1, Headers), + {'Upgrade', "WebSocket"} = lists:keyfind('Upgrade', 1, Headers), + {"sec-websocket-location", "ws://localhost/websocket"} + = lists:keyfind("sec-websocket-location", 1, Headers), + {"sec-websocket-origin", "http://localhost"} + = lists:keyfind("sec-websocket-origin", 1, Headers), + <<169,244,191,103,146,33,149,59,74,104,67,5,99,118,171,236>> = Body, + ok = gen_tcp:send(Socket, << 0, "client_msg", 255 >>), + {ok, << 0, "client_msg", 255 >>} = gen_tcp:recv(Socket, 0, 6000), + {ok, << 0, "websocket_init", 255 >>} = gen_tcp:recv(Socket, 0, 6000), + {ok, << 0, "websocket_handle", 255 >>} = gen_tcp:recv(Socket, 0, 6000), + {ok, << 0, "websocket_handle", 255 >>} = gen_tcp:recv(Socket, 0, 6000), + {ok, << 0, "websocket_handle", 255 >>} = gen_tcp:recv(Socket, 0, 6000), + ok = gen_tcp:send(Socket, << 255, 0 >>), + {ok, << 255, 0 >>} = gen_tcp:recv(Socket, 0, 6000), + {error, closed} = gen_tcp:recv(Socket, 0, 6000), + ok. + +websocket_headers({ok, http_eoh, Rest}, Acc) -> + [Acc, Rest]; +websocket_headers({ok, {http_header, _I, Key, _R, Value}, Rest}, Acc) -> + F = fun(S) when is_atom(S) -> S; (S) -> string:to_lower(S) end, + websocket_headers(erlang:decode_packet(httph, Rest, []), + [{F(Key), Value}|Acc]). + %% http and https. build_url(Path, Config) -> diff --git a/test/websocket_handler.erl b/test/websocket_handler.erl new file mode 100644 index 0000000..8e6915b --- /dev/null +++ b/test/websocket_handler.erl @@ -0,0 +1,29 @@ +%% Feel free to use, reuse and abuse the code in this file. + +-module(websocket_handler). +-behaviour(cowboy_http_handler). +-behaviour(cowboy_http_websocket_handler). +-export([init/3, handle/2, terminate/2]). +-export([websocket_init/3, websocket_handle/3, websocket_terminate/3]). + +init(_Any, _Req, _Opts) -> + {upgrade, protocol, cowboy_http_websocket}. + +handle(_Req, _State) -> + exit(badarg). + +terminate(_Req, _State) -> + exit(badarg). + +websocket_init(_TransportName, Req, _Opts) -> + erlang:start_timer(1000, self(), <<"websocket_init">>), + {ok, Req, undefined}. + +websocket_handle({timeout, _Ref, Msg}, Req, State) -> + erlang:start_timer(1000, self(), <<"websocket_handle">>), + {reply, Msg, Req, State}; +websocket_handle({websocket, Data}, Req, State) -> + {reply, Data, Req, State}. + +websocket_terminate(_Reason, _Req, _State) -> + ok. |