diff options
Diffstat (limited to 'src/HTTPServer/HTTPMessage.cpp')
-rw-r--r-- | src/HTTPServer/HTTPMessage.cpp | 290 |
1 files changed, 0 insertions, 290 deletions
diff --git a/src/HTTPServer/HTTPMessage.cpp b/src/HTTPServer/HTTPMessage.cpp deleted file mode 100644 index 360145a9a..000000000 --- a/src/HTTPServer/HTTPMessage.cpp +++ /dev/null @@ -1,290 +0,0 @@ - -// HTTPMessage.cpp - -// Declares the cHTTPMessage class representing the common ancestor for HTTP request and response classes - -#include "Globals.h" -#include "HTTPMessage.h" - - - - - -// Disable MSVC warnings: -#if defined(_MSC_VER) - #pragma warning(push) - #pragma warning(disable:4355) // 'this' : used in base member initializer list -#endif - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cHTTPMessage: - -cHTTPMessage::cHTTPMessage(eKind a_Kind) : - m_Kind(a_Kind), - m_ContentLength(AString::npos) -{ -} - - - - - -void cHTTPMessage::AddHeader(const AString & a_Key, const AString & a_Value) -{ - AString Key = StrToLower(a_Key); - cNameValueMap::iterator itr = m_Headers.find(Key); - if (itr == m_Headers.end()) - { - m_Headers[Key] = a_Value; - } - else - { - // The header-field key is specified multiple times, combine into comma-separated list (RFC 2616 @ 4.2) - itr->second.append(", "); - itr->second.append(a_Value); - } - - // Special processing for well-known headers: - if (Key == "content-type") - { - m_ContentType = m_Headers[Key]; - } - else if (Key == "content-length") - { - if (!StringToInteger(m_Headers[Key], m_ContentLength)) - { - m_ContentLength = 0; - } - } -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cHTTPRequest: - -cHTTPRequest::cHTTPRequest(void) : - super(mkRequest), - m_EnvelopeParser(*this), - m_IsValid(true), - m_UserData(nullptr), - m_HasAuth(false), - m_AllowKeepAlive(false) -{ -} - - - - - -size_t cHTTPRequest::ParseHeaders(const char * a_Data, size_t a_Size) -{ - if (!m_IsValid) - { - return AString::npos; - } - - if (m_Method.empty()) - { - // The first line hasn't been processed yet - size_t res = ParseRequestLine(a_Data, a_Size); - ASSERT((res == AString::npos) || (res <= a_Size)); - if ((res == AString::npos) || (res == a_Size)) - { - return res; - } - size_t res2 = m_EnvelopeParser.Parse(a_Data + res, a_Size - res); - ASSERT((res2 == AString::npos) || (res2 <= a_Size - res)); - if (res2 == AString::npos) - { - m_IsValid = false; - return res2; - } - return res2 + res; - } - - if (m_EnvelopeParser.IsInHeaders()) - { - size_t res = m_EnvelopeParser.Parse(a_Data, a_Size); - ASSERT((res == AString::npos) || (res <= a_Size)); - if (res == AString::npos) - { - m_IsValid = false; - } - return res; - } - return 0; -} - - - - - -AString cHTTPRequest::GetBareURL(void) const -{ - size_t idxQM = m_URL.find('?'); - if (idxQM != AString::npos) - { - return m_URL.substr(0, idxQM); - } - else - { - return m_URL; - } -} - - - - - -size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_Size) -{ - auto inBufferSoFar = m_IncomingHeaderData.size(); - m_IncomingHeaderData.append(a_Data, a_Size); - auto IdxEnd = m_IncomingHeaderData.size(); - - // Ignore the initial CRLFs (HTTP spec's "should") - size_t LineStart = 0; - while ( - (LineStart < IdxEnd) && - ( - (m_IncomingHeaderData[LineStart] == '\r') || - (m_IncomingHeaderData[LineStart] == '\n') - ) - ) - { - LineStart++; - } - if (LineStart >= IdxEnd) - { - m_IsValid = false; - return AString::npos; - } - - int NumSpaces = 0; - size_t MethodEnd = 0; - size_t URLEnd = 0; - for (size_t i = LineStart; i < IdxEnd; i++) - { - switch (m_IncomingHeaderData[i]) - { - case ' ': - { - switch (NumSpaces) - { - case 0: - { - MethodEnd = i; - break; - } - case 1: - { - URLEnd = i; - break; - } - default: - { - // Too many spaces in the request - m_IsValid = false; - return AString::npos; - } - } - NumSpaces += 1; - break; - } - case '\n': - { - if ((i == 0) || (m_IncomingHeaderData[i - 1] != '\r') || (NumSpaces != 2) || (i < URLEnd + 7)) - { - // LF too early, without a CR, without two preceeding spaces or too soon after the second space - m_IsValid = false; - return AString::npos; - } - // Check that there's HTTP / version at the end - if (strncmp(m_IncomingHeaderData.c_str() + URLEnd + 1, "HTTP/1.", 7) != 0) - { - m_IsValid = false; - return AString::npos; - } - m_Method = m_IncomingHeaderData.substr(LineStart, MethodEnd - LineStart); - m_URL = m_IncomingHeaderData.substr(MethodEnd + 1, URLEnd - MethodEnd - 1); - return i + 1 - inBufferSoFar; - } - } // switch (m_IncomingHeaderData[i]) - } // for i - m_IncomingHeaderData[] - - // CRLF hasn't been encountered yet, consider all data consumed - return a_Size; -} - - - - - -void cHTTPRequest::OnHeaderLine(const AString & a_Key, const AString & a_Value) -{ - if ( - (NoCaseCompare(a_Key, "Authorization") == 0) && - (strncmp(a_Value.c_str(), "Basic ", 6) == 0) - ) - { - AString UserPass = Base64Decode(a_Value.substr(6)); - size_t idxCol = UserPass.find(':'); - if (idxCol != AString::npos) - { - m_AuthUsername = UserPass.substr(0, idxCol); - m_AuthPassword = UserPass.substr(idxCol + 1); - m_HasAuth = true; - } - } - if ((a_Key == "Connection") && (NoCaseCompare(a_Value, "keep-alive") == 0)) - { - m_AllowKeepAlive = true; - } - AddHeader(a_Key, a_Value); -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cHTTPResponse: - -cHTTPResponse::cHTTPResponse(void) : - super(mkResponse) -{ -} - - - - - -void cHTTPResponse::AppendToData(AString & a_DataStream) const -{ - a_DataStream.append("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-Type: "); - a_DataStream.append(m_ContentType); - a_DataStream.append("\r\n"); - for (cNameValueMap::const_iterator itr = m_Headers.begin(), end = m_Headers.end(); itr != end; ++itr) - { - if ((itr->first == "Content-Type") || (itr->first == "Content-Length")) - { - continue; - } - a_DataStream.append(itr->first); - a_DataStream.append(": "); - a_DataStream.append(itr->second); - a_DataStream.append("\r\n"); - } // for itr - m_Headers[] - a_DataStream.append("\r\n"); -} - - - - |