Permalink
Browse files

Fix autobahn case Case 1.1.6: message of 65536 bytes.

The message size is bigger than the tcp socket buffer size set by
yaws. This buffer could possibly be made bigger but at some point we'll
have to just read more data before the whole payload can be read.
yaws_websocket:buffer/2 basically concatenates successive buffers,
recursing until the payload is as long as the given Len.
This is probably really dirty and quite slow for bigger messages.
Have a look at cases 9.1.* for a laugh :)
  • Loading branch information...
1 parent 03e7365 commit c8e27e36a334e588a03e09110546c9f4234138b4 @jbothma committed Oct 15, 2011
Showing with 37 additions and 6 deletions.
  1. +23 −3 src/yaws_websockets.erl
  2. +13 −2 www/websockets_autobahn_endpoint.yaws
  3. +1 −1 www/websockets_jd.yaws
View
@@ -115,14 +115,31 @@ ws_version(Headers) ->
end
end.
+buffer(Len, Buffered) ->
+ case Buffered of
+ <<Payload:Len/binary>> ->
+ Payload;
+ _ ->
+ receive
+ {tcp, Socket, More} ->
+ buffer(Len, <<Buffered/binary, More/binary>>)
+ end
+ end.
+
+
unframe_one(8, DataFrames) ->
+ debug(val, {"Frame bytes list length:",length(binary_to_list(DataFrames))}),
<<1:1,_Rsv:3,_Opcode:4,1:1,Len1:7,Rest/binary>> = DataFrames,
-
+ debug(val,{"Len",Len1}),
case Len1 of
126 ->
<<Len:16, MaskingKey:4/binary, Payload:Len/binary>> = Rest;
127 ->
- <<Len:64, MaskingKey:4/binary, Payload:Len/binary>> = Rest;
+ <<Len:64, Rest2/binary>> = Rest,
+ debug(val,{"Len",Len}),
+ <<MaskingKey:4/binary, Rest3/binary>> = Rest2,
+ debug(val, {"Payload bytes list length:",length(binary_to_list(Rest3))}),
+ Payload = buffer(Len, Rest3);
Len ->
<<_:0, MaskingKey:4/binary, Payload:Len/binary>> = Rest
end,
@@ -182,7 +199,7 @@ frame(_, Data) ->
% better than the speed and danger of not checking?
case Defined of
true ->
- << FirstByte, 0:1, 127:7, Length:16, Data:Length/binary >>;
+ << FirstByte, 0:1, 127:7, Length:64, Data:Length/binary >>;
_ ->
undefined
end
@@ -275,3 +292,6 @@ unpack_length(Binary, LenBytes, Length) ->
0 ->
{NewLength, LenBytes + 1}
end.
+
+debug(val, Val) ->
+ io:format("~p~n",[Val]).
@@ -16,10 +16,19 @@ echo_server(WebSocket = {Socket, ProtocolVersion}) ->
receive
{tcp, Socket, DataFrame} ->
Data = yaws_api:websocket_unframe_data(ProtocolVersion, DataFrame),
-
- io:format("Got data from Websocket: ~p~n", [Data]),
+
+ CharCount = length(binary_to_list(Data)),
+ io:format("Text Chars Count = ~p~n", [CharCount]),
+ if
+ CharCount < 1000 ->
+ io:format("Got data from Websocket: ~p~n", [Data]);
+ true ->
+ io:format("Too many chars to print easily...~n",[])
+ end,
yaws_api:websocket_send(WebSocket, Data),
+ io:format("Frame: ~p~n", [frame_info(DataFrame)]),
+
echo_server(WebSocket);
{tcp_closed, Socket} ->
io:format("Websocket closed. Terminating echo_server...~n");
@@ -28,5 +37,7 @@ echo_server(WebSocket = {Socket, ProtocolVersion}) ->
echo_server(WebSocket)
end.
+frame_info(Frame = <<Fin:1,Rsv1:1,Rsv2:1,Rsv3:1,Opcode:4,Masked:1,Len1:7,Rest1/binary>>) ->
+ FrameInfo = [{fin, Fin},{rsv1,Rsv1},{rsv2,Rsv2},{rsv3,Rsv3},{opcode,Opcode},{masked,Masked},{len1,Len1}].
</erl>
View
@@ -4,7 +4,7 @@ out(A) ->
Host = (A#arg.headers)#headers.host,
{abs_path, Path} = (A#arg.req)#http_request.path,
EndpointPath = filename:dirname(Path)
- ++ "websockets_jd_endpoint.yaws",
+ ++ "websockets_autobahn_endpoint.yaws",
WebSocketLocation = Host ++ EndpointPath,
Body = html_body(WebSocketLocation),
{content, "text/html", Body}.

1 comment on commit c8e27e3

Please sign in to comment.