aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpasio.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-10-15 11:24:13 +0200
committerStefan Boberg <[email protected]>2021-10-15 11:24:13 +0200
commita53fc4eda27a00415f020818d44c3f88942f9010 (patch)
tree7fc307c3b501e3c18392f46b256649a0cab7503d /zenhttp/httpasio.cpp
parentasio HTTP implementation (#23) (diff)
downloadzen-a53fc4eda27a00415f020818d44c3f88942f9010.tar.xz
zen-a53fc4eda27a00415f020818d44c3f88942f9010.zip
httpasio: implemented proper handling of query strings
Also removed fake dates from responses (there are in fact no date headers at all now)
Diffstat (limited to 'zenhttp/httpasio.cpp')
-rw-r--r--zenhttp/httpasio.cpp107
1 files changed, 63 insertions, 44 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp
index 015d32633..1f049b0c1 100644
--- a/zenhttp/httpasio.cpp
+++ b/zenhttp/httpasio.cpp
@@ -31,7 +31,7 @@ inline spdlog::logger&
InitLogger()
{
spdlog::logger& Logger = logging::Get("asio");
-// Logger.set_level(spdlog::level::trace);
+ // Logger.set_level(spdlog::level::trace);
return Logger;
}
@@ -96,7 +96,6 @@ public:
asio_http::HttpRequest& m_Request;
IoBuffer m_PayloadBuffer;
- std::string_view m_QueryString;
std::unique_ptr<HttpResponse> m_Response;
};
@@ -106,12 +105,12 @@ struct HttpRequest
void Initialize();
size_t ConsumeData(const char* InputData, size_t DataSize);
-
- void ResetState();
+ void ResetState();
HttpVerb RequestVerb() const { return m_RequestVerb; }
bool IsKeepAlive() const { return m_KeepAlive; }
std::string_view Url() const { return std::string_view(m_Url, m_UrlLength); }
+ std::string_view QueryString() const { return std::string_view(m_QueryString, m_QueryLength); }
IoBuffer Body() { return m_BodyBuffer; }
inline HttpContentType ContentType()
@@ -149,6 +148,8 @@ private:
char* m_HeaderCursor = m_HeaderBuffer;
char* m_Url = nullptr;
size_t m_UrlLength = 0;
+ char* m_QueryString = nullptr;
+ size_t m_QueryLength = 0;
char* m_CurrentHeaderName = nullptr; // Used while parsing headers
size_t m_CurrentHeaderNameLength = 0;
char* m_CurrentHeaderValue = nullptr; // Used while parsing headers
@@ -249,14 +250,14 @@ public:
{
m_Headers << "HTTP/1.1 " << ResponseCode() << " " << ReasonStringForHttpResultCode(ResponseCode()) << "\r\n"
<< "Content-Type: " << MapContentTypeToString(m_ContentType) << "\r\n"
- << "Content-Length: " << ContentLength() << "\r\n";
+ << "Content-Length: " << ContentLength() << "\r\n"sv;
if (!m_IsKeepAlive)
{
- m_Headers << "Connection: close\r\n";
+ m_Headers << "Connection: close\r\n"sv;
}
- m_Headers << "Date: Mon, 11 Oct 2021 15:06:32 GMT\r\n\r\n"; // TODO: produce more believable data
+ m_Headers << "\r\n"sv;
return m_Headers;
}
@@ -531,13 +532,14 @@ HttpServerConnection::HandleRequest()
{
std::string_view Response =
"HTTP/1.1 404 NOT FOUND\r\n"
- "Date: Mon, 11 Oct 2021 15:06:32 GMT\r\n\r\n"sv;
+ "\r\n"sv;
if (!m_RequestData.IsKeepAlive())
{
Response =
"HTTP/1.1 404 NOT FOUND\r\n"
- "Date: Mon, 11 Oct 2021 15:06:32 GMT\r\nConnection: close\r\n\r\n"sv;
+ "Connection: close\r\n"
+ "\r\n"sv;
}
asio::async_write(*m_Socket.get(), asio::buffer(Response), [this](const asio::error_code& Ec, std::size_t ByteCount) {
@@ -548,13 +550,20 @@ HttpServerConnection::HandleRequest()
{
std::string_view Response =
"HTTP/1.1 404 NOT FOUND\r\n"
- "Content-Length: 23\r\nContent-Type: text/plain\r\nDate: Mon, 11 Oct 2021 15:06:32 GMT\r\n\r\nNo suitable route found"sv;
+ "Content-Length: 23\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "No suitable route found"sv;
if (!m_RequestData.IsKeepAlive())
{
Response =
"HTTP/1.1 404 NOT FOUND\r\n"
- "Content-Length: 23\r\nContent-Type: text/plain\r\nDate: Mon, 11 Oct 2021 15:06:32 GMT\r\nConnection: close\r\n\r\nNo suitable route found"sv;
+ "Content-Length: 23\r\n"
+ "Content-Type: text/plain\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "No suitable route found"sv;
}
asio::async_write(*m_Socket.get(), asio::buffer(Response), [this](const asio::error_code& Ec, std::size_t ByteCount) {
@@ -602,7 +611,7 @@ HttpRequest::ConsumeData(const char* InputData, size_t DataSize)
{
ZEN_WARN("HTTP parser error {}", (uint32_t)m_Parser.http_errno);
- // TODO: we need to kill the connection since we're most likely
+ // TODO: we need to kill the connection since we're most likely
// out of sync and can't make progress
}
@@ -747,6 +756,46 @@ HttpRequest::OnHeadersComplete()
m_KeepAlive = !!http_should_keep_alive(&m_Parser);
+ switch (m_Parser.method)
+ {
+ case HTTP_GET:
+ m_RequestVerb = HttpVerb::kGet;
+ break;
+
+ case HTTP_POST:
+ m_RequestVerb = HttpVerb::kPost;
+ break;
+
+ case HTTP_PUT:
+ m_RequestVerb = HttpVerb::kPut;
+ break;
+
+ case HTTP_DELETE:
+ m_RequestVerb = HttpVerb::kDelete;
+ break;
+
+ case HTTP_HEAD:
+ m_RequestVerb = HttpVerb::kHead;
+ break;
+
+ case HTTP_COPY:
+ m_RequestVerb = HttpVerb::kCopy;
+ break;
+
+ case HTTP_OPTIONS:
+ m_RequestVerb = HttpVerb::kOptions;
+ break;
+ }
+
+ std::string_view Url(m_Url, m_UrlLength);
+
+ if (auto QuerySplit = Url.find_first_of('?'); QuerySplit != std::string_view::npos)
+ {
+ m_UrlLength = QuerySplit;
+ m_QueryString = m_Url + QuerySplit + 1;
+ m_QueryLength = Url.size() - QuerySplit - 1;
+ }
+
return 0;
}
@@ -797,37 +846,6 @@ HttpRequest::OnMessageBegin()
int
HttpRequest::OnMessageComplete()
{
- switch (m_Parser.method)
- {
- case HTTP_GET:
- m_RequestVerb = HttpVerb::kGet;
- break;
-
- case HTTP_POST:
- m_RequestVerb = HttpVerb::kPost;
- break;
-
- case HTTP_PUT:
- m_RequestVerb = HttpVerb::kPut;
- break;
-
- case HTTP_DELETE:
- m_RequestVerb = HttpVerb::kDelete;
- break;
-
- case HTTP_HEAD:
- m_RequestVerb = HttpVerb::kHead;
- break;
-
- case HTTP_COPY:
- m_RequestVerb = HttpVerb::kCopy;
- break;
-
- case HTTP_OPTIONS:
- m_RequestVerb = HttpVerb::kOptions;
- break;
- }
-
m_Connection.HandleRequest();
ResetState();
@@ -905,7 +923,8 @@ HttpAsioServerRequest::HttpAsioServerRequest(asio_http::HttpRequest& Request, Ht
std::string_view Uri = Request.Url();
Uri.remove_prefix(PrefixLength);
- m_Uri = Uri;
+ m_Uri = Uri;
+ m_QueryString = Request.QueryString();
m_Verb = Request.RequestVerb();
m_ContentLength = Request.Body().Size();