From 1d01d0fc06bae095e488f17a172246907eceea3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 15 Aug 2016 19:21:38 +0200 Subject: Allow websocket_init/1 to reply/close/hibernate --- test/handlers/ws_init_h.erl | 47 +++++++++++++++++++++++++ test/ws_SUITE.erl | 86 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 test/handlers/ws_init_h.erl (limited to 'test') diff --git a/test/handlers/ws_init_h.erl b/test/handlers/ws_init_h.erl new file mode 100644 index 0000000..08971ae --- /dev/null +++ b/test/handlers/ws_init_h.erl @@ -0,0 +1,47 @@ +%% This module returns a different value in websocket_init/1 depending on the query string. + +-module(ws_init_h). +-behavior(cowboy_websocket). + +-export([init/2]). +-export([websocket_init/1]). +-export([websocket_handle/2]). +-export([websocket_info/2]). + +init(Req, _) -> + State = binary_to_atom(cowboy_req:qs(Req), latin1), + {cowboy_websocket, Req, State}. + +%% Sleep to make sure the HTTP response was sent. +websocket_init(State) -> + timer:sleep(100), + do_websocket_init(State). + +do_websocket_init(State=ok) -> + {ok, State}; +do_websocket_init(State=ok_hibernate) -> + {ok, State, hibernate}; +do_websocket_init(State=reply) -> + {reply, {text, "Hello"}, State}; +do_websocket_init(State=reply_hibernate) -> + {reply, {text, "Hello"}, State, hibernate}; +do_websocket_init(State=reply_close) -> + {reply, close, State}; +do_websocket_init(State=reply_close_hibernate) -> + {reply, close, State, hibernate}; +do_websocket_init(State=reply_many) -> + {reply, [{text, "Hello"}, {binary, "World"}], State}; +do_websocket_init(State=reply_many_hibernate) -> + {reply, [{text, "Hello"}, {binary, "World"}], State, hibernate}; +do_websocket_init(State=reply_many_close) -> + {reply, [{text, "Hello"}, close], State}; +do_websocket_init(State=reply_many_close_hibernate) -> + {reply, [{text, "Hello"}, close], State, hibernate}; +do_websocket_init(State=stop) -> + {stop, State}. + +websocket_handle(_, State) -> + {ok, State}. + +websocket_info(_, State) -> + {ok, State}. diff --git a/test/ws_SUITE.erl b/test/ws_SUITE.erl index dafc402..a908a81 100644 --- a/test/ws_SUITE.erl +++ b/test/ws_SUITE.erl @@ -60,6 +60,7 @@ init_dispatch() -> {"localhost", [ {"/ws_echo", ws_echo, []}, {"/ws_echo_timer", ws_echo_timer, []}, + {"/ws_init", ws_init_h, []}, {"/ws_init_shutdown", ws_init_shutdown, []}, {"/ws_send_many", ws_send_many, [ {sequence, [ @@ -184,7 +185,90 @@ do_ws_version(Socket) -> {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. -ws_init_shutdown(Config) -> +ws_init_return_ok(Config) -> + doc("Handler does nothing."), + {ok, Socket, _} = do_handshake("/ws_init?ok", Config), + %% The handler does nothing; nothing should happen here. + {error, timeout} = gen_tcp:recv(Socket, 0, 1000), + ok. + +ws_init_return_ok_hibernate(Config) -> + doc("Handler does nothing; hibernates."), + {ok, Socket, _} = do_handshake("/ws_init?ok_hibernate", Config), + %% The handler does nothing; nothing should happen here. + {error, timeout} = gen_tcp:recv(Socket, 0, 1000), + ok. + +ws_init_return_reply(Config) -> + doc("Handler sends a text frame just after the handshake."), + {ok, Socket, _} = do_handshake("/ws_init?reply", Config), + {ok, << 1:1, 0:3, 1:4, 0:1, 5:7, "Hello" >>} = gen_tcp:recv(Socket, 0, 6000), + ok. + +ws_init_return_reply_hibernate(Config) -> + doc("Handler sends a text frame just after the handshake and then hibernates."), + {ok, Socket, _} = do_handshake("/ws_init?reply_hibernate", Config), + {ok, << 1:1, 0:3, 1:4, 0:1, 5:7, "Hello" >>} = gen_tcp:recv(Socket, 0, 6000), + ok. + +ws_init_return_reply_close(Config) -> + doc("Handler closes immediately after the handshake."), + {ok, Socket, _} = do_handshake("/ws_init?reply_close", Config), + {ok, << 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), + {error, closed} = gen_tcp:recv(Socket, 0, 6000), + ok. + +ws_init_return_reply_close_hibernate(Config) -> + doc("Handler closes immediately after the handshake, then attempts to hibernate."), + {ok, Socket, _} = do_handshake("/ws_init?reply_close_hibernate", Config), + {ok, << 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), + {error, closed} = gen_tcp:recv(Socket, 0, 6000), + ok. + +ws_init_return_reply_many(Config) -> + doc("Handler sends many frames just after the handshake."), + {ok, Socket, _} = do_handshake("/ws_init?reply_many", Config), + %% We catch all frames at once and check them directly. + {ok, << + 1:1, 0:3, 1:4, 0:1, 5:7, "Hello", + 1:1, 0:3, 2:4, 0:1, 5:7, "World" >>} = gen_tcp:recv(Socket, 14, 6000), + ok. + +ws_init_return_reply_many_hibernate(Config) -> + doc("Handler sends many frames just after the handshake and then hibernates."), + {ok, Socket, _} = do_handshake("/ws_init?reply_many_hibernate", Config), + %% We catch all frames at once and check them directly. + {ok, << + 1:1, 0:3, 1:4, 0:1, 5:7, "Hello", + 1:1, 0:3, 2:4, 0:1, 5:7, "World" >>} = gen_tcp:recv(Socket, 14, 6000), + ok. + +ws_init_return_reply_many_close(Config) -> + doc("Handler sends many frames including a close frame just after the handshake."), + {ok, Socket, _} = do_handshake("/ws_init?reply_many_close", Config), + %% We catch all frames at once and check them directly. + {ok, << + 1:1, 0:3, 1:4, 0:1, 5:7, "Hello", + 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 9, 6000), + ok. + +ws_init_return_reply_many_close_hibernate(Config) -> + doc("Handler sends many frames including a close frame just after the handshake and then hibernates."), + {ok, Socket, _} = do_handshake("/ws_init?reply_many_close_hibernate", Config), + %% We catch all frames at once and check them directly. + {ok, << + 1:1, 0:3, 1:4, 0:1, 5:7, "Hello", + 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 9, 6000), + ok. + +ws_init_return_stop(Config) -> + doc("Handler closes immediately after the handshake."), + {ok, Socket, _} = do_handshake("/ws_init?stop", Config), + {ok, << 1:1, 0:3, 8:4, 0:1, 2:7, 1000:16 >>} = gen_tcp:recv(Socket, 0, 6000), + {error, closed} = gen_tcp:recv(Socket, 0, 6000), + ok. + +ws_init_shutdown_before_handshake(Config) -> doc("Handler stops before Websocket handshake."), {ok, Socket} = gen_tcp:connect("localhost", config(port, Config), [binary, {active, false}]), ok = gen_tcp:send(Socket, [ -- cgit v1.2.3