aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorJames Fish <[email protected]>2013-06-11 21:47:26 +0100
committerJames Fish <[email protected]>2013-07-05 22:45:18 +0100
commitf0cc2d01e64f489275821b56c7e4343e4aa5bf97 (patch)
tree32971aa12cfbf2c5675317c1499673d6542eeda1 /test
parent116acaead7c988bf292bdae68e9016ef962553da (diff)
downloadcowboy-f0cc2d01e64f489275821b56c7e4343e4aa5bf97.tar.gz
cowboy-f0cc2d01e64f489275821b56c7e4343e4aa5bf97.tar.bz2
cowboy-f0cc2d01e64f489275821b56c7e4343e4aa5bf97.zip
Fix decoding of chunked body.
Previously cowboy_http:te_chunked/2 would enter an incorrect state if it tried to parse an incomplete chunk when the length was known from the partial chunk. Previosuly cowboy_http:te_chunked/2 expected the trailing "\r\n" to always be present if chunk body was present in the buffer. This is not guaranteed and so this commit accommodates that situation.
Diffstat (limited to 'test')
-rw-r--r--test/http_SUITE.erl50
1 files changed, 50 insertions, 0 deletions
diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl
index bdff0d0..d5cf7f6 100644
--- a/test/http_SUITE.erl
+++ b/test/http_SUITE.erl
@@ -88,6 +88,8 @@
-export([te_chunked/1]).
-export([te_chunked_chopped/1]).
-export([te_chunked_delayed/1]).
+-export([te_chunked_split_body/1]).
+-export([te_chunked_split_crlf/1]).
-export([te_identity/1]).
%% ct.
@@ -162,6 +164,8 @@ groups() ->
te_chunked,
te_chunked_chopped,
te_chunked_delayed,
+ te_chunked_split_body,
+ te_chunked_split_crlf,
te_identity
],
[
@@ -1281,6 +1285,52 @@ te_chunked_delayed(Config) ->
{ok, 200, _, Client3} = cowboy_client:response(Client2),
{ok, Body, _} = cowboy_client:response_body(Client3).
+te_chunked_split_body(Config) ->
+ Client = ?config(client, Config),
+ Body = list_to_binary(io_lib:format("~p", [lists:seq(1, 100)])),
+ Chunks = body_to_chunks(50, Body, []),
+ {ok, Client2} = cowboy_client:request(<<"GET">>,
+ build_url("/echo/body", Config),
+ [{<<"transfer-encoding">>, <<"chunked">>}], Client),
+ {ok, Transport, Socket} = cowboy_client:transport(Client2),
+ _ = [begin
+ case Chunk of
+ %% Final chunk.
+ <<"0\r\n\r\n">> ->
+ ok = Transport:send(Socket, Chunk);
+ _ ->
+ %% Chunk of form <<"9\r\nChunkBody\r\n">>.
+ [Size, ChunkBody, <<>>] =
+ binary:split(Chunk, [<<"\r\n">>], [global]),
+ PartASize = random:uniform(byte_size(ChunkBody)),
+ <<PartA:PartASize/binary, PartB/binary>> = ChunkBody,
+ ok = Transport:send(Socket, [Size, <<"\r\n">>, PartA]),
+ ok = timer:sleep(10),
+ ok = Transport:send(Socket, [PartB, <<"\r\n">>])
+ end
+ end || Chunk <- Chunks],
+ {ok, 200, _, Client3} = cowboy_client:response(Client2),
+ {ok, Body, _} = cowboy_client:response_body(Client3).
+
+te_chunked_split_crlf(Config) ->
+ Client = ?config(client, Config),
+ Body = list_to_binary(io_lib:format("~p", [lists:seq(1, 100)])),
+ Chunks = body_to_chunks(50, Body, []),
+ {ok, Client2} = cowboy_client:request(<<"GET">>,
+ build_url("/echo/body", Config),
+ [{<<"transfer-encoding">>, <<"chunked">>}], Client),
+ {ok, Transport, Socket} = cowboy_client:transport(Client2),
+ _ = [begin
+ %% <<"\r\n">> is last 2 bytes of Chunk split before or after <<"\r">>.
+ Len = byte_size(Chunk) - (random:uniform(2) - 1),
+ <<Chunk2:Len/binary, End/binary>> = Chunk,
+ ok = Transport:send(Socket, Chunk2),
+ ok = timer:sleep(10),
+ ok = Transport:send(Socket, End)
+ end || Chunk <- Chunks],
+ {ok, 200, _, Client3} = cowboy_client:response(Client2),
+ {ok, Body, _} = cowboy_client:response_body(Client3).
+
te_identity(Config) ->
Client = ?config(client, Config),
Body = list_to_binary(io_lib:format("~p", [lists:seq(1, 100)])),