From 6250b22384dae437892d256b50c2e91df169b7aa Mon Sep 17 00:00:00 2001 From: Hunter Morris Date: Fri, 30 Sep 2011 18:05:02 +0100 Subject: Fix byte-by-byte Websocket handling If the websocket frame handling code in cowboy_http_websocket receives only 1 byte at a time, it fails with a badmatch in cowboy_http_websocket:websocket_data/4. This commit fixes the problem and introduces a test of the correct behaviour. --- src/cowboy_http_websocket.erl | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/cowboy_http_websocket.erl') diff --git a/src/cowboy_http_websocket.erl b/src/cowboy_http_websocket.erl index 1164684..e481d4b 100644 --- a/src/cowboy_http_websocket.erl +++ b/src/cowboy_http_websocket.erl @@ -232,20 +232,26 @@ websocket_data(State=#state{version=0, eop=EOP}, Req, HandlerState, %% @todo We probably should allow limiting frame length. handler_before_loop(State, Req, HandlerState, Data) end; +%% incomplete hybi data frame. +websocket_data(State=#state{version=Version}, Req, HandlerState, Data) + when Version =/= 0, byte_size(Data) =:= 1 -> + handler_before_loop(State, Req, HandlerState, Data); %% hybi data frame. %% @todo Handle Fin. websocket_data(State=#state{version=Version}, Req, HandlerState, Data) when Version =/= 0 -> << 1:1, 0:3, Opcode:4, Mask:1, PayloadLen:7, Rest/bits >> = Data, - {PayloadLen2, Rest2} = case PayloadLen of - 126 -> << L:16, R/bits >> = Rest, {L, R}; - 127 -> << 0:1, L:63, R/bits >> = Rest, {L, R}; - PayloadLen -> {PayloadLen, Rest} + {PayloadLen2, Rest2} = case {PayloadLen, Rest} of + {126, << L:16, R/bits >>} -> {L, R}; + {126, Rest} -> {undefined, Rest}; + {127, << 0:1, L:63, R/bits >>} -> {L, R}; + {127, Rest} -> {undefined, Rest}; + {PayloadLen, Rest} -> {PayloadLen, Rest} end, case {Mask, PayloadLen2} of {0, 0} -> websocket_dispatch(State, Req, HandlerState, Rest2, Opcode, <<>>); - {1, N} when N + 4 < byte_size(Rest2) -> + {1, N} when N + 4 > byte_size(Rest2); N =:= undefined -> %% @todo We probably should allow limiting frame length. handler_before_loop(State, Req, HandlerState, Data); {1, _N} -> -- cgit v1.2.3