aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-10-19 13:30:32 +0200
committerStefan Boberg <[email protected]>2021-10-19 13:30:32 +0200
commit0fe877390805272f8efe6c793ffb83e8c159d50a (patch)
tree82752087d8c0386a6c79751fea243f6108a238b2
parentcas: added structured manifest support (diff)
parentstring: Fixed ToLower logic (needs to use unsigned arithmetic) (diff)
downloadzen-0fe877390805272f8efe6c793ffb83e8c159d50a.tar.xz
zen-0fe877390805272f8efe6c793ffb83e8c159d50a.zip
Merge branch 'main' into gc
-rw-r--r--zencore/include/zencore/iobuffer.h3
-rw-r--r--zencore/include/zencore/string.h4
-rw-r--r--zencore/string.cpp6
-rw-r--r--zenhttp/httpasio.cpp50
-rw-r--r--zenhttp/httpsys.cpp12
-rw-r--r--zenserver/projectstore.cpp2
6 files changed, 56 insertions, 21 deletions
diff --git a/zencore/include/zencore/iobuffer.h b/zencore/include/zencore/iobuffer.h
index db462e238..8679511c9 100644
--- a/zencore/include/zencore/iobuffer.h
+++ b/zencore/include/zencore/iobuffer.h
@@ -357,6 +357,9 @@ public:
[[nodiscard]] inline ZenContentType GetContentType() const { return m_Core->GetContentType(); }
[[nodiscard]] ZENCORE_API bool GetFileReference(IoBufferFileReference& OutRef) const;
+ template<typename T>
+ [[nodiscard]] const T* Data() const { return reinterpret_cast<const T*>(m_Core->DataPointer()); }
+
private:
RefPtr<IoBufferCore> m_Core = new IoBufferCore;
diff --git a/zencore/include/zencore/string.h b/zencore/include/zencore/string.h
index a94e063a4..630341056 100644
--- a/zencore/include/zencore/string.h
+++ b/zencore/include/zencore/string.h
@@ -632,7 +632,7 @@ HashStringAsLowerDjb2(const std::string_view& InString)
{
uint32_t HashValue = 5381;
- for (int CurChar : InString)
+ for (uint8_t CurChar : InString)
{
CurChar -= ((CurChar - 'A') <= ('Z' - 'A')) * ('A' - 'a'); // this should be compiled into branchless logic
HashValue = HashValue * 33 + CurChar;
@@ -650,7 +650,7 @@ ToLower(const std::string_view& InString)
for (char& CurChar : Out)
{
- CurChar -= ((CurChar - 'A') <= ('Z' - 'A')) * ('A' - 'a'); // this should be compiled into branchless logic
+ CurChar -= (uint8_t(CurChar - 'A') <= ('Z' - 'A')) * ('A' - 'a'); // this should be compiled into branchless logic
}
return Out;
diff --git a/zencore/string.cpp b/zencore/string.cpp
index 8e7921bb6..43381aa5d 100644
--- a/zencore/string.cpp
+++ b/zencore/string.cpp
@@ -936,6 +936,12 @@ TEST_CASE("string")
CHECK(HashStringAsLowerDjb2("aBCd"sv) == HashStringDjb2(ToLower("aBCd"sv)));
}
+ SUBCASE("tolower")
+ {
+ CHECK_EQ(ToLower("te!st"sv), "te!st"sv);
+ CHECK_EQ(ToLower("TE%St"sv), "te%st"sv);
+ }
+
SUBCASE("ForEachStrTok")
{
const auto Tokens = "here,is,my,different,tokens"sv;
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp
index 12fbdb61e..ce6503a96 100644
--- a/zenhttp/httpasio.cpp
+++ b/zenhttp/httpasio.cpp
@@ -2,14 +2,17 @@
#include "httpasio.h"
+#include <zencore/logging.h>
#include <zenhttp/httpserver.h>
-#include <conio.h>
-#include <zencore/logging.h>
+#include <deque>
+#include <memory_resource>
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <conio.h>
#include <http_parser.h>
#include <asio.hpp>
-#include <deque>
+ZEN_THIRD_PARTY_INCLUDES_END
namespace zen::asio_http {
@@ -24,6 +27,7 @@ struct HttpServerConnection;
static constinit uint32_t HashContentLength = HashStringAsLowerDjb2("Content-Length"sv);
static constinit uint32_t HashContentType = HashStringAsLowerDjb2("Content-Type"sv);
static constinit uint32_t HashAccept = HashStringAsLowerDjb2("Accept"sv);
+static constinit uint32_t HashExpect = HashStringAsLowerDjb2("Expect"sv);
static constinit uint32_t HashSession = HashStringAsLowerDjb2("UE-Session"sv);
static constinit uint32_t HashRequest = HashStringAsLowerDjb2("UE-Request"sv);
@@ -31,7 +35,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;
}
@@ -144,7 +148,6 @@ private:
};
HttpServerConnection& m_Connection;
- char m_HeaderBuffer[512];
char* m_HeaderCursor = m_HeaderBuffer;
char* m_Url = nullptr;
size_t m_UrlLength = 0;
@@ -158,13 +161,15 @@ private:
int8_t m_ContentLengthHeaderIndex;
int8_t m_AcceptHeaderIndex;
int8_t m_ContentTypeHeaderIndex;
- int m_RequestId = -1;
+ HttpVerb m_RequestVerb;
+ bool m_KeepAlive = false;
+ bool m_Expect100Continue = false;
+ int m_RequestId = -1;
Oid m_SessionId{};
IoBuffer m_BodyBuffer;
- uint64_t m_BodyPosition;
+ uint64_t m_BodyPosition = 0;
http_parser m_Parser;
- HttpVerb m_RequestVerb;
- bool m_KeepAlive = false;
+ char m_HeaderBuffer[512];
void AppendInputBytes(const char* Data, size_t Bytes);
void AppendCurrentHeader();
@@ -327,6 +332,7 @@ HttpServerConnection::HttpServerConnection(HttpAsioServerImpl& Server, std::uniq
HttpServerConnection::~HttpServerConnection()
{
+ ZEN_TRACE("destroying connection #{}", m_ConnectionId);
}
void
@@ -701,6 +707,18 @@ HttpRequest::AppendCurrentHeader()
{
std::from_chars(HeaderValue.data(), HeaderValue.data() + HeaderValue.size(), m_RequestId);
}
+ else if (HeaderHash == HashExpect)
+ {
+ if (HeaderValue == "100-continue"sv)
+ {
+ // We don't currently do anything with this
+ m_Expect100Continue = true;
+ }
+ else
+ {
+ ZEN_INFO("Unexpected expect - Expect: {}", HeaderValue);
+ }
+ }
m_Headers.emplace_back(HeaderName, HeaderValue);
}
@@ -744,10 +762,6 @@ HttpRequest::OnHeadersComplete()
{
m_BodyBuffer = IoBuffer(ContentLength);
}
- else
- {
- m_BodyBuffer = {};
- }
m_BodyBuffer.SetContentType(ContentType());
@@ -827,13 +841,14 @@ HttpRequest::ResetState()
m_CurrentHeaderName = nullptr;
m_Url = nullptr;
m_UrlLength = 0;
+ m_QueryString = nullptr;
+ m_QueryLength = 0;
m_ContentLengthHeaderIndex = -1;
m_AcceptHeaderIndex = -1;
m_ContentTypeHeaderIndex = -1;
-
- m_BodyBuffer = {};
- m_BodyPosition = 0;
-
+ m_Expect100Continue = false;
+ m_BodyBuffer = {};
+ m_BodyPosition = 0;
m_Headers.clear();
}
@@ -1115,6 +1130,7 @@ HttpAsioServerImpl::RouteRequest(std::string_view Url)
namespace zen {
HttpAsioServer::HttpAsioServer() : m_Impl(std::make_unique<asio_http::HttpAsioServerImpl>())
{
+ ZEN_DEBUG("Request object size: {} ({:#x})", sizeof(asio_http::HttpRequest), sizeof(asio_http::HttpRequest));
}
HttpAsioServer::~HttpAsioServer()
diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp
index f3568bbd1..cdf9e0a39 100644
--- a/zenhttp/httpsys.cpp
+++ b/zenhttp/httpsys.cpp
@@ -341,8 +341,6 @@ HttpMessageResponseRequest::~HttpMessageResponseRequest()
void
HttpMessageResponseRequest::InitializeForPayload(uint16_t ResponseCode, std::span<IoBuffer> BlobList)
{
- m_ResponseCode = ResponseCode;
-
const uint32_t ChunkCount = gsl::narrow<uint32_t>(BlobList.size());
m_HttpDataChunks.reserve(ChunkCount);
@@ -407,6 +405,16 @@ HttpMessageResponseRequest::InitializeForPayload(uint16_t ResponseCode, std::spa
m_RemainingChunkCount = gsl::narrow<uint32_t>(m_HttpDataChunks.size());
m_TotalDataSize = LocalDataSize;
+
+ if (m_TotalDataSize == 0 && ResponseCode == 200)
+ {
+ // Some HTTP clients really don't like empty responses unless a 204 response is sent
+ m_ResponseCode = uint16_t(HttpResponseCode::NoContent);
+ }
+ else
+ {
+ m_ResponseCode = ResponseCode;
+ }
}
void
diff --git a/zenserver/projectstore.cpp b/zenserver/projectstore.cpp
index 39348b436..d54d03450 100644
--- a/zenserver/projectstore.cpp
+++ b/zenserver/projectstore.cpp
@@ -1613,6 +1613,8 @@ HttpProjectService::HttpProjectService(CasStore& Store, ProjectStore* Projects)
}
m_ProjectStore->DeleteProject(ProjectId);
+
+ return Req.ServerRequest().WriteResponse(HttpResponseCode::NoContent);
}
break;
}