From 7aa231ee939df914473c44e07ab1c74041c8f589 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Mon, 12 Dec 2016 11:41:47 +0100 Subject: 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. --- lib/inets/src/http_client/httpc_handler.erl | 4 +-- lib/inets/test/httpc_SUITE.erl | 40 +++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) (limited to 'lib') 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() -> @@ -1110,6 +1111,13 @@ redirect_port_in_host_header(Config) when is_list(Config) -> {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []), 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"}]. @@ -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" ++ "foobar"; +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. -- cgit v1.2.3