diff options
| author | Stefan Boberg <[email protected]> | 2021-10-15 11:24:13 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-10-15 11:24:13 +0200 |
| commit | a53fc4eda27a00415f020818d44c3f88942f9010 (patch) | |
| tree | 7fc307c3b501e3c18392f46b256649a0cab7503d /zenhttp/httpasio.cpp | |
| parent | asio HTTP implementation (#23) (diff) | |
| download | zen-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.cpp | 107 |
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(); |