aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2016-12-12 11:41:47 +0100
committerIngela Anderton Andin <[email protected]>2016-12-20 12:28:35 +0100
commit7aa231ee939df914473c44e07ab1c74041c8f589 (patch)
tree38962c5a923e756374187eae24458563adddcb1f /lib
parent1715b9284643150da0f3ea43df42df1a4a90e144 (diff)
downloadotp-7aa231ee939df914473c44e07ab1c74041c8f589.tar.gz
otp-7aa231ee939df914473c44e07ab1c74041c8f589.tar.bz2
otp-7aa231ee939df914473c44e07ab1c74041c8f589.zip
inets: httpc - Chunk size decoding could fail
Correct chunk decoding by adding missing argument to match. The symptom was that chunk decoding sometimes failed depending on stream data arrival timing.
Diffstat (limited to 'lib')
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl4
-rw-r--r--lib/inets/test/httpc_SUITE.erl40
2 files changed, 40 insertions, 4 deletions
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 2e7df8e424..bb500dbb46 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -493,7 +493,7 @@ handle_info({Proto, _Socket, Data},
{noreply, NewState#state{mfa = NewMFA,
request = NewRequest}};
{Module, decode_size,
- [TotalChunk, HexList,
+ [TotalChunk, HexList, AccHeaderSize,
{MaxBodySize, BodySoFar, AccLength, MaxHeaderSize}]}
when BodySoFar =/= <<>> ->
?hcrd("data processed - decode_size", []),
@@ -503,7 +503,7 @@ handle_info({Proto, _Socket, Data},
{_, NewBody, NewRequest} = stream(BodySoFar, Request, Code),
NewState = next_body_chunk(State, Code),
NewMFA = {Module, decode_size,
- [TotalChunk, HexList,
+ [TotalChunk, HexList, AccHeaderSize,
{MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
{noreply, NewState#state{mfa = NewMFA,
request = NewRequest}};
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index b2d0ce7631..0d241833d5 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -126,7 +126,8 @@ only_simulated() ->
redirect_temporary_redirect,
port_in_host_header,
redirect_port_in_host_header,
- relaxed
+ relaxed,
+ multipart_chunks
].
misc() ->
@@ -1111,6 +1112,13 @@ redirect_port_in_host_header(Config) when is_list(Config) ->
inets_test_lib:check_body(Body).
%%-------------------------------------------------------------------------
+multipart_chunks(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/multipart_chunks.html", Config), []},
+ {ok, Ref} = httpc:request(get, Request, [], [{sync, false}, {stream, self}]),
+ ok = receive_stream_n(Ref, 10),
+ httpc:cancel_request(Ref).
+
+%%-------------------------------------------------------------------------
timeout_memory_leak() ->
[{doc, "Check OTP-8739"}].
timeout_memory_leak(Config) when is_list(Config) ->
@@ -1405,7 +1413,7 @@ dummy_server(Caller, SocketType, Inet, Extra) ->
end.
dummy_server_init(Caller, ip_comm, Inet, _) ->
- BaseOpts = [binary, {packet, 0}, {reuseaddr,true}, {active, false}],
+ BaseOpts = [binary, {packet, 0}, {reuseaddr,true}, {keepalive, true}, {active, false}],
{ok, ListenSocket} = gen_tcp:listen(0, [Inet | BaseOpts]),
{ok, Port} = inet:port(ListenSocket),
Caller ! {port, Port},
@@ -1981,6 +1989,16 @@ handle_uri(_,"/missing_CR.html",_,_,_,_) ->
"Content-Length:32\r\n\n" ++
"<HTML><BODY>foobar</BODY></HTML>";
+handle_uri(_,"/multipart_chunks.html",_,_,Socket,_) ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:chunked\r\n" ++
+ "Date: " ++ httpd_util:rfc1123_date() ++ "\r\n"
+ "Connection: Keep-Alive\r\n" ++
+ "Content-Type: multipart/x-mixed-replace; boundary=chunk_boundary\r\n" ++
+ "\r\n",
+ send(Socket, Head),
+ send_multipart_chunks(Socket),
+ http_chunk:encode_last();
handle_uri("HEAD",_,_,_,_,_) ->
"HTTP/1.1 200 ok\r\n" ++
"Content-Length:0\r\n\r\n";
@@ -2277,3 +2295,21 @@ otp_8739_dummy_server_main(_Parent, ListenSocket) ->
Error ->
exit(Error)
end.
+
+send_multipart_chunks(Socket) ->
+ send(Socket, http_chunk:encode("--chunk_boundary\r\n")),
+ send(Socket, http_chunk:encode("Content-Type: text/plain\r\nContent-Length: 4\r\n\r\n")),
+ send(Socket, http_chunk:encode("test\r\n")),
+ ct:sleep(500),
+ send_multipart_chunks(Socket).
+
+receive_stream_n(_, 0) ->
+ ok;
+receive_stream_n(Ref, N) ->
+ receive
+ {http, {Ref, stream_start, _}} ->
+ receive_stream_n(Ref, N);
+ {http, {Ref,stream, Data}} ->
+ ct:pal("Data: ~p", [Data]),
+ receive_stream_n(Ref, N-1)
+ end.