mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-16 05:00:24 +00:00
Allow HTTP handlers to skip the handle/2 step in init/3
You can now return {shutdown, Req, State} from Handler:init/3 to skip the handle/2 step. Also allow init/3 function to send responses.
This commit is contained in:
parent
5740a9671e
commit
138cccb4f9
4 changed files with 24 additions and 3 deletions
|
@ -66,5 +66,5 @@
|
|||
buffer = <<>> :: binary(),
|
||||
|
||||
%% Response.
|
||||
resp_state = locked :: locked | waiting | chunks | done
|
||||
resp_state = waiting :: locked | waiting | chunks | done
|
||||
}).
|
||||
|
|
|
@ -205,6 +205,8 @@ handler_init(Req, State=#state{listener=ListenerPid,
|
|||
try Handler:init({Transport:name(), http}, Req, Opts) of
|
||||
{ok, Req2, HandlerState} ->
|
||||
handler_loop(HandlerState, Req2, State);
|
||||
{shutdown, Req2, HandlerState} ->
|
||||
handler_terminate(HandlerState, Req2, State);
|
||||
%% @todo {upgrade, transport, Module}
|
||||
{upgrade, protocol, Module} ->
|
||||
Module:upgrade(ListenerPid, Handler, Opts, Req)
|
||||
|
@ -220,7 +222,7 @@ handler_init(Req, State=#state{listener=ListenerPid,
|
|||
|
||||
-spec handler_loop(any(), #http_req{}, #state{}) -> ok.
|
||||
handler_loop(HandlerState, Req, State=#state{handler={Handler, Opts}}) ->
|
||||
try Handler:handle(Req#http_req{resp_state=waiting}, HandlerState) of
|
||||
try Handler:handle(Req, HandlerState) of
|
||||
{ok, Req2, HandlerState2} ->
|
||||
next_request(HandlerState2, Req2, State)
|
||||
catch Class:Reason ->
|
||||
|
|
|
@ -95,6 +95,7 @@ init_http_dispatch() ->
|
|||
{[<<"chunked_response">>], chunked_handler, []},
|
||||
{[<<"websocket">>], websocket_handler, []},
|
||||
{[<<"ws_timeout_hibernate">>], ws_timeout_hibernate_handler, []},
|
||||
{[<<"init_shutdown">>], http_handler_init_shutdown, []},
|
||||
{[<<"headers">>, <<"dupe">>], http_handler,
|
||||
[{headers, [{<<"Connection">>, <<"close">>}]}]},
|
||||
{[], http_handler, []}
|
||||
|
@ -224,7 +225,8 @@ raw(Config) ->
|
|||
{"GET / HTTP/1.1\r\nHost: localhost\r\n", 408},
|
||||
{"GET / HTTP/1.1\r\nHost: localhost\r\n\r", 408},
|
||||
{"GET http://localhost/ HTTP/1.1\r\n\r\n", 501},
|
||||
{"GET / HTTP/1.2\r\nHost: localhost\r\n\r\n", 505}
|
||||
{"GET / HTTP/1.2\r\nHost: localhost\r\n\r\n", 505},
|
||||
{"GET /init_shutdown HTTP/1.1\r\nHost: localhost\r\n\r\n", 666}
|
||||
],
|
||||
[{Packet, StatusCode} = raw_req(Packet, Config)
|
||||
|| {Packet, StatusCode} <- Tests].
|
||||
|
|
17
test/http_handler_init_shutdown.erl
Normal file
17
test/http_handler_init_shutdown.erl
Normal file
|
@ -0,0 +1,17 @@
|
|||
%% Feel free to use, reuse and abuse the code in this file.
|
||||
|
||||
-module(http_handler_init_shutdown).
|
||||
-behaviour(cowboy_http_handler).
|
||||
-export([init/3, handle/2, terminate/2]).
|
||||
|
||||
init({_Transport, http}, Req, _Opts) ->
|
||||
Req2 = cowboy_http_req:reply(<<"666 Init Shutdown Testing">>,
|
||||
[{'Connection', <<"close">>}], [], Req),
|
||||
{shutdown, Req2, undefined}.
|
||||
|
||||
handle(Req, State) ->
|
||||
Req2 = cowboy_http_req:reply(200, [], "Hello world!", Req),
|
||||
{ok, Req2, State}.
|
||||
|
||||
terminate(_Req, _State) ->
|
||||
ok.
|
Loading…
Add table
Add a link
Reference in a new issue