diff options
author | James Fish <[email protected]> | 2013-06-11 21:47:26 +0100 |
---|---|---|
committer | James Fish <[email protected]> | 2013-07-05 22:45:18 +0100 |
commit | f0cc2d01e64f489275821b56c7e4343e4aa5bf97 (patch) | |
tree | 32971aa12cfbf2c5675317c1499673d6542eeda1 /test | |
parent | 116acaead7c988bf292bdae68e9016ef962553da (diff) | |
download | cowboy-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.erl | 50 |
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)])), |