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:
parent
10adcdbc7d
commit
cc2e084d45
11 changed files with 128 additions and 68 deletions
|
@ -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.
|
||||||
|
|
|
@ -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}.
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
57
src/cowboy_loop_handler.erl
Normal file
57
src/cowboy_loop_handler.erl
Normal 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.
|
|
@ -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]}],
|
||||||
|
|
|
@ -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.
|
|
@ -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, _) ->
|
||||||
|
|
|
@ -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]).
|
||||||
|
|
|
@ -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]).
|
||||||
|
|
|
@ -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]).
|
||||||
|
|
|
@ -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]).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue