2013-09-27 12:14:26 -04:00
|
|
|
|
|
|
|
// HTTPMessage.cpp
|
|
|
|
|
|
|
|
// Declares the cHTTPMessage class representing the common ancestor for HTTP request and response classes
|
|
|
|
|
|
|
|
#include "Globals.h"
|
|
|
|
#include "HTTPMessage.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-10-04 07:07:57 -04:00
|
|
|
// Disable MSVC warnings:
|
|
|
|
#if defined(_MSC_VER)
|
|
|
|
#pragma warning(push)
|
|
|
|
#pragma warning(disable:4355) // 'this' : used in base member initializer list
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-17 16:15:34 -04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2013-09-27 12:14:26 -04:00
|
|
|
// cHTTPMessage:
|
|
|
|
|
|
|
|
cHTTPMessage::cHTTPMessage(eKind a_Kind) :
|
2013-10-04 07:07:57 -04:00
|
|
|
m_Kind(a_Kind),
|
2014-04-01 10:36:00 -04:00
|
|
|
m_ContentLength(AString::npos)
|
2013-09-27 12:14:26 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cHTTPMessage::AddHeader(const AString & a_Key, const AString & a_Value)
|
|
|
|
{
|
2015-12-25 13:54:04 -05:00
|
|
|
auto Key = StrToLower(a_Key);
|
|
|
|
auto itr = m_Headers.find(Key);
|
2013-09-27 12:14:26 -04:00
|
|
|
if (itr == m_Headers.end())
|
|
|
|
{
|
2013-10-04 07:07:57 -04:00
|
|
|
m_Headers[Key] = a_Value;
|
2013-09-27 12:14:26 -04:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
2016-02-05 16:45:45 -05:00
|
|
|
|
2013-09-27 12:14:26 -04:00
|
|
|
// Special processing for well-known headers:
|
2013-10-04 07:07:57 -04:00
|
|
|
if (Key == "content-type")
|
2013-09-27 12:14:26 -04:00
|
|
|
{
|
2013-10-04 07:07:57 -04:00
|
|
|
m_ContentType = m_Headers[Key];
|
2013-09-27 12:14:26 -04:00
|
|
|
}
|
2013-10-04 07:07:57 -04:00
|
|
|
else if (Key == "content-length")
|
2013-09-27 12:14:26 -04:00
|
|
|
{
|
2015-01-25 10:25:15 -05:00
|
|
|
if (!StringToInteger(m_Headers[Key], m_ContentLength))
|
|
|
|
{
|
|
|
|
m_ContentLength = 0;
|
|
|
|
}
|
2013-09-27 12:14:26 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-17 16:15:34 -04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2016-02-21 05:34:16 -05:00
|
|
|
// cHTTPOutgoingResponse:
|
2013-09-27 12:14:26 -04:00
|
|
|
|
2016-02-20 06:33:27 -05:00
|
|
|
cHTTPOutgoingResponse::cHTTPOutgoingResponse(void) :
|
2020-04-13 12:38:06 -04:00
|
|
|
Super(mkResponse)
|
2013-09-27 12:14:26 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-02-20 06:33:27 -05:00
|
|
|
void cHTTPOutgoingResponse::AppendToData(AString & a_DataStream) const
|
2013-09-27 12:14:26 -04:00
|
|
|
{
|
2013-09-27 14:33:18 -04:00
|
|
|
a_DataStream.append("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-Type: ");
|
2013-09-27 12:14:26 -04:00
|
|
|
a_DataStream.append(m_ContentType);
|
|
|
|
a_DataStream.append("\r\n");
|
2015-12-25 13:54:04 -05:00
|
|
|
for (auto itr = m_Headers.cbegin(), end = m_Headers.cend(); itr != end; ++itr)
|
2013-09-27 12:14:26 -04:00
|
|
|
{
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-02-20 05:50:52 -05:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// cHTTPIncomingRequest:
|
|
|
|
|
|
|
|
cHTTPIncomingRequest::cHTTPIncomingRequest(const AString & a_Method, const AString & a_URL):
|
|
|
|
Super(mkRequest),
|
|
|
|
m_Method(a_Method),
|
2016-03-11 04:44:35 -05:00
|
|
|
m_URL(a_URL),
|
|
|
|
m_HasAuth(false)
|
2016-02-20 05:50:52 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AString cHTTPIncomingRequest::GetURLPath(void) const
|
|
|
|
{
|
|
|
|
auto idxQuestionMark = m_URL.find('?');
|
|
|
|
if (idxQuestionMark == AString::npos)
|
|
|
|
{
|
|
|
|
return m_URL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return m_URL.substr(0, idxQuestionMark);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cHTTPIncomingRequest::AddHeader(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;
|
|
|
|
}
|
2016-03-03 10:20:11 -05:00
|
|
|
Super::AddHeader(a_Key, a_Value);
|
2016-02-20 05:50:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|