aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpasio.cpp
diff options
context:
space:
mode:
authorMartin Ridgers <[email protected]>2021-11-29 09:18:03 +0100
committerMartin Ridgers <[email protected]>2021-11-29 09:18:03 +0100
commit91aa9708bd42960405019148d39b57dda0155367 (patch)
treeb4ed6d1273e53cbe95e2ec20c37373f629947592 /zenhttp/httpasio.cpp
parentAdded a simple NamedMutex test (diff)
parentMerge pull request #28 from EpicGames/non-elevated-asio (diff)
downloadzen-91aa9708bd42960405019148d39b57dda0155367.tar.xz
zen-91aa9708bd42960405019148d39b57dda0155367.zip
Merged main
Diffstat (limited to 'zenhttp/httpasio.cpp')
-rw-r--r--zenhttp/httpasio.cpp51
1 files changed, 37 insertions, 14 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp
index 0ed5e78cf..e2b9262ff 100644
--- a/zenhttp/httpasio.cpp
+++ b/zenhttp/httpasio.cpp
@@ -17,6 +17,14 @@ ZEN_THIRD_PARTY_INCLUDES_START
#include <asio.hpp>
ZEN_THIRD_PARTY_INCLUDES_END
+#define ASIO_VERBOSE_TRACE 0
+
+#if ASIO_VERBOSE_TRACE
+#define ZEN_TRACE_VERBOSE ZEN_TRACE
+#else
+#define ZEN_TRACE_VERBOSE(fmtstr, ...)
+#endif
+
namespace zen::asio_http {
using namespace std::literals;
@@ -320,6 +328,7 @@ private:
std::unique_ptr<asio::ip::tcp::socket> m_Socket;
std::atomic<uint32_t> m_RequestCounter{0};
uint32_t m_ConnectionId = 0;
+ Ref<IHttpPackageHandler> m_PackageHandler;
RwLock m_ResponsesLock;
std::deque<std::unique_ptr<HttpResponse>> m_Responses;
@@ -332,12 +341,12 @@ HttpServerConnection::HttpServerConnection(HttpAsioServerImpl& Server, std::uniq
, m_Socket(std::move(Socket))
, m_ConnectionId(g_ConnectionIdCounter.fetch_add(1))
{
- ZEN_TRACE("new connection #{}", m_ConnectionId);
+ ZEN_TRACE_VERBOSE("new connection #{}", m_ConnectionId);
}
HttpServerConnection::~HttpServerConnection()
{
- ZEN_TRACE("destroying connection #{}", m_ConnectionId);
+ ZEN_TRACE_VERBOSE("destroying connection #{}", m_ConnectionId);
}
void
@@ -373,18 +382,18 @@ HttpServerConnection::EnqueueRead()
asio::async_read(*m_Socket.get(),
m_RequestBuffer,
- asio::transfer_at_least(16),
+ asio::transfer_at_least(1),
[Conn = AsSharedPtr()](const asio::error_code& Ec, std::size_t ByteCount) { Conn->OnDataReceived(Ec, ByteCount); });
}
void
-HttpServerConnection::OnDataReceived(const asio::error_code& Ec, std::size_t ByteCount)
+HttpServerConnection::OnDataReceived(const asio::error_code& Ec, [[maybe_unused]] std::size_t ByteCount)
{
if (Ec)
{
if (m_RequestState == RequestState::kDone || m_RequestState == RequestState::kInitialRead)
{
- ZEN_TRACE("on data received ERROR (EXPECTED), connection '{}' reason '{}'", m_ConnectionId, Ec.message());
+ ZEN_TRACE_VERBOSE("on data received ERROR (EXPECTED), connection '{}' reason '{}'", m_ConnectionId, Ec.message());
return;
}
else
@@ -394,7 +403,7 @@ HttpServerConnection::OnDataReceived(const asio::error_code& Ec, std::size_t Byt
}
}
- ZEN_TRACE("on data received, connection '{}', request '{}', thread '{}', bytes '{}'",
+ ZEN_TRACE_VERBOSE("on data received, connection '{}', request '{}', thread '{}', bytes '{}'",
m_ConnectionId,
m_RequestCounter.load(std::memory_order_relaxed),
zen::GetCurrentThreadId(),
@@ -423,7 +432,7 @@ HttpServerConnection::OnDataReceived(const asio::error_code& Ec, std::size_t Byt
}
void
-HttpServerConnection::OnResponseDataSent(const asio::error_code& Ec, std::size_t ByteCount, bool Pop)
+HttpServerConnection::OnResponseDataSent(const asio::error_code& Ec, [[maybe_unused]] std::size_t ByteCount, bool Pop)
{
if (Ec)
{
@@ -432,7 +441,7 @@ HttpServerConnection::OnResponseDataSent(const asio::error_code& Ec, std::size_t
}
else
{
- ZEN_TRACE("on data sent, connection '{}', request '{}', thread '{}', bytes '{}'",
+ ZEN_TRACE_VERBOSE("on data sent, connection '{}', request '{}', thread '{}', bytes '{}'",
m_ConnectionId,
m_RequestCounter.load(std::memory_order_relaxed),
zen::GetCurrentThreadId(),
@@ -487,9 +496,13 @@ HttpServerConnection::HandleRequest()
{
HttpAsioServerRequest Request(m_RequestData, *Service, m_RequestData.Body());
- ZEN_TRACE("handle request, connection '{}' request '{}'", m_ConnectionId, m_RequestCounter.load(std::memory_order_relaxed));
- Service->HandleRequest(Request);
+ ZEN_TRACE_VERBOSE("handle request, connection '{}' request '{}'", m_ConnectionId, m_RequestCounter.load(std::memory_order_relaxed));
+
+ if (!HandlePackageOffers(*Service, Request, m_PackageHandler))
+ {
+ Service->HandleRequest(Request);
+ }
if (std::unique_ptr<HttpResponse> Response = std::move(Request.m_Response))
{
@@ -937,7 +950,7 @@ HttpAsioServerRequest::HttpAsioServerRequest(asio_http::HttpRequest& Request, Ht
const int PrefixLength = Service.UriPrefixLength();
std::string_view Uri = Request.Url();
- Uri.remove_prefix(PrefixLength);
+ Uri.remove_prefix(std::min(PrefixLength, static_cast<int>(Uri.size())));
m_Uri = Uri;
m_QueryString = Request.QueryString();
@@ -1101,6 +1114,10 @@ HttpAsioServerImpl::RegisterService(const char* InUrlPath, HttpService& Service)
{
std::string_view UrlPath(InUrlPath);
Service.SetUriPrefixLength(UrlPath.size());
+ if (!UrlPath.empty() && UrlPath.back() == '/')
+ {
+ UrlPath.remove_suffix(1);
+ }
RwLock::ExclusiveLockScope _(m_Lock);
m_UriHandlers.push_back({std::string(UrlPath), &Service});
@@ -1111,16 +1128,22 @@ HttpAsioServerImpl::RouteRequest(std::string_view Url)
{
RwLock::SharedLockScope _(m_Lock);
+ HttpService* CandidateService = nullptr;
+ std::string::size_type CandidateMatchSize = 0;
for (const ServiceEntry& SvcEntry : m_UriHandlers)
{
const std::string& SvcUrl = SvcEntry.ServiceUrlPath;
- if (Url.compare(0, SvcUrl.size(), SvcUrl) == 0)
+ const std::string::size_type SvcUrlSize = SvcUrl.size();
+ if ((SvcUrlSize >= CandidateMatchSize) &&
+ Url.compare(0, SvcUrlSize, SvcUrl) == 0 &&
+ ((SvcUrlSize == Url.size()) || (Url[SvcUrlSize] == '/')))
{
- return SvcEntry.Service;
+ CandidateMatchSize = SvcUrl.size();
+ CandidateService = SvcEntry.Service;
}
}
- return nullptr;
+ return CandidateService;
}
} // namespace zen::asio_http