From 12d95ab0474dffa443bf82834177db7e10110fae Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 4 Feb 2016 17:44:10 +0100 Subject: HTTP: Fixed response parser, unified API. --- src/HTTP/EnvelopeParser.cpp | 6 +++--- src/HTTP/HTTPRequestParser.h | 4 ++-- src/HTTP/HTTPResponseParser.cpp | 22 +++++++++++++++------- src/HTTP/HTTPResponseParser.h | 6 ++---- 4 files changed, 22 insertions(+), 16 deletions(-) (limited to 'src/HTTP') diff --git a/src/HTTP/EnvelopeParser.cpp b/src/HTTP/EnvelopeParser.cpp index 407e9dcfc..1c49b643f 100644 --- a/src/HTTP/EnvelopeParser.cpp +++ b/src/HTTP/EnvelopeParser.cpp @@ -28,12 +28,12 @@ size_t cEnvelopeParser::Parse(const char * a_Data, size_t a_Size) } // Start searching 1 char from the end of the already received data, if available: - size_t SearchStart = m_IncomingData.size(); - SearchStart = (SearchStart > 1) ? SearchStart - 1 : 0; + auto searchStart = m_IncomingData.size(); + searchStart = (searchStart > 1) ? searchStart - 1 : 0; m_IncomingData.append(a_Data, a_Size); - size_t idxCRLF = m_IncomingData.find("\r\n", SearchStart); + size_t idxCRLF = m_IncomingData.find("\r\n", searchStart); if (idxCRLF == AString::npos) { // Not a complete line yet, all input consumed: diff --git a/src/HTTP/HTTPRequestParser.h b/src/HTTP/HTTPRequestParser.h index f3d3add91..1b06d7b8b 100644 --- a/src/HTTP/HTTPRequestParser.h +++ b/src/HTTP/HTTPRequestParser.h @@ -25,8 +25,8 @@ public: cHTTPRequestParser(void); /** Parses the request line and then headers from the received data. - Returns the number of bytes consumed or AString::npos number for error - */ + Returns the number of bytes consumed or AString::npos number for error. + Once it has fully parsed all the headers, doesn't consume any more data. */ size_t ParseHeaders(const char * a_Data, size_t a_Size); /** Returns true if the request did contain a Content-Length header */ diff --git a/src/HTTP/HTTPResponseParser.cpp b/src/HTTP/HTTPResponseParser.cpp index 9411208e2..5469666b6 100644 --- a/src/HTTP/HTTPResponseParser.cpp +++ b/src/HTTP/HTTPResponseParser.cpp @@ -29,17 +29,18 @@ size_t cHTTPResponseParser::Parse(const char * a_Data, size_t a_Size) // If parsing already finished or errorred, let the caller keep all the data: if (m_IsFinished || m_HasHadError) { - return a_Size; + return 0; } // If still waiting for the status line, add to buffer and try parsing it: + auto inBufferSoFar = m_Buffer.size(); if (m_StatusLine.empty()) { m_Buffer.append(a_Data, a_Size); if (!ParseStatusLine()) { // All data used, but not a complete status line yet. - return 0; + return a_Size; } if (m_HasHadError) { @@ -53,14 +54,20 @@ size_t cHTTPResponseParser::Parse(const char * a_Data, size_t a_Size) m_Callbacks.OnError("Failed to parse the envelope"); return AString::npos; } + ASSERT(bytesConsumed < inBufferSoFar + a_Size); m_Buffer.erase(0, bytesConsumed); if (!m_Buffer.empty()) { // Headers finished and there's still data left in the buffer, process it as message body: HeadersFinished(); - return ParseBody(m_Buffer.data(), m_Buffer.size()); + auto res = ParseBody(m_Buffer.data(), m_Buffer.size()); + if (res == AString::npos) + { + return AString::npos; + } + return res + bytesConsumed - inBufferSoFar; } - return 0; + return a_Size; } // if (m_StatusLine.empty()) // If still parsing headers, send them to the envelope parser: @@ -77,9 +84,9 @@ size_t cHTTPResponseParser::Parse(const char * a_Data, size_t a_Size) { // Headers finished and there's still data left in the buffer, process it as message body: HeadersFinished(); - return ParseBody(a_Data + bytesConsumed, a_Size - bytesConsumed); + return bytesConsumed + ParseBody(a_Data + bytesConsumed, a_Size - bytesConsumed); } - return 0; + return a_Size; } // Already parsing the body @@ -116,7 +123,8 @@ size_t cHTTPResponseParser::ParseBody(const char * a_Data, size_t a_Size) } // Parse the body using the transfer encoding parser: - return m_TransferEncodingParser->Parse(a_Data, a_Size); + // (Note that TE parser returns the number of bytes left, while we return the number of bytes consumed) + return a_Size - m_TransferEncodingParser->Parse(a_Data, a_Size); } diff --git a/src/HTTP/HTTPResponseParser.h b/src/HTTP/HTTPResponseParser.h index 19652ccef..1d867ecc5 100644 --- a/src/HTTP/HTTPResponseParser.h +++ b/src/HTTP/HTTPResponseParser.h @@ -51,8 +51,7 @@ public: cHTTPResponseParser(cCallbacks & a_Callbacks); /** Parses the incoming data and calls the appropriate callbacks. - Returns the number of bytes from the end of a_Data that is already not part of this response. - Returns AString::npos on an error. */ + Returns the number of bytes consumed or AString::npos number for error. */ size_t Parse(const char * a_Data, size_t a_Size); /** Called when the server indicates no more data will be sent (HTTP 1.0 socket closed). @@ -97,8 +96,7 @@ protected: /** Parses the message body. Processes transfer encoding and calls the callbacks for body data. - Returns the number of bytes from the end of a_Data that is already not part of this response. - Returns AString::npos on error. */ + Returns the number of bytes consumed or AString::npos number for error. */ size_t ParseBody(const char * a_Data, size_t a_Size); /** Called internally when the headers-parsing has just finished. */ -- cgit v1.2.3