diff options
author | Loïc Hoguin <[email protected]> | 2011-03-19 19:51:44 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2011-03-19 19:51:44 +0100 |
commit | bd3a64631657b5095a2c22ea342c906c9c2aecae (patch) | |
tree | 3924aeec675dcf066675619b7cb10c86370600f7 /src | |
parent | a4f8bb65739b8a3b102c244a5ef7e5aa6a9f38e4 (diff) | |
download | cowboy-bd3a64631657b5095a2c22ea342c906c9c2aecae.tar.gz cowboy-bd3a64631657b5095a2c22ea342c906c9c2aecae.tar.bz2 cowboy-bd3a64631657b5095a2c22ea342c906c9c2aecae.zip |
Protect the calls to the handler using catch.
* Handler:init shouldn't reply anything; send an error 500.
* Handler:handle may have sent something to the client; close the socket.
* Handler:terminate failed to clean itself up. Close the socket.
Diffstat (limited to 'src')
-rw-r--r-- | src/cowboy_http_protocol.erl | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl index b25c2f4..e2a2250 100644 --- a/src/cowboy_http_protocol.erl +++ b/src/cowboy_http_protocol.erl @@ -128,25 +128,29 @@ header(http_eoh, Req, State) -> -spec handler_init(Req::#http_req{}, State::#state{}) -> ok. handler_init(Req, State=#state{handler={Handler, Opts}}) -> - case Handler:init(Req, Opts) of + case catch Handler:init(Req, Opts) of {ok, Req, HandlerState} -> - handler_loop(HandlerState, Req, State) + handler_loop(HandlerState, Req, State); %% @todo {mode, active}; {upgrade_protocol, Module}; {error, Reason} + {'EXIT', _Reason} -> + error_terminate(500, State) end. -spec handler_loop(HandlerState::term(), Req::#http_req{}, State::#state{}) -> ok. handler_loop(HandlerState, Req, State=#state{handler={Handler, _Opts}}) -> - case Handler:handle(Req, HandlerState) of + case catch Handler:handle(Req, HandlerState) of {ok, Req2, HandlerState2} -> - handler_terminate(HandlerState2, Req2, State) + handler_terminate(HandlerState2, Req2, State); %% @todo {mode, active} + {'EXIT', _Reason} -> + terminate(State) end. -spec handler_terminate(HandlerState::term(), Req::#http_req{}, State::#state{}) -> ok. handler_terminate(HandlerState, Req, State=#state{handler={Handler, _Opts}}) -> - Res = Handler:terminate(Req, HandlerState), + Res = (catch Handler:terminate(Req, HandlerState)), %% @todo We need to check if the Req has been replied to. %% All requests must have a reply, at worst an error. %% If a request started but wasn't completed, complete it. |