aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http_protocol.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2011-12-08 18:30:13 +0100
committerLoïc Hoguin <[email protected]>2011-12-08 18:30:13 +0100
commit8d2102fe1174d5fb82d80ca3beba83b9d5bbb238 (patch)
tree0197df52297c60b63f1af303e0a7ea84781f8ac1 /src/cowboy_http_protocol.erl
parent7f46e5343625ba32b6e93e6a9a1ba76b4447b7a8 (diff)
downloadcowboy-8d2102fe1174d5fb82d80ca3beba83b9d5bbb238.tar.gz
cowboy-8d2102fe1174d5fb82d80ca3beba83b9d5bbb238.tar.bz2
cowboy-8d2102fe1174d5fb82d80ca3beba83b9d5bbb238.zip
Allow HTTP protocol upgrades to use keepalive
REST needed this to be allowed to chain requests on the same connection.
Diffstat (limited to 'src/cowboy_http_protocol.erl')
-rw-r--r--src/cowboy_http_protocol.erl30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl
index 54df29f..3a6522f 100644
--- a/src/cowboy_http_protocol.erl
+++ b/src/cowboy_http_protocol.erl
@@ -219,8 +219,8 @@ dispatch(Next, Req=#http_req{host=Host, path=Path},
end.
-spec handler_init(#http_req{}, #state{}) -> ok | none().
-handler_init(Req, State=#state{listener=ListenerPid,
- transport=Transport, handler={Handler, Opts}}) ->
+handler_init(Req, State=#state{transport=Transport,
+ handler={Handler, Opts}}) ->
try Handler:init({Transport:name(), http}, Req, Opts) of
{ok, Req2, HandlerState} ->
handler_handle(HandlerState, Req2, State);
@@ -239,7 +239,7 @@ handler_init(Req, State=#state{listener=ListenerPid,
handler_terminate(HandlerState, Req2, State);
%% @todo {upgrade, transport, Module}
{upgrade, protocol, Module} ->
- Module:upgrade(ListenerPid, Handler, Opts, Req)
+ upgrade_protocol(Req, State, Module)
catch Class:Reason ->
error_terminate(500, State),
error_logger:error_msg(
@@ -250,11 +250,19 @@ handler_init(Req, State=#state{listener=ListenerPid,
[Handler, Class, Reason, Opts, Req, erlang:get_stacktrace()])
end.
+-spec upgrade_protocol(#http_req{}, #state{}, atom()) -> ok | none().
+upgrade_protocol(Req, State=#state{listener=ListenerPid,
+ handler={Handler, Opts}}, Module) ->
+ case Module:upgrade(ListenerPid, Handler, Opts, Req) of
+ {UpgradeRes, Req2} -> next_request(Req2, State, UpgradeRes);
+ _Any -> terminate(State)
+ end.
+
-spec handler_handle(any(), #http_req{}, #state{}) -> ok | none().
handler_handle(HandlerState, Req, State=#state{handler={Handler, Opts}}) ->
try Handler:handle(Req, HandlerState) of
{ok, Req2, HandlerState2} ->
- next_request(HandlerState2, Req2, State)
+ terminate_request(HandlerState2, Req2, State)
catch Class:Reason ->
error_logger:error_msg(
"** Handler ~p terminating in handle/2~n"
@@ -294,7 +302,7 @@ handler_loop_timeout(State=#state{loop_timeout=Timeout,
handler_loop(HandlerState, Req, State=#state{loop_timeout_ref=TRef}) ->
receive
{?MODULE, timeout, TRef} ->
- next_request(HandlerState, Req, State);
+ terminate_request(HandlerState, Req, State);
{?MODULE, timeout, OlderTRef} when is_reference(OlderTRef) ->
handler_loop(HandlerState, Req, State);
Message ->
@@ -306,7 +314,7 @@ handler_call(HandlerState, Req, State=#state{handler={Handler, Opts}},
Message) ->
try Handler:info(Message, Req, HandlerState) of
{ok, Req2, HandlerState2} ->
- next_request(HandlerState2, Req2, State);
+ terminate_request(HandlerState2, Req2, State);
{loop, Req2, HandlerState2} ->
handler_before_loop(HandlerState2, Req2, State);
{loop, Req2, HandlerState2, hibernate} ->
@@ -336,10 +344,14 @@ handler_terminate(HandlerState, Req, #state{handler={Handler, Opts}}) ->
HandlerState, Req, erlang:get_stacktrace()])
end.
--spec next_request(any(), #http_req{}, #state{}) -> ok | none().
-next_request(HandlerState, Req=#http_req{connection=Conn, buffer=Buffer},
- State) ->
+-spec terminate_request(any(), #http_req{}, #state{}) -> ok | none().
+terminate_request(HandlerState, Req, State) ->
HandlerRes = handler_terminate(HandlerState, Req, State),
+ next_request(Req, State, HandlerRes).
+
+-spec next_request(#http_req{}, #state{}, any()) -> ok | none().
+next_request(Req=#http_req{connection=Conn, buffer=Buffer},
+ State, HandlerRes) ->
BodyRes = ensure_body_processed(Req),
RespRes = ensure_response(Req),
case {HandlerRes, BodyRes, RespRes, Conn} of