From a29d62307666e8fb0138ce72eca8577ccfa12800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ri=C4=8Dardas=20Pocius?= Date: Mon, 1 Oct 2018 21:55:54 +0300 Subject: [PATCH 1/2] Gather full http response before giving away the socket. fix 536 --- src/hackney_http_connect.erl | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/hackney_http_connect.erl b/src/hackney_http_connect.erl index 52fe9c32..13dc7671 100644 --- a/src/hackney_http_connect.erl +++ b/src/hackney_http_connect.erl @@ -20,6 +20,7 @@ sockname/1]). -define(TIMEOUT, infinity). +-define(MAX_RESPONSE_HEADER_SIZE, 8192). -type http_socket() :: {atom(), inet:socket()}. -export_type([http_socket/0]). @@ -186,13 +187,35 @@ do_handshake(Socket, Host, Port, Options) -> end. check_response(Socket) -> - case gen_tcp:recv(Socket, 0, ?TIMEOUT) of + case gather_response(Socket, <<>>) of {ok, Data} -> check_status(Data); Error -> Error end. +gather_response(Socket, Buffer) -> + ReadResult = gen_tcp:recv(Socket, 0, ?TIMEOUT), + case gather_lines(Buffer, ReadResult) of + {match, NBuffer} -> + {ok, NBuffer}; + {nomatch, NBuffer} -> + gather_response(Socket, NBuffer); + Error -> + Error + end. + +gather_lines(Buffer, {ok, Data}) when (size(Buffer) + size(Data)) > ?MAX_RESPONSE_HEADER_SIZE -> + {error, response_to_big}; +gather_lines(Buffer, {ok, Data}) -> + NBuffer = <>, + case binary:match(NBuffer, <<"\r\n\r\n\r\n">>) of + nomatch -> {nomatch, NBuffer}; + _Match -> {match, NBuffer} + end; +gather_lines(_, Error) -> + Error. + check_status(<< "HTTP/1.1 200", _/bits >>) -> ok; check_status(<< "HTTP/1.1 201", _/bits >>) -> From 303771bbe0f7a75200d4fa40a7a00f08d2f38a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ri=C4=8Dardas=20Pocius?= Date: Tue, 2 Oct 2018 16:43:30 +0300 Subject: [PATCH 2/2] Fix the fix, match for on too many end of line removed --- src/hackney_http_connect.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hackney_http_connect.erl b/src/hackney_http_connect.erl index 13dc7671..eee57398 100644 --- a/src/hackney_http_connect.erl +++ b/src/hackney_http_connect.erl @@ -209,7 +209,7 @@ gather_lines(Buffer, {ok, Data}) when (size(Buffer) + size(Data)) > ?MAX_RESPONS {error, response_to_big}; gather_lines(Buffer, {ok, Data}) -> NBuffer = <>, - case binary:match(NBuffer, <<"\r\n\r\n\r\n">>) of + case binary:match(NBuffer, <<"\r\n\r\n">>) of nomatch -> {nomatch, NBuffer}; _Match -> {match, NBuffer} end;