From 59da943548c7c1be5f4b27dce73a0ad27cf0de5d Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 14 Nov 2017 14:13:24 +0100 Subject: [PATCH] Fix incorrect socket handling for the HTTP client --- lib/base/stream.cpp | 3 +++ lib/remote/httpresponse.cpp | 39 +++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/base/stream.cpp b/lib/base/stream.cpp index 9390d97b9..57791d305 100644 --- a/lib/base/stream.cpp +++ b/lib/base/stream.cpp @@ -145,6 +145,9 @@ bool StreamReadContext::FillFromStream(const Stream::Ptr& stream, bool may_wait) if (!Buffer) throw std::bad_alloc(); + if (stream->IsEof()) + break; + size_t rc = stream->Read(Buffer + Size, 4096, true); Size += rc; diff --git a/lib/remote/httpresponse.cpp b/lib/remote/httpresponse.cpp index 7f77ed386..ab7458655 100644 --- a/lib/remote/httpresponse.cpp +++ b/lib/remote/httpresponse.cpp @@ -159,12 +159,7 @@ bool HttpResponse::Parse(StreamReadContext& src, bool may_wait) if (line == "") { m_State = HttpResponseBody; - - /* we're done if the request doesn't contain a message body */ - if (!Headers->Contains("content-length") && !Headers->Contains("transfer-encoding")) - Complete = true; - else - m_Body = new FIFO(); + m_Body = new FIFO(); return true; @@ -204,27 +199,41 @@ bool HttpResponse::Parse(StreamReadContext& src, bool may_wait) return true; } } else { - if (src.Eof) + bool hasLengthIndicator = false; + size_t lengthIndicator = 0; + Value contentLengthHeader; + + if (Headers->Get("content-length", &contentLengthHeader)) { + hasLengthIndicator = true; + lengthIndicator = Convert::ToLong(contentLengthHeader); + } + + if (hasLengthIndicator && src.Eof) BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body")); if (src.MustRead) { - if (!src.FillFromStream(m_Stream, false)) { + if (!src.FillFromStream(m_Stream, may_wait)) src.Eof = true; - BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body")); - } src.MustRead = false; } - size_t length_indicator = Convert::ToLong(Headers->Get("content-length")); + if (!hasLengthIndicator) + lengthIndicator = src.Size; - if (src.Size < length_indicator) { + if (src.Size < lengthIndicator) { src.MustRead = true; - return false; + return may_wait; + } + + m_Body->Write(src.Buffer, lengthIndicator); + src.DropData(lengthIndicator); + + if (!hasLengthIndicator && !src.Eof) { + src.MustRead = true; + return may_wait; } - m_Body->Write(src.Buffer, length_indicator); - src.DropData(length_indicator); Complete = true; return true; }