From 9b0049fdd77a1e717b7647af2edcd2872201ac89 Mon Sep 17 00:00:00 2001 From: Ali Sabil Date: Sun, 8 Apr 2012 11:57:30 +0200 Subject: 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. --- src/cowboy_websocket.erl | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'src/cowboy_websocket.erl') 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. -- cgit v1.2.3