diff options
author | Ali Sabil <[email protected]> | 2012-04-08 11:57:30 +0200 |
---|---|---|
committer | Ali Sabil <[email protected]> | 2012-11-27 13:45:25 +0100 |
commit | 9b0049fdd77a1e717b7647af2edcd2872201ac89 (patch) | |
tree | e3846adac4fe351afc9eaae8ba0ef7291a6bf991 | |
parent | 8386e10dcc9a4136717d728bb8c0918dc57d9f93 (diff) | |
download | cowboy-9b0049fdd77a1e717b7647af2edcd2872201ac89.tar.gz cowboy-9b0049fdd77a1e717b7647af2edcd2872201ac89.tar.bz2 cowboy-9b0049fdd77a1e717b7647af2edcd2872201ac89.zip |
Check for errors when calling Transport:send in the websocket protocol
In some situations, the underlying socket might become "half-open" in
which case the websocket will stay in a waiting state indefinitely. The
detection of this state requires checking for errors when calling send.
-rw-r--r-- | src/cowboy_websocket.erl | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index 1c6d20c..515c6d4 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -452,22 +452,38 @@ handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, Req2, HandlerState2, RemainingData); {reply, Payload, Req2, HandlerState2} when is_tuple(Payload) -> - ok = websocket_send(Payload, State), - NextState(State, Req2, HandlerState2, RemainingData); + case websocket_send(Payload, State) of + ok -> + NextState(State, Req2, HandlerState2, RemainingData); + {error, _} = Error -> + handler_terminate(State, Req2, HandlerState2, Error) + end; {reply, Payload, Req2, HandlerState2, hibernate} when is_tuple(Payload) -> - ok = websocket_send(Payload, State), - NextState(State#state{hibernate=true}, - Req2, HandlerState2, RemainingData); + case websocket_send(Payload, State) of + ok -> + NextState(State#state{hibernate=true}, + Req2, HandlerState2, RemainingData); + {error, _} = Error -> + handler_terminate(State, Req2, HandlerState2, Error) + end; {reply, Payload, Req2, HandlerState2} when is_list(Payload) -> - ok = websocket_send_many(Payload, State), - NextState(State, Req2, HandlerState2, RemainingData); + case websocket_send_many(Payload, State) of + ok -> + NextState(State, Req2, HandlerState2, RemainingData); + {error, _} = Error -> + handler_terminate(State, Req2, HandlerState2, Error) + end; {reply, Payload, Req2, HandlerState2, hibernate} when is_list(Payload) -> - ok = websocket_send_many(Payload, State), - NextState(State#state{hibernate=true}, - Req2, HandlerState2, RemainingData); + case websocket_send_many(Payload, State) of + ok -> + NextState(State#state{hibernate=true}, + Req2, HandlerState2, RemainingData); + {error, _} = Error -> + handler_terminate(State, Req2, HandlerState2, Error) + end; {shutdown, Req2, HandlerState2} -> websocket_close(State, Req2, HandlerState2, {normal, shutdown}) catch Class:Reason -> @@ -507,8 +523,10 @@ websocket_send({Type, Payload}, #state{socket=Socket, transport=Transport}) -> websocket_send_many([], _) -> ok; websocket_send_many([Frame|Tail], State) -> - ok = websocket_send(Frame, State), - websocket_send_many(Tail, State). + case websocket_send(Frame, State) of + ok -> websocket_send_many(Tail, State); + Error -> Error + end. -spec websocket_close(#state{}, cowboy_req:req(), any(), {atom(), atom()}) -> closed. |