Skip to content

Commit

Permalink
Update behaviours for R15B+
Browse files Browse the repository at this point in the history
This effectively drops the R14B compatibility.

The cowboy_req:req() type will be introduced in a future commit.
It refers to the #http_req{} record.
  • Loading branch information
essen committed Aug 27, 2012
1 parent 10adcdb commit cc2e084
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 68 deletions.
5 changes: 0 additions & 5 deletions src/cowboy_app.erl
Expand Up @@ -20,15 +20,10 @@
-export([start/2]).
-export([stop/1]).

-type application_start_type() :: normal
| {takeover, node()} | {failover, node()}.

%% API.

-spec start(application_start_type(), any()) -> {ok, pid()}.
start(_Type, _Args) ->
cowboy_sup:start_link().

-spec stop(any()) -> ok.
stop(_State) ->
ok.
7 changes: 0 additions & 7 deletions src/cowboy_clock.erl
Expand Up @@ -107,7 +107,6 @@ rfc2109(LocalTime) ->
%% gen_server.

%% @private
-spec init([]) -> {ok, #state{}}.
init([]) ->
?TABLE = ets:new(?TABLE, [set, protected,
named_table, {read_concurrency, true}]),
Expand All @@ -118,21 +117,17 @@ init([]) ->
{ok, #state{universaltime=T, rfc1123=B, tref=TRef}}.

%% @private
-spec handle_call(_, _, State)
-> {reply, ignored, State} | {stop, normal, stopped, State}.
handle_call(stop, _From, State=#state{tref=TRef}) ->
{ok, cancel} = timer:cancel(TRef),
{stop, normal, stopped, State};
handle_call(_Request, _From, State) ->
{reply, ignored, State}.

%% @private
-spec handle_cast(_, State) -> {noreply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.

%% @private
-spec handle_info(_, State) -> {noreply, State}.
handle_info(update, #state{universaltime=Prev, rfc1123=B1, tref=TRef}) ->
T = erlang:universaltime(),
B2 = update_rfc1123(B1, Prev, T),
Expand All @@ -142,12 +137,10 @@ handle_info(_Info, State) ->
{noreply, State}.

%% @private
-spec terminate(_, _) -> ok.
terminate(_Reason, _State) ->
ok.

%% @private
-spec code_change(_, State, _) -> {ok, State}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.

Expand Down
54 changes: 27 additions & 27 deletions src/cowboy_http_handler.erl
Expand Up @@ -12,37 +12,37 @@
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

%% @doc Handler for HTTP requests.
%% @doc Behaviour for short-lived HTTP handlers.
%%
%% HTTP handlers must implement three callbacks: <em>init/3</em>,
%% <em>handle/2</em> and <em>terminate/2</em>, called one after another in
%% that order.
%% <em>init/3</em> allows you to initialize a state for all subsequent
%% callbacks, and indicate to Cowboy whether you accept to handle the
%% request or want to shutdown without handling it, in which case the
%% <em>handle/2</em> call will simply be skipped.
%%
%% <em>init/3</em> is meant for initialization. It receives information about
%% the transport and protocol used, along with the handler options from the
%% dispatch list, and allows you to upgrade the protocol if needed. You can
%% define a request-wide state here.
%% <em>handle/2</em> allows you to handle the request. It receives the
%% state previously defined.
%%
%% <em>handle/2</em> is meant for handling the request. It receives the
%% request and the state previously defined.
%% <em>terminate/2</em> allows you to clean up. It receives the state
%% previously defined.
%%
%% <em>terminate/2</em> is meant for cleaning up. It also receives the
%% request and the state previously defined.
%%
%% You do not have to read the request body or even send a reply if you do
%% not need to. Cowboy will properly handle these cases and clean-up afterwards.
%% In doubt it'll simply close the connection.
%%
%% Note that when upgrading the connection to WebSocket you do not need to
%% define the <em>handle/2</em> and <em>terminate/2</em> callbacks.
%% There is no required operation to perform in any of these callbacks
%% other than returning the proper values. Make sure you always return
%% the last modified Req so that Cowboy has the up to date information
%% about the request.
-module(cowboy_http_handler).

-export([behaviour_info/1]).
-type opts() :: any().
-type state() :: any().

%% @private
-spec behaviour_info(_)
-> undefined | [{handle, 2} | {init, 3} | {terminate, 2}, ...].
behaviour_info(callbacks) ->
[{init, 3}, {handle, 2}, {terminate, 2}];
behaviour_info(_Other) ->
undefined.
-callback init({atom(), http}, Req, opts())
-> {ok, Req, state()}
| {loop, Req, state()}
| {loop, Req, state(), hibernate}
| {loop, Req, state(), timeout()}
| {loop, Req, state(), timeout(), hibernate}
| {shutdown, Req, state()}
| {upgrade, protocol, module()}
when Req::cowboy_req:req().
-callback handle(Req, State) -> {ok, Req, State}
when Req::cowboy_req:req(), State::state().
-callback terminate(cowboy_req:req(), state()) -> ok.
57 changes: 57 additions & 0 deletions src/cowboy_loop_handler.erl
@@ -0,0 +1,57 @@
%% Copyright (c) 2011-2012, Loïc Hoguin <essen@ninenines.eu>
%%
%% 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.

%% @doc Behaviour for long-lived HTTP handlers.
%%
%% <em>init/3</em> allows you to initialize a state for all subsequent
%% callbacks, and indicate to Cowboy whether you accept to handle the
%% request or want to shutdown without handling it, in which case the
%% receive loop and <em>info/3</em> calls will simply be skipped.
%%
%% <em>info/3</em> allows you to handle the messages this process will
%% receive. It receives the message and the state previously defined.
%% It can decide to stop the receive loop or continue receiving.
%%
%% <em>terminate/2</em> allows you to clean up. It receives the state
%% previously defined.
%%
%% There is no required operation to perform in any of these callbacks
%% other than returning the proper values. Make sure you always return
%% the last modified Req so that Cowboy has the up to date information
%% about the request.
%%
%% It is recommended to use hibernate if this process is not going to
%% receive a lot of messages. It is also recommended to use a timeout
%% value so that the connection gets closed after a long period of
%% inactivity.
-module(cowboy_loop_handler).

-type opts() :: any().
-type state() :: any().

-callback init({atom(), http}, Req, opts())
-> {ok, Req, state()}
| {loop, Req, state()}
| {loop, Req, state(), hibernate}
| {loop, Req, state(), timeout()}
| {loop, Req, state(), timeout(), hibernate}
| {shutdown, Req, state()}
| {upgrade, protocol, module()}
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().
-callback terminate(cowboy_req:req(), state()) -> ok.
7 changes: 0 additions & 7 deletions src/cowboy_sup.erl
Expand Up @@ -32,13 +32,6 @@ start_link() ->

%% supervisor.

-spec init([]) -> {'ok', {{'one_for_one', 10, 10}, [{
any(), {atom() | tuple(), atom(), 'undefined' | [any()]},
'permanent' | 'temporary' | 'transient',
'brutal_kill' | 'infinity' | non_neg_integer(),
'supervisor' | 'worker',
'dynamic' | [atom() | tuple()]}]
}}.
init([]) ->
Procs = [{cowboy_clock, {cowboy_clock, start_link, []},
permanent, 5000, worker, [cowboy_clock]}],
Expand Down
Expand Up @@ -14,13 +14,14 @@

%% @doc Handler for HTTP WebSocket requests.
%%
%% WebSocket handlers must implement four callbacks: <em>websocket_init/3</em>,
%% <em>websocket_handle/3</em>, <em>websocket_info/3</em> and
%% <em>websocket_terminate/3</em>. These callbacks will only be called if the
%% connection is upgraded to WebSocket in the HTTP handler's <em>init/3</em>
%% callback. They are then called in that order, although
%% <em>websocket_handle/3</em> will be called for each packet received,
%% and <em>websocket_info</em> for each message received.
%% WebSocket handlers must implement five callbacks: <em>init/3</em>,
%% <em>websocket_init/3</em>, <em>websocket_handle/3</em>,
%% <em>websocket_info/3</em> and <em>websocket_terminate/3</em>.
%% These callbacks will only be called if the connection is upgraded
%% to WebSocket in the HTTP handler's <em>init/3</em> callback.
%% They are then called in that order, although <em>websocket_handle/3</em>
%% will be called for each packet received, and <em>websocket_info</em>
%% for each message received.
%%
%% <em>websocket_init/3</em> is meant for initialization. It receives
%% information about the transport and protocol used, along with the handler
Expand All @@ -45,16 +46,36 @@
%% <em>websocket_info/3</em> can decide to hibernate the process by adding
%% an extra element to the returned tuple, containing the atom
%% <em>hibernate</em>. Doing so helps save memory and improve CPU usage.
-module(cowboy_http_websocket_handler).
-module(cowboy_websocket_handler).

-export([behaviour_info/1]).
-type opts() :: any().
-type state() :: any().
-type terminate_reason() :: {normal, closed}
| {normal, timeout}
| {error, closed}
| {error, badframe}
| {error, atom()}.

%% @private
-spec behaviour_info(_)
-> undefined | [{websocket_handle, 3} | {websocket_info, 3}
| {websocket_init, 3} | {websocket_terminate, 3}, ...].
behaviour_info(callbacks) ->
[{websocket_init, 3}, {websocket_handle, 3},
{websocket_info, 3}, {websocket_terminate, 3}];
behaviour_info(_Other) ->
undefined.
-callback websocket_init(atom(), Req, opts())
-> {ok, Req, state()}
| {ok, Req, state(), hibernate}
| {ok, Req, state(), timeout()}
| {ok, Req, state(), timeout(), hibernate}
| {shutdown, Req}
when Req::cowboy_req:req().
-callback websocket_handle({text | binary | ping | pong, binary()}, Req, State)
-> {ok, Req, State}
| {ok, Req, State, hibernate}
| {reply, {text | binary | ping | pong, binary()}, Req, State}
| {reply, {text | binary | ping | pong, binary()}, 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, {text | binary | ping | pong, binary()}, Req, State}
| {reply, {text | binary | ping | pong, binary()}, Req, State, hibernate}
| {shutdown, Req, State}
when Req::cowboy_req:req(), State::state().
-callback websocket_terminate(terminate_reason(), cowboy_req:req(), state())
-> ok.
1 change: 1 addition & 0 deletions test/http_handler_loop_timeout.erl
@@ -1,6 +1,7 @@
%% Feel free to use, reuse and abuse the code in this file.

-module(http_handler_loop_timeout).
-behaviour(cowboy_loop_handler).
-export([init/3, info/3, terminate/2]).

init({_, http}, Req, _) ->
Expand Down
2 changes: 1 addition & 1 deletion test/websocket_echo_handler.erl
Expand Up @@ -2,7 +2,7 @@

-module(websocket_echo_handler).
-behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler).
-behaviour(cowboy_websocket_handler).
-export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]).
Expand Down
2 changes: 1 addition & 1 deletion test/websocket_handler.erl
Expand Up @@ -2,7 +2,7 @@

-module(websocket_handler).
-behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler).
-behaviour(cowboy_websocket_handler).
-export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]).
Expand Down
2 changes: 1 addition & 1 deletion test/websocket_handler_init_shutdown.erl
Expand Up @@ -2,7 +2,7 @@

-module(websocket_handler_init_shutdown).
-behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler).
-behaviour(cowboy_websocket_handler).
-export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]).
Expand Down
2 changes: 1 addition & 1 deletion test/ws_timeout_hibernate_handler.erl
Expand Up @@ -2,7 +2,7 @@

-module(ws_timeout_hibernate_handler).
-behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler).
-behaviour(cowboy_websocket_handler).
-export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]).
Expand Down

0 comments on commit cc2e084

Please sign in to comment.