Navigation Menu

Skip to content

Commit

Permalink
keep websocket errors from crashing gen_server
Browse files Browse the repository at this point in the history
Change websocket implementation to not stop abnormally or crash with noisy
logs if errors occur.
  • Loading branch information
vinoski committed Oct 22, 2012
1 parent fb4df1f commit 2a131ff
Showing 1 changed file with 26 additions and 17 deletions.
43 changes: 26 additions & 17 deletions src/yaws_websockets.erl
Expand Up @@ -151,11 +151,16 @@ handle_info({tcp, Socket, FirstPacket}, #state{wsstate=#ws_state{sock=Socket}}=S
case Results of
{close, Reason} ->
do_close(WSState, Reason),
{stop, Reason, State#state{cbstate=NewCallbackState}};
{stop, normal, State#state{cbstate=NewCallbackState}};
_ ->
Last = lists:last(FrameInfos),
NewWSState = Last#ws_frame_info.ws_state,
{noreply, State#state{wsstate=NewWSState, cbstate=NewCallbackState}}
if
is_record(Last, ws_frame_info) ->
NewWSState = Last#ws_frame_info.ws_state,
{noreply, State#state{wsstate=NewWSState, cbstate=NewCallbackState}};
true ->
{stop, normal, State#state{cbstate=NewCallbackState}}
end
end;
handle_info({tcp_closed, Socket}, #state{wsstate=#ws_state{sock=Socket}}=State) ->
%% The only way we should get here is due to an abnormal close.
Expand Down Expand Up @@ -525,20 +530,24 @@ unframe(State, FirstPacket) ->

%% -> {#ws_frame_info, RestBin} | {fail_connection, Reason}
unframe_one(State = #ws_state{vsn=8}, FirstPacket) ->
{FrameInfo = #ws_frame_info{}, RestBin} = ws_frame_info(State, FirstPacket),
Unmasked = mask(FrameInfo#ws_frame_info.masking_key,
FrameInfo#ws_frame_info.payload),
NewState = frag_state_machine(State, FrameInfo),
Unframed = FrameInfo#ws_frame_info{data = Unmasked,
ws_state = NewState},

case checks(Unframed) of
#ws_frame_info{} when is_record(NewState, ws_state) ->
{Unframed, RestBin};
#ws_frame_info{} when not is_record(NewState, ws_state) ->
NewState; % pass back the error details
Fail ->
Fail
case ws_frame_info(State, FirstPacket) of
{FrameInfo = #ws_frame_info{}, RestBin} ->
Unmasked = mask(FrameInfo#ws_frame_info.masking_key,
FrameInfo#ws_frame_info.payload),
NewState = frag_state_machine(State, FrameInfo),
Unframed = FrameInfo#ws_frame_info{data = Unmasked,
ws_state = NewState},

case checks(Unframed) of
#ws_frame_info{} when is_record(NewState, ws_state) ->
{Unframed, RestBin};
#ws_frame_info{} when not is_record(NewState, ws_state) ->
NewState; % pass back the error details
Fail ->
Fail
end;
Else ->
Else
end.

websocket_setopts(#ws_state{sock=Socket}, Opts) ->
Expand Down

0 comments on commit 2a131ff

Please sign in to comment.