diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cowboy_handler.erl | 62 | ||||
-rw-r--r-- | src/cowboy_http_handler.erl | 36 | ||||
-rw-r--r-- | src/cowboy_loop.erl (renamed from src/cowboy_long_polling.erl) | 36 | ||||
-rw-r--r-- | src/cowboy_loop_handler.erl | 39 | ||||
-rw-r--r-- | src/cowboy_rest.erl | 16 | ||||
-rw-r--r-- | src/cowboy_static.erl | 6 | ||||
-rw-r--r-- | src/cowboy_websocket.erl | 58 | ||||
-rw-r--r-- | src/cowboy_websocket_handler.erl | 51 |
8 files changed, 101 insertions, 203 deletions
diff --git a/src/cowboy_handler.erl b/src/cowboy_handler.erl index a666714..e3faf66 100644 --- a/src/cowboy_handler.erl +++ b/src/cowboy_handler.erl @@ -21,7 +21,15 @@ -behaviour(cowboy_middleware). -export([execute/2]). --export([terminate/5]). +-export([terminate/4]). + +-callback init(Req, any()) + -> {ok | module(), Req, any()} + | {module(), Req, any(), hibernate} + | {module(), Req, any(), timeout()} + | {module(), Req, any(), timeout(), hibernate} + when Req::cowboy_req:req(). +%% @todo optional -callback terminate(terminate_reason(), cowboy_req:req(), state()) -> ok. -spec execute(Req, Env) -> {ok, Req, Env} when Req::cowboy_req:req(), Env::cowboy_middleware:env(). @@ -29,21 +37,21 @@ execute(Req, Env) -> {_, Handler} = lists:keyfind(handler, 1, Env), {_, HandlerOpts} = lists:keyfind(handler_opts, 1, Env), try Handler:init(Req, HandlerOpts) of - {http, Req2, State} -> - handle(Req2, Env, Handler, State); - {shutdown, Req2, State} -> - terminate(Req2, Env, Handler, State, {normal, shutdown}); + {ok, Req2, State} -> + Result = terminate(normal, Req2, State, Handler), + {ok, Req2, [{result, Result}|Env]}; {Mod, Req2, State} -> - upgrade(Req2, Env, Handler, State, infinity, run, Mod); + Mod:upgrade(Req2, Env, Handler, State, infinity, run); {Mod, Req2, State, hibernate} -> - upgrade(Req2, Env, Handler, State, infinity, hibernate, Mod); + Mod:upgrade(Req2, Env, Handler, State, infinity, hibernate); {Mod, Req2, State, Timeout} -> - upgrade(Req2, Env, Handler, State, Timeout, run, Mod); + Mod:upgrade(Req2, Env, Handler, State, Timeout, run); {Mod, Req2, State, Timeout, hibernate} -> - upgrade(Req2, Env, Handler, State, Timeout, hibernate, Mod) + Mod:upgrade(Req2, Env, Handler, State, Timeout, hibernate) catch Class:Reason -> Stacktrace = erlang:get_stacktrace(), cowboy_req:maybe_reply(Stacktrace, Req), + terminate({crash, Class, Reason}, Req, HandlerOpts, Handler), erlang:Class([ {reason, Reason}, {mfa, {Handler, init, 2}}, @@ -53,36 +61,9 @@ execute(Req, Env) -> ]) end. -handle(Req, Env, Handler, State) -> - try Handler:handle(Req, State) of - {ok, Req2, State2} -> - terminate(Req2, Env, Handler, State2, {normal, shutdown}) - catch Class:Reason -> - Stacktrace = erlang:get_stacktrace(), - cowboy_req:maybe_reply(Stacktrace, Req), - _ = terminate(Req, Env, Handler, State, Reason), - erlang:Class([ - {reason, Reason}, - {mfa, {Handler, handle, 2}}, - {stacktrace, Stacktrace}, - {req, cowboy_req:to_list(Req)}, - {state, State} - ]) - end. - -upgrade(Req, Env, Handler, State, Timeout, Hibernate, Mod) -> - Mod2 = case Mod of - long_polling -> cowboy_long_polling; - rest -> cowboy_rest; - ws -> cowboy_websocket; - _ when Mod =/= http -> Mod - end, - Mod2:upgrade(Req, Env, Handler, State, Timeout, Hibernate). - --spec terminate(Req, Env, module(), any(), {normal, shutdown} | {error, atom()} | any()) - -> {ok, Req, Env} when Req::cowboy_req:req(), Env::cowboy_middleware:env(). -terminate(Req, Env, Handler, State, Reason) -> - Result = case erlang:function_exported(Handler, terminate, 3) of +-spec terminate(any(), Req, any(), module()) -> ok when Req::cowboy_req:req(). +terminate(Reason, Req, State, Handler) -> + case erlang:function_exported(Handler, terminate, 3) of true -> try Handler:terminate(Reason, cowboy_req:lock(Req), State) @@ -98,5 +79,4 @@ terminate(Req, Env, Handler, State, Reason) -> end; false -> ok - end, - {ok, Req, [{result, Result}|Env]}. + end. diff --git a/src/cowboy_http_handler.erl b/src/cowboy_http_handler.erl deleted file mode 100644 index 75b41d2..0000000 --- a/src/cowboy_http_handler.erl +++ /dev/null @@ -1,36 +0,0 @@ -%% Copyright (c) 2011-2014, Loïc Hoguin <[email protected]> -%% -%% Permission to use, copy, modify, and/or distribute this software for any -%% purpose with or without fee is hereby granted, provided that the above -%% copyright notice and this permission notice appear in all copies. -%% -%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - --module(cowboy_http_handler). - --type opts() :: any(). --type state() :: any(). -%% @todo see terminate -%-type terminate_reason() :: {normal, shutdown} -% | {normal, timeout} %% Only occurs in loop handlers. -% | {error, closed} %% Only occurs in loop handlers. -% | {error, overflow} %% Only occurs in loop handlers. -% | {error, atom()}. - --callback init(Req, opts()) - -> {http, Req, state()} - | {long_polling | rest | ws | module(), Req, state()} - | {long_polling | rest | ws | module(), Req, state(), hibernate} - | {long_polling | rest | ws | module(), Req, state(), timeout()} - | {long_polling | rest | ws | module(), Req, state(), timeout(), hibernate} - | {shutdown, Req, state()} - when Req::cowboy_req:req(). --callback handle(Req, State) -> {ok, Req, State} - when Req::cowboy_req:req(), State::state(). -%% @todo optional -callback terminate(terminate_reason(), cowboy_req:req(), state()) -> ok. diff --git a/src/cowboy_long_polling.erl b/src/cowboy_loop.erl index 6616a78..b9eb8cd 100644 --- a/src/cowboy_long_polling.erl +++ b/src/cowboy_loop.erl @@ -21,12 +21,25 @@ %% by default. This can be configured through the <em>loop_max_buffer</em> %% environment value. The request will be terminated with an %% <em>{error, overflow}</em> reason if this threshold is reached. --module(cowboy_long_polling). +-module(cowboy_loop). -behaviour(cowboy_sub_protocol). -export([upgrade/6]). -export([loop/4]). +-callback init(Req, any()) + -> {ok | module(), Req, any()} + | {module(), Req, any(), hibernate} + | {module(), Req, any(), timeout()} + | {module(), Req, any(), timeout(), hibernate} + when Req::cowboy_req:req(). +-callback info(any(), Req, State) + -> {ok, Req, State} + | {ok, Req, State, hibernate} + | {shutdown, Req, State} + when Req::cowboy_req:req(), State::any(). +%% @todo optional -callback terminate(terminate_reason(), cowboy_req:req(), state()) -> ok. + -record(state, { env :: cowboy_middleware:env(), hibernate = false :: boolean(), @@ -91,7 +104,7 @@ timeout(State=#state{timeout=Timeout, -spec loop(Req, #state{}, module(), any()) -> {ok, Req, cowboy_middleware:env()} | {suspend, module(), atom(), [any()]} when Req::cowboy_req:req(). -loop(Req, State=#state{env=Env, buffer_size=NbBytes, +loop(Req, State=#state{buffer_size=NbBytes, max_buffer=Threshold, timeout_ref=TRef, resp_sent=RespSent}, Handler, HandlerState) -> [Socket, Transport] = cowboy_req:get([socket, transport], Req), @@ -103,7 +116,7 @@ loop(Req, State=#state{env=Env, buffer_size=NbBytes, _ = if RespSent -> ok; true -> cowboy_req:reply(500, Req) end, - _ = cowboy_handler:terminate(Req, Env, Handler, HandlerState, {error, overflow}), + cowboy_handler:terminate({error, overflow}, Req, HandlerState, Handler), exit(normal); true -> Req2 = cowboy_req:append_buffer(Data, Req), @@ -115,7 +128,7 @@ loop(Req, State=#state{env=Env, buffer_size=NbBytes, {Error, Socket, Reason} -> terminate(Req, State, Handler, HandlerState, {error, Reason}); {timeout, TRef, ?MODULE} -> - after_loop(Req, State, Handler, HandlerState, {normal, timeout}); + after_loop(Req, State, Handler, HandlerState, timeout); {timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) -> loop(Req, State, Handler, HandlerState); Message -> @@ -133,21 +146,21 @@ loop(Req, State=#state{env=Env, buffer_size=NbBytes, call(Req2, State, Handler, HandlerState, Message) end. -call(Req, State=#state{env=Env, resp_sent=RespSent}, +call(Req, State=#state{resp_sent=RespSent}, Handler, HandlerState, Message) -> try Handler:info(Message, Req, HandlerState) of {ok, Req2, HandlerState2} -> - after_loop(Req2, State, Handler, HandlerState2, {normal, shutdown}); - {loop, Req2, HandlerState2} -> after_call(Req2, State, Handler, HandlerState2); - {loop, Req2, HandlerState2, hibernate} -> - after_call(Req2, State#state{hibernate=true}, Handler, HandlerState2) + {ok, Req2, HandlerState2, hibernate} -> + after_call(Req2, State#state{hibernate=true}, Handler, HandlerState2); + {shutdown, Req2, HandlerState2} -> + after_loop(Req2, State, Handler, HandlerState2, shutdown) catch Class:Reason -> Stacktrace = erlang:get_stacktrace(), if RespSent -> ok; true -> cowboy_req:maybe_reply(Stacktrace, Req) end, - _ = cowboy_handler:terminate(Req, Env, Handler, HandlerState, {error, overflow}), + cowboy_handler:terminate({crash, Class, Reason}, Req, HandlerState, Handler), erlang:Class([ {reason, Reason}, {mfa, {Handler, info, 3}}, @@ -180,7 +193,8 @@ terminate(Req, #state{env=Env, timeout_ref=TRef}, TRef -> erlang:cancel_timer(TRef) end, flush_timeouts(), - cowboy_handler:terminate(Req, Env, Handler, HandlerState, Reason). + Result = cowboy_handler:terminate(Reason, Req, HandlerState, Handler), + {ok, Req, [{result, Result}|Env]}. flush_timeouts() -> receive diff --git a/src/cowboy_loop_handler.erl b/src/cowboy_loop_handler.erl deleted file mode 100644 index 5e50c34..0000000 --- a/src/cowboy_loop_handler.erl +++ /dev/null @@ -1,39 +0,0 @@ -%% Copyright (c) 2011-2014, Loïc Hoguin <[email protected]> -%% -%% Permission to use, copy, modify, and/or distribute this software for any -%% purpose with or without fee is hereby granted, provided that the above -%% copyright notice and this permission notice appear in all copies. -%% -%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - --module(cowboy_loop_handler). - --type opts() :: any(). --type state() :: any(). -%% @todo see terminate -%-type terminate_reason() :: {normal, shutdown} -% | {normal, timeout} -% | {error, closed} -% | {error, overflow} -% | {error, atom()}. - --callback init(Req, opts()) - -> {http, Req, state()} - | {long_polling | rest | ws | module(), Req, state()} - | {long_polling | rest | ws | module(), Req, state(), hibernate} - | {long_polling | rest | ws | module(), Req, state(), timeout()} - | {long_polling | rest | ws | module(), Req, state(), timeout(), hibernate} - | {shutdown, Req, state()} - when Req::cowboy_req:req(). --callback info(any(), Req, State) - -> {ok, Req, State} - | {loop, Req, State} - | {loop, Req, State, hibernate} - when Req::cowboy_req:req(), State::state(). -%% @todo optional -callback terminate(terminate_reason(), cowboy_req:req(), state()) -> ok. diff --git a/src/cowboy_rest.erl b/src/cowboy_rest.erl index 63f33e6..98c6f3b 100644 --- a/src/cowboy_rest.erl +++ b/src/cowboy_rest.erl @@ -19,6 +19,15 @@ -export([upgrade/6]). +-callback init(Req, any()) + -> {ok | module(), Req, any()} + | {module(), Req, any(), hibernate} + | {module(), Req, any(), timeout()} + | {module(), Req, any(), timeout(), hibernate} + when Req::cowboy_req:req(). +%% @todo optional REST callbacks +%% @todo optional -callback terminate(terminate_reason(), cowboy_req:req(), state()) -> ok. + -record(state, { env :: cowboy_middleware:env(), method = undefined :: binary(), @@ -967,11 +976,11 @@ next(Req, State, StatusCode) when is_integer(StatusCode) -> respond(Req, State, StatusCode) -> terminate(cowboy_req:reply(StatusCode, Req), State). -error_terminate(Req, State=#state{handler=Handler, handler_state=HandlerState}, +error_terminate(Req, #state{handler=Handler, handler_state=HandlerState}, Class, Reason, Callback) -> - _ = terminate(Req, State), Stacktrace = erlang:get_stacktrace(), cowboy_req:maybe_reply(Stacktrace, Req), + cowboy_handler:terminate({crash, Class, Reason}, Req, HandlerState, Handler), erlang:Class([ {reason, Reason}, {mfa, {Handler, Callback, 2}}, @@ -981,4 +990,5 @@ error_terminate(Req, State=#state{handler=Handler, handler_state=HandlerState}, ]). terminate(Req, #state{env=Env, handler=Handler, handler_state=HandlerState}) -> - cowboy_handler:terminate(Req, Env, Handler, HandlerState, {normal, shutdown}). + Result = cowboy_handler:terminate(normal, Req, HandlerState, Handler), + {ok, Req, [{result, Result}|Env]}. diff --git a/src/cowboy_static.erl b/src/cowboy_static.erl index ecca6fa..99ad82e 100644 --- a/src/cowboy_static.erl +++ b/src/cowboy_static.erl @@ -42,7 +42,7 @@ %% If the handler is configured to manage a directory, check that the %% requested file is inside the configured directory. --spec init(Req, opts()) -> {rest, Req, error | state()} when Req::cowboy_req:req(). +-spec init(Req, opts()) -> {cowboy_rest, Req, error | state()} when Req::cowboy_req:req(). init(Req, {Name, Path}) -> init_opts(Req, {Name, Path, []}); init(Req, {Name, App, Path}) @@ -87,7 +87,7 @@ init_dir(Req, Path, Extra) -> << Dir:Len/binary, $/, _/binary >> -> init_info(Req, Filepath, Extra); _ -> - {rest, Req, error} + {cowboy_rest, Req, error} end. fullpath(Path) -> @@ -105,7 +105,7 @@ fullpath([Segment|Tail], Acc) -> init_info(Req, Path, Extra) -> Info = file:read_file_info(Path, [{time, universal}]), - {rest, Req, {Path, Info, Extra}}. + {cowboy_rest, Req, {Path, Info, Extra}}. -ifdef(TEST). fullpath_test_() -> diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index e0b20ca..c700af9 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -33,8 +33,32 @@ -type frag_state() :: undefined | {nofin, opcode(), binary()} | {fin, opcode(), binary()}. -type rsv() :: << _:3 >>. --type terminate_reason() :: {normal | error | remote, atom()} - | {remote, close_code(), binary()}. +-type terminate_reason() :: normal | shutdown | timeout + | remote | {remote, close_code(), binary()} + | {error, badencoding | badframe | closed | atom()} + | {crash, error | exit | throw, any()}. + +-callback init(Req, any()) + -> {ok | module(), Req, any()} + | {module(), Req, any(), hibernate} + | {module(), Req, any(), timeout()} + | {module(), Req, any(), timeout(), hibernate} + when Req::cowboy_req:req(). +-callback websocket_handle({text | binary | ping | pong, binary()}, Req, State) + -> {ok, Req, State} + | {ok, Req, State, hibernate} + | {reply, frame() | [frame()], Req, State} + | {reply, frame() | [frame()], Req, State, hibernate} + | {shutdown, Req, State} + when Req::cowboy_req:req(), State::any(). +-callback websocket_info(any(), Req, State) + -> {ok, Req, State} + | {ok, Req, State, hibernate} + | {reply, frame() | [frame()], Req, State} + | {reply, frame() | [frame()], Req, State, hibernate} + | {shutdown, Req, State} + when Req::cowboy_req:req(), State::any(). +%% @todo optional -callback terminate(terminate_reason(), cowboy_req:req(), state()) -> ok. -record(state, { env :: cowboy_middleware:env(), @@ -181,7 +205,7 @@ handler_loop(State=#state{socket=Socket, messages={OK, Closed, Error}, {Error, Socket, Reason} -> handler_terminate(State, Req, HandlerState, {error, Reason}); {timeout, TRef, ?MODULE} -> - websocket_close(State, Req, HandlerState, {normal, timeout}); + websocket_close(State, Req, HandlerState, timeout); {timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) -> handler_loop(State, Req, HandlerState, SoFar); Message -> @@ -487,7 +511,7 @@ websocket_payload_loop(State=#state{socket=Socket, transport=Transport, {Error, Socket, Reason} -> handler_terminate(State, Req, HandlerState, {error, Reason}); {timeout, TRef, ?MODULE} -> - websocket_close(State, Req, HandlerState, {normal, timeout}); + websocket_close(State, Req, HandlerState, timeout); {timeout, OlderTRef, ?MODULE} when is_reference(OlderTRef) -> websocket_payload_loop(State, Req, HandlerState, Opcode, Len, MaskKey, Unmasked, UnmaskedLen, Rsv); @@ -524,7 +548,7 @@ websocket_dispatch(State, Req, HandlerState, RemainingData, 2, Payload) -> websocket_handle, {binary, Payload}, fun websocket_data/4); %% Close control frame. websocket_dispatch(State, Req, HandlerState, _RemainingData, 8, <<>>) -> - websocket_close(State, Req, HandlerState, {remote, closed}); + websocket_close(State, Req, HandlerState, remote); websocket_dispatch(State, Req, HandlerState, _RemainingData, 8, << Code:16, Payload/bits >>) -> websocket_close(State, Req, HandlerState, {remote, Code, Payload}); @@ -558,8 +582,7 @@ handler_call(State=#state{handler=Handler}, Req, HandlerState, {ok, State2} -> NextState(State2, Req2, HandlerState2, RemainingData); {shutdown, State2} -> - handler_terminate(State2, Req2, HandlerState2, - {normal, shutdown}); + handler_terminate(State2, Req2, HandlerState2, shutdown); {{error, _} = Error, State2} -> handler_terminate(State2, Req2, HandlerState2, Error) end; @@ -570,8 +593,7 @@ handler_call(State=#state{handler=Handler}, Req, HandlerState, NextState(State2#state{hibernate=true}, Req2, HandlerState2, RemainingData); {shutdown, State2} -> - handler_terminate(State2, Req2, HandlerState2, - {normal, shutdown}); + handler_terminate(State2, Req2, HandlerState2, shutdown); {{error, _} = Error, State2} -> handler_terminate(State2, Req2, HandlerState2, Error) end; @@ -580,8 +602,7 @@ handler_call(State=#state{handler=Handler}, Req, HandlerState, {ok, State2} -> NextState(State2, Req2, HandlerState2, RemainingData); {shutdown, State2} -> - handler_terminate(State2, Req2, HandlerState2, - {normal, shutdown}); + handler_terminate(State2, Req2, HandlerState2, shutdown); {{error, _} = Error, State2} -> handler_terminate(State2, Req2, HandlerState2, Error) end; @@ -591,15 +612,14 @@ handler_call(State=#state{handler=Handler}, Req, HandlerState, NextState(State2#state{hibernate=true}, Req2, HandlerState2, RemainingData); {shutdown, State2} -> - handler_terminate(State2, Req2, HandlerState2, - {normal, shutdown}); + handler_terminate(State2, Req2, HandlerState2, shutdown); {{error, _} = Error, State2} -> handler_terminate(State2, Req2, HandlerState2, Error) end; {shutdown, Req2, HandlerState2} -> - websocket_close(State, Req2, HandlerState2, {normal, shutdown}) + websocket_close(State, Req2, HandlerState2, shutdown) catch Class:Reason -> - _ = websocket_close(State, Req, HandlerState, {error, handler}), + _ = websocket_close(State, Req, HandlerState, {crash, Class, Reason}), erlang:Class([ {reason, Reason}, {mfa, {Handler, Callback, 3}}, @@ -696,15 +716,15 @@ websocket_send_many([Frame|Tail], State) -> websocket_close(State=#state{socket=Socket, transport=Transport}, Req, HandlerState, Reason) -> case Reason of - {normal, _} -> + Normal when Normal =:= shutdown; Normal =:= timeout -> Transport:send(Socket, << 1:1, 0:3, 8:4, 0:1, 2:7, 1000:16 >>); {error, badframe} -> Transport:send(Socket, << 1:1, 0:3, 8:4, 0:1, 2:7, 1002:16 >>); {error, badencoding} -> Transport:send(Socket, << 1:1, 0:3, 8:4, 0:1, 2:7, 1007:16 >>); - {error, handler} -> + {crash, _, _} -> Transport:send(Socket, << 1:1, 0:3, 8:4, 0:1, 2:7, 1011:16 >>); - {remote, closed} -> + remote -> Transport:send(Socket, << 1:1, 0:3, 8:4, 0:8 >>); {remote, Code, _} -> Transport:send(Socket, << 1:1, 0:3, 8:4, 0:1, 2:7, Code:16 >>) @@ -716,5 +736,5 @@ websocket_close(State=#state{socket=Socket, transport=Transport}, when Req::cowboy_req:req(). handler_terminate(#state{env=Env, handler=Handler}, Req, HandlerState, Reason) -> - _ = cowboy_handler:terminate(Req, Env, Handler, HandlerState, Reason), + cowboy_handler:terminate(Reason, Req, HandlerState, Handler), {ok, Req, [{result, closed}|Env]}. diff --git a/src/cowboy_websocket_handler.erl b/src/cowboy_websocket_handler.erl deleted file mode 100644 index a6a036b..0000000 --- a/src/cowboy_websocket_handler.erl +++ /dev/null @@ -1,51 +0,0 @@ -%% Copyright (c) 2011-2014, Loïc Hoguin <[email protected]> -%% -%% Permission to use, copy, modify, and/or distribute this software for any -%% purpose with or without fee is hereby granted, provided that the above -%% copyright notice and this permission notice appear in all copies. -%% -%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - --module(cowboy_websocket_handler). - --type opts() :: any(). --type state() :: any(). -%% @todo see terminate -%-type terminate_reason() :: {normal, shutdown} -% | {normal, timeout} -% | {error, closed} -% | {remote, closed} -% | {remote, cowboy_websocket:close_code(), binary()} -% | {error, badencoding} -% | {error, badframe} -% | {error, atom()}. - --callback init(Req, opts()) - -> {http, Req, state()} - | {long_polling | rest | ws | module(), Req, state()} - | {long_polling | rest | ws | module(), Req, state(), hibernate} - | {long_polling | rest | ws | module(), Req, state(), timeout()} - | {long_polling | rest | ws | module(), Req, state(), timeout(), hibernate} - | {shutdown, Req, state()} - when Req::cowboy_req:req(). --callback websocket_handle({text | binary | ping | pong, binary()}, Req, State) - -> {ok, Req, State} - | {ok, Req, State, hibernate} - | {reply, cowboy_websocket:frame() | [cowboy_websocket:frame()], Req, State} - | {reply, cowboy_websocket:frame() | [cowboy_websocket:frame()], Req, State, hibernate} - | {shutdown, Req, State} - when Req::cowboy_req:req(), State::state(). --callback websocket_info(any(), Req, State) - -> {ok, Req, State} - | {ok, Req, State, hibernate} - | {reply, cowboy_websocket:frame() | [cowboy_websocket:frame()], Req, State} - | {reply, cowboy_websocket:frame() | [cowboy_websocket:frame()], Req, State, hibernate} - | {shutdown, Req, State} - when Req::cowboy_req:req(), State::state(). -%% @todo optional -callback terminate(terminate_reason(), cowboy_req:req(), state()) -> ok. |