Cuberite
A lightweight, fast and extensible game server for Minecraft
HTTPMessage.cpp
Go to the documentation of this file.
1 
2 // HTTPMessage.cpp
3 
4 // Declares the cHTTPMessage class representing the common ancestor for HTTP request and response classes
5 
6 #include "Globals.h"
7 #include "HTTPMessage.h"
8 
9 
10 
11 
12 
13 // Disable MSVC warnings:
14 #if defined(_MSC_VER)
15  #pragma warning(push)
16  #pragma warning(disable:4355) // 'this' : used in base member initializer list
17 #endif
18 
19 
20 
21 
22 
24 // cHTTPMessage:
25 
27  m_Kind(a_Kind),
28  m_ContentLength(AString::npos)
29 {
30 }
31 
32 
33 
34 
35 
36 void cHTTPMessage::AddHeader(const AString & a_Key, const AString & a_Value)
37 {
38  auto Key = StrToLower(a_Key);
39  auto itr = m_Headers.find(Key);
40  if (itr == m_Headers.end())
41  {
42  m_Headers[Key] = a_Value;
43  }
44  else
45  {
46  // The header-field key is specified multiple times, combine into comma-separated list (RFC 2616 @ 4.2)
47  itr->second.append(", ");
48  itr->second.append(a_Value);
49  }
50 
51  // Special processing for well-known headers:
52  if (Key == "content-type")
53  {
54  m_ContentType = m_Headers[Key];
55  }
56  else if (Key == "content-length")
57  {
59  {
60  m_ContentLength = 0;
61  }
62  }
63 }
64 
65 
66 
67 
68 
70 // cHTTPOutgoingResponse:
71 
73  Super(mkResponse)
74 {
75 }
76 
77 
78 
79 
80 
81 void cHTTPOutgoingResponse::AppendToData(AString & a_DataStream) const
82 {
83  a_DataStream.append("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-Type: ");
84  a_DataStream.append(m_ContentType);
85  a_DataStream.append("\r\n");
86  for (auto itr = m_Headers.cbegin(), end = m_Headers.cend(); itr != end; ++itr)
87  {
88  if ((itr->first == "Content-Type") || (itr->first == "Content-Length"))
89  {
90  continue;
91  }
92  a_DataStream.append(itr->first);
93  a_DataStream.append(": ");
94  a_DataStream.append(itr->second);
95  a_DataStream.append("\r\n");
96  } // for itr - m_Headers[]
97  a_DataStream.append("\r\n");
98 }
99 
100 
101 
102 
103 
105 // cHTTPIncomingRequest:
106 
108  Super(mkRequest),
109  m_Method(a_Method),
110  m_URL(a_URL),
111  m_HasAuth(false)
112 {
113 }
114 
115 
116 
117 
118 
120 {
121  auto idxQuestionMark = m_URL.find('?');
122  if (idxQuestionMark == AString::npos)
123  {
124  return m_URL;
125  }
126  else
127  {
128  return m_URL.substr(0, idxQuestionMark);
129  }
130 }
131 
132 
133 
134 
135 
136 void cHTTPIncomingRequest::AddHeader(const AString & a_Key, const AString & a_Value)
137 {
138  if (
139  (NoCaseCompare(a_Key, "Authorization") == 0) &&
140  (strncmp(a_Value.c_str(), "Basic ", 6) == 0)
141  )
142  {
143  AString UserPass = Base64Decode(a_Value.substr(6));
144  size_t idxCol = UserPass.find(':');
145  if (idxCol != AString::npos)
146  {
147  m_AuthUsername = UserPass.substr(0, idxCol);
148  m_AuthPassword = UserPass.substr(idxCol + 1);
149  m_HasAuth = true;
150  }
151  }
152  if ((a_Key == "Connection") && (NoCaseCompare(a_Value, "keep-alive") == 0))
153  {
154  m_AllowKeepAlive = true;
155  }
156  Super::AddHeader(a_Key, a_Value);
157 }
158 
159 
160 
161 
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
AString Base64Decode(const AString &a_Base64String)
Decodes a Base64-encoded string into the raw data.
int NoCaseCompare(const AString &s1, const AString &s2)
Case-insensitive string comparison.
std::string AString
Definition: StringUtils.h:11
bool StringToInteger(const AString &a_str, T &a_Num)
Parses any integer type.
Definition: StringUtils.h:143
cHTTPMessage(eKind a_Kind)
Definition: HTTPMessage.cpp:26
virtual void AddHeader(const AString &a_Key, const AString &a_Value)
Adds a header into the internal map of headers.
Definition: HTTPMessage.cpp:36
AString m_ContentType
Type of the content; parsed by AddHeader(), set directly by SetContentLength()
Definition: HTTPMessage.h:56
AStringMap m_Headers
Map of headers, with their keys lowercased.
Definition: HTTPMessage.h:53
size_t m_ContentLength
Length of the content that is to be received.
Definition: HTTPMessage.h:61
void AppendToData(AString &a_DataStream) const
Appends the response to the specified datastream - response line and headers.
Definition: HTTPMessage.cpp:81
virtual void AddHeader(const AString &a_Key, const AString &a_Value) override
Adds the specified header into the internal list of headers.
cHTTPIncomingRequest(const AString &a_Method, const AString &a_URL)
Creates a new instance of the class, containing the method and URL provided by the client.
bool m_AllowKeepAlive
Set to true if the request indicated that it supports keepalives.
Definition: HTTPMessage.h:157
AString GetURLPath(void) const
Returns the path part of the URL.
bool m_HasAuth
Set to true if the request contains auth data that was understood by the parser.
Definition: HTTPMessage.h:147
AString m_URL
Full URL of the request.
Definition: HTTPMessage.h:144
AString m_AuthUsername
The username used for auth.
Definition: HTTPMessage.h:150
AString m_AuthPassword
The password used for auth.
Definition: HTTPMessage.h:153