0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 20:30:23 +00:00

Update behaviours for R15B+

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.
This commit is contained in:
Loïc Hoguin 2012-08-27 12:46:42 +02:00
parent 10adcdbc7d
commit cc2e084d45
11 changed files with 128 additions and 68 deletions

View file

@ -20,15 +20,10 @@
-export([start/2]). -export([start/2]).
-export([stop/1]). -export([stop/1]).
-type application_start_type() :: normal
| {takeover, node()} | {failover, node()}.
%% API. %% API.
-spec start(application_start_type(), any()) -> {ok, pid()}.
start(_Type, _Args) -> start(_Type, _Args) ->
cowboy_sup:start_link(). cowboy_sup:start_link().
-spec stop(any()) -> ok.
stop(_State) -> stop(_State) ->
ok. ok.

View file

@ -107,7 +107,6 @@ rfc2109(LocalTime) ->
%% gen_server. %% gen_server.
%% @private %% @private
-spec init([]) -> {ok, #state{}}.
init([]) -> init([]) ->
?TABLE = ets:new(?TABLE, [set, protected, ?TABLE = ets:new(?TABLE, [set, protected,
named_table, {read_concurrency, true}]), named_table, {read_concurrency, true}]),
@ -118,8 +117,6 @@ init([]) ->
{ok, #state{universaltime=T, rfc1123=B, tref=TRef}}. {ok, #state{universaltime=T, rfc1123=B, tref=TRef}}.
%% @private %% @private
-spec handle_call(_, _, State)
-> {reply, ignored, State} | {stop, normal, stopped, State}.
handle_call(stop, _From, State=#state{tref=TRef}) -> handle_call(stop, _From, State=#state{tref=TRef}) ->
{ok, cancel} = timer:cancel(TRef), {ok, cancel} = timer:cancel(TRef),
{stop, normal, stopped, State}; {stop, normal, stopped, State};
@ -127,12 +124,10 @@ handle_call(_Request, _From, State) ->
{reply, ignored, State}. {reply, ignored, State}.
%% @private %% @private
-spec handle_cast(_, State) -> {noreply, State}.
handle_cast(_Msg, State) -> handle_cast(_Msg, State) ->
{noreply, State}. {noreply, State}.
%% @private %% @private
-spec handle_info(_, State) -> {noreply, State}.
handle_info(update, #state{universaltime=Prev, rfc1123=B1, tref=TRef}) -> handle_info(update, #state{universaltime=Prev, rfc1123=B1, tref=TRef}) ->
T = erlang:universaltime(), T = erlang:universaltime(),
B2 = update_rfc1123(B1, Prev, T), B2 = update_rfc1123(B1, Prev, T),
@ -142,12 +137,10 @@ handle_info(_Info, State) ->
{noreply, State}. {noreply, State}.
%% @private %% @private
-spec terminate(_, _) -> ok.
terminate(_Reason, _State) -> terminate(_Reason, _State) ->
ok. ok.
%% @private %% @private
-spec code_change(_, State, _) -> {ok, State}.
code_change(_OldVsn, State, _Extra) -> code_change(_OldVsn, State, _Extra) ->
{ok, State}. {ok, State}.

View file

@ -12,37 +12,37 @@
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% 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>init/3</em> allows you to initialize a state for all subsequent
%% <em>handle/2</em> and <em>terminate/2</em>, called one after another in %% callbacks, and indicate to Cowboy whether you accept to handle the
%% that order. %% 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 %% <em>handle/2</em> allows you to handle the request. It receives the
%% the transport and protocol used, along with the handler options from the %% state previously defined.
%% dispatch list, and allows you to upgrade the protocol if needed. You can
%% define a request-wide state here.
%% %%
%% <em>handle/2</em> is meant for handling the request. It receives the %% <em>terminate/2</em> allows you to clean up. It receives the state
%% request and the state previously defined. %% previously defined.
%% %%
%% <em>terminate/2</em> is meant for cleaning up. It also receives the %% There is no required operation to perform in any of these callbacks
%% request and the state previously defined. %% other than returning the proper values. Make sure you always return
%% %% the last modified Req so that Cowboy has the up to date information
%% You do not have to read the request body or even send a reply if you do %% about the request.
%% 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.
-module(cowboy_http_handler). -module(cowboy_http_handler).
-export([behaviour_info/1]). -type opts() :: any().
-type state() :: any().
%% @private -callback init({atom(), http}, Req, opts())
-spec behaviour_info(_) -> {ok, Req, state()}
-> undefined | [{handle, 2} | {init, 3} | {terminate, 2}, ...]. | {loop, Req, state()}
behaviour_info(callbacks) -> | {loop, Req, state(), hibernate}
[{init, 3}, {handle, 2}, {terminate, 2}]; | {loop, Req, state(), timeout()}
behaviour_info(_Other) -> | {loop, Req, state(), timeout(), hibernate}
undefined. | {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.

View file

@ -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.

View file

@ -32,13 +32,6 @@ start_link() ->
%% supervisor. %% 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([]) -> init([]) ->
Procs = [{cowboy_clock, {cowboy_clock, start_link, []}, Procs = [{cowboy_clock, {cowboy_clock, start_link, []},
permanent, 5000, worker, [cowboy_clock]}], permanent, 5000, worker, [cowboy_clock]}],

View file

@ -14,13 +14,14 @@
%% @doc Handler for HTTP WebSocket requests. %% @doc Handler for HTTP WebSocket requests.
%% %%
%% WebSocket handlers must implement four callbacks: <em>websocket_init/3</em>, %% WebSocket handlers must implement five callbacks: <em>init/3</em>,
%% <em>websocket_handle/3</em>, <em>websocket_info/3</em> and %% <em>websocket_init/3</em>, <em>websocket_handle/3</em>,
%% <em>websocket_terminate/3</em>. These callbacks will only be called if the %% <em>websocket_info/3</em> and <em>websocket_terminate/3</em>.
%% connection is upgraded to WebSocket in the HTTP handler's <em>init/3</em> %% These callbacks will only be called if the connection is upgraded
%% callback. They are then called in that order, although %% to WebSocket in the HTTP handler's <em>init/3</em> callback.
%% <em>websocket_handle/3</em> will be called for each packet received, %% They are then called in that order, although <em>websocket_handle/3</em>
%% and <em>websocket_info</em> for each message received. %% 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 %% <em>websocket_init/3</em> is meant for initialization. It receives
%% information about the transport and protocol used, along with the handler %% information about the transport and protocol used, along with the handler
@ -45,16 +46,36 @@
%% <em>websocket_info/3</em> can decide to hibernate the process by adding %% <em>websocket_info/3</em> can decide to hibernate the process by adding
%% an extra element to the returned tuple, containing the atom %% an extra element to the returned tuple, containing the atom
%% <em>hibernate</em>. Doing so helps save memory and improve CPU usage. %% <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 -callback websocket_init(atom(), Req, opts())
-spec behaviour_info(_) -> {ok, Req, state()}
-> undefined | [{websocket_handle, 3} | {websocket_info, 3} | {ok, Req, state(), hibernate}
| {websocket_init, 3} | {websocket_terminate, 3}, ...]. | {ok, Req, state(), timeout()}
behaviour_info(callbacks) -> | {ok, Req, state(), timeout(), hibernate}
[{websocket_init, 3}, {websocket_handle, 3}, | {shutdown, Req}
{websocket_info, 3}, {websocket_terminate, 3}]; when Req::cowboy_req:req().
behaviour_info(_Other) -> -callback websocket_handle({text | binary | ping | pong, binary()}, Req, State)
undefined. -> {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.

View file

@ -1,6 +1,7 @@
%% Feel free to use, reuse and abuse the code in this file. %% Feel free to use, reuse and abuse the code in this file.
-module(http_handler_loop_timeout). -module(http_handler_loop_timeout).
-behaviour(cowboy_loop_handler).
-export([init/3, info/3, terminate/2]). -export([init/3, info/3, terminate/2]).
init({_, http}, Req, _) -> init({_, http}, Req, _) ->

View file

@ -2,7 +2,7 @@
-module(websocket_echo_handler). -module(websocket_echo_handler).
-behaviour(cowboy_http_handler). -behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler). -behaviour(cowboy_websocket_handler).
-export([init/3, handle/2, terminate/2]). -export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3, -export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]). websocket_info/3, websocket_terminate/3]).

View file

@ -2,7 +2,7 @@
-module(websocket_handler). -module(websocket_handler).
-behaviour(cowboy_http_handler). -behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler). -behaviour(cowboy_websocket_handler).
-export([init/3, handle/2, terminate/2]). -export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3, -export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]). websocket_info/3, websocket_terminate/3]).

View file

@ -2,7 +2,7 @@
-module(websocket_handler_init_shutdown). -module(websocket_handler_init_shutdown).
-behaviour(cowboy_http_handler). -behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler). -behaviour(cowboy_websocket_handler).
-export([init/3, handle/2, terminate/2]). -export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3, -export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]). websocket_info/3, websocket_terminate/3]).

View file

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