aboutsummaryrefslogtreecommitdiff
path: root/zenhttp
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2022-01-28 13:07:36 +0100
committerPer Larsson <[email protected]>2022-01-28 13:07:36 +0100
commitbd43839e042425d72b584b33c7dbb86dabc95e12 (patch)
tree1e663395ac626f3863ef92e95952b3c4245abf76 /zenhttp
parentGet access token from auth mgr. (diff)
parentCompile fix (diff)
downloadzen-bd43839e042425d72b584b33c7dbb86dabc95e12.tar.xz
zen-bd43839e042425d72b584b33c7dbb86dabc95e12.zip
Merged main.
Diffstat (limited to 'zenhttp')
-rw-r--r--zenhttp/httpasio.cpp22
-rw-r--r--zenhttp/httpasio.h2
-rw-r--r--zenhttp/httpnull.cpp4
-rw-r--r--zenhttp/httpnull.h2
-rw-r--r--zenhttp/httpsys.cpp55
-rw-r--r--zenhttp/httpsys.h4
-rw-r--r--zenhttp/include/zenhttp/httpserver.h2
7 files changed, 63 insertions, 28 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp
index 801bb51ac..f2d48200e 100644
--- a/zenhttp/httpasio.cpp
+++ b/zenhttp/httpasio.cpp
@@ -64,7 +64,7 @@ public:
HttpAsioServerImpl();
~HttpAsioServerImpl();
- void Start(uint16_t Port, int ThreadCount);
+ int Start(uint16_t Port, int ThreadCount);
void Stop();
void RegisterService(const char* UrlPath, HttpService& Service);
HttpService* RouteRequest(std::string_view Url);
@@ -934,7 +934,12 @@ struct HttpAcceptor
m_Acceptor.set_option(asio::ip::v6_only(false));
m_Acceptor.set_option(asio::socket_base::reuse_address(true));
m_Acceptor.set_option(asio::ip::tcp::no_delay(true));
- m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), Port));
+ asio::error_code BindErrorCode;
+ m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), Port), BindErrorCode);
+ if (BindErrorCode == asio::error::access_denied)
+ {
+ m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), 0));
+ }
m_Acceptor.listen();
}
@@ -980,6 +985,8 @@ struct HttpAcceptor
});
}
+ int GetAcceptPort() { return m_Acceptor.local_endpoint().port(); }
+
private:
HttpAsioServerImpl& m_Server;
asio::io_service& m_IoService;
@@ -1119,7 +1126,7 @@ HttpAsioServerImpl::~HttpAsioServerImpl()
{
}
-void
+int
HttpAsioServerImpl::Start(uint16_t Port, int ThreadCount)
{
ZEN_ASSERT(ThreadCount > 0);
@@ -1142,6 +1149,8 @@ HttpAsioServerImpl::Start(uint16_t Port, int ThreadCount)
}
});
}
+
+ return m_Acceptor->GetAcceptPort();
}
void
@@ -1212,12 +1221,11 @@ HttpAsioServer::RegisterService(HttpService& Service)
m_Impl->RegisterService(Service.BaseUri(), Service);
}
-void
+int
HttpAsioServer::Initialize(int BasePort)
{
- m_BasePort = BasePort;
-
- m_Impl->Start(gsl::narrow<uint16_t>(m_BasePort), Max(std::thread::hardware_concurrency(), 8u));
+ m_BasePort = m_Impl->Start(gsl::narrow<uint16_t>(BasePort), Max(std::thread::hardware_concurrency(), 8u));
+ return m_BasePort;
}
void
diff --git a/zenhttp/httpasio.h b/zenhttp/httpasio.h
index 08834ba21..716145955 100644
--- a/zenhttp/httpasio.h
+++ b/zenhttp/httpasio.h
@@ -22,7 +22,7 @@ public:
~HttpAsioServer();
virtual void RegisterService(HttpService& Service) override;
- virtual void Initialize(int BasePort) override;
+ virtual int Initialize(int BasePort) override;
virtual void Run(bool IsInteractiveSession) override;
virtual void RequestExit() override;
diff --git a/zenhttp/httpnull.cpp b/zenhttp/httpnull.cpp
index 31b13a6ce..a6e1d3567 100644
--- a/zenhttp/httpnull.cpp
+++ b/zenhttp/httpnull.cpp
@@ -24,10 +24,10 @@ HttpNullServer::RegisterService(HttpService& Service)
ZEN_UNUSED(Service);
}
-void
+int
HttpNullServer::Initialize(int BasePort)
{
- ZEN_UNUSED(BasePort);
+ return BasePort;
}
void
diff --git a/zenhttp/httpnull.h b/zenhttp/httpnull.h
index 867bbe4d2..74f021f6b 100644
--- a/zenhttp/httpnull.h
+++ b/zenhttp/httpnull.h
@@ -18,7 +18,7 @@ public:
~HttpNullServer();
virtual void RegisterService(HttpService& Service) override;
- virtual void Initialize(int BasePort) override;
+ virtual int Initialize(int BasePort) override;
virtual void Run(bool IsInteractiveSession) override;
virtual void RequestExit() override;
diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp
index b3d109b6a..3c57f7ce3 100644
--- a/zenhttp/httpsys.cpp
+++ b/zenhttp/httpsys.cpp
@@ -746,7 +746,7 @@ HttpSysServer::~HttpSysServer()
}
}
-void
+int
HttpSysServer::InitializeServer(int BasePort)
{
using namespace std::literals;
@@ -762,7 +762,7 @@ HttpSysServer::InitializeServer(int BasePort)
{
ZEN_ERROR("Failed to create server session for '{}': {:#x}", WideToUtf8(WildcardUrlPath), Result);
- return;
+ return BasePort;
}
Result = HttpCreateUrlGroup(m_HttpSessionId, &m_HttpUrlGroupId, 0);
@@ -771,17 +771,29 @@ HttpSysServer::InitializeServer(int BasePort)
{
ZEN_ERROR("Failed to create URL group for '{}': {:#x}", WideToUtf8(WildcardUrlPath), Result);
- return;
+ return BasePort;
}
+ int EffectivePort = BasePort;
+
Result = HttpAddUrlToUrlGroup(m_HttpUrlGroupId, WildcardUrlPath.c_str(), HTTP_URL_CONTEXT(0), 0);
+ // Sharing violation implies the port is being used by another process
+ for (int PortOffset = 1; (Result == ERROR_SHARING_VIOLATION) && (PortOffset < 10); ++PortOffset)
+ {
+ EffectivePort = BasePort + (PortOffset * 100);
+ WildcardUrlPath.Reset();
+ WildcardUrlPath << u8"http://*:"sv << int64_t(EffectivePort) << u8"/"sv;
+
+ Result = HttpAddUrlToUrlGroup(m_HttpUrlGroupId, WildcardUrlPath.c_str(), HTTP_URL_CONTEXT(0), 0);
+ }
+
m_BaseUris.clear();
if (Result == NO_ERROR)
{
m_BaseUris.push_back(WildcardUrlPath.c_str());
}
- else
+ else if (Result == ERROR_ACCESS_DENIED)
{
// If we can't register the wildcard path, we fall back to local paths
// This local paths allow requests originating locally to function, but will not allow
@@ -792,14 +804,26 @@ HttpSysServer::InitializeServer(int BasePort)
const std::u8string_view Hosts[] = {u8"[::1]"sv, u8"localhost"sv, u8"127.0.0.1"sv};
- for (const std::u8string_view Host : Hosts)
+ ULONG InternalResult = ERROR_SHARING_VIOLATION;
+ for (int PortOffset = 0; (InternalResult == ERROR_SHARING_VIOLATION) && (PortOffset < 10); ++PortOffset)
{
- WideStringBuilder<64> LocalUrlPath;
- LocalUrlPath << u8"http://"sv << Host << u8":"sv << int64_t(BasePort) << u8"/"sv;
+ EffectivePort = BasePort + (PortOffset * 100);
- if (HttpAddUrlToUrlGroup(m_HttpUrlGroupId, LocalUrlPath.c_str(), HTTP_URL_CONTEXT(0), 0) == NO_ERROR)
+ for (const std::u8string_view Host : Hosts)
{
- m_BaseUris.push_back(LocalUrlPath.c_str());
+ WideStringBuilder<64> LocalUrlPath;
+ LocalUrlPath << u8"http://"sv << Host << u8":"sv << int64_t(EffectivePort) << u8"/"sv;
+
+ InternalResult = HttpAddUrlToUrlGroup(m_HttpUrlGroupId, LocalUrlPath.c_str(), HTTP_URL_CONTEXT(0), 0);
+
+ if (InternalResult == NO_ERROR)
+ {
+ m_BaseUris.push_back(LocalUrlPath.c_str());
+ }
+ else
+ {
+ break;
+ }
}
}
}
@@ -808,7 +832,7 @@ HttpSysServer::InitializeServer(int BasePort)
{
ZEN_ERROR("Failed to add base URL to URL group for '{}': {:#x}", WideToUtf8(WildcardUrlPath), Result);
- return;
+ return BasePort;
}
HTTP_BINDING_INFO HttpBindingInfo = {{0}, 0};
@@ -823,7 +847,7 @@ HttpSysServer::InitializeServer(int BasePort)
{
ZEN_ERROR("Failed to create request queue for '{}': {:#x}", WideToUtf8(m_BaseUris.front()), Result);
- return;
+ return EffectivePort;
}
HttpBindingInfo.Flags.Present = 1;
@@ -835,7 +859,7 @@ HttpSysServer::InitializeServer(int BasePort)
{
ZEN_ERROR("Failed to set server binding property for '{}': {:#x}", WideToUtf8(m_BaseUris.front()), Result);
- return;
+ return EffectivePort;
}
// Create I/O completion port
@@ -853,6 +877,8 @@ HttpSysServer::InitializeServer(int BasePort)
ZEN_INFO("Started http.sys server at '{}'", WideToUtf8(m_BaseUris.front()));
}
+
+ return EffectivePort;
}
void
@@ -1603,11 +1629,12 @@ InitialRequestHandler::HandleCompletion(ULONG IoResult, ULONG_PTR NumberOfBytesT
// HttpServer interface implementation
//
-void
+int
HttpSysServer::Initialize(int BasePort)
{
- InitializeServer(BasePort);
+ int EffectivePort = InitializeServer(BasePort);
StartServer();
+ return EffectivePort;
}
void
diff --git a/zenhttp/httpsys.h b/zenhttp/httpsys.h
index 06bad99c3..0453b8740 100644
--- a/zenhttp/httpsys.h
+++ b/zenhttp/httpsys.h
@@ -41,7 +41,7 @@ public:
// HttpServer interface implementation
- virtual void Initialize(int BasePort) override;
+ virtual int Initialize(int BasePort) override;
virtual void Run(bool TestMode) override;
virtual void RequestExit() override;
virtual void RegisterService(HttpService& Service) override;
@@ -52,7 +52,7 @@ public:
inline bool IsAsyncResponseEnabled() const { return m_IsAsyncResponseEnabled; }
private:
- void InitializeServer(int BasePort);
+ int InitializeServer(int BasePort);
void Cleanup();
void StartServer();
diff --git a/zenhttp/include/zenhttp/httpserver.h b/zenhttp/include/zenhttp/httpserver.h
index 902310f04..545b96db2 100644
--- a/zenhttp/include/zenhttp/httpserver.h
+++ b/zenhttp/include/zenhttp/httpserver.h
@@ -169,7 +169,7 @@ class HttpServer : public RefCounted
{
public:
virtual void RegisterService(HttpService& Service) = 0;
- virtual void Initialize(int BasePort) = 0;
+ virtual int Initialize(int BasePort) = 0;
virtual void Run(bool IsInteractiveSession) = 0;
virtual void RequestExit() = 0;
};