diff options
| author | Per Larsson <[email protected]> | 2022-01-28 13:07:36 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2022-01-28 13:07:36 +0100 |
| commit | bd43839e042425d72b584b33c7dbb86dabc95e12 (patch) | |
| tree | 1e663395ac626f3863ef92e95952b3c4245abf76 /zenhttp | |
| parent | Get access token from auth mgr. (diff) | |
| parent | Compile fix (diff) | |
| download | zen-bd43839e042425d72b584b33c7dbb86dabc95e12.tar.xz zen-bd43839e042425d72b584b33c7dbb86dabc95e12.zip | |
Merged main.
Diffstat (limited to 'zenhttp')
| -rw-r--r-- | zenhttp/httpasio.cpp | 22 | ||||
| -rw-r--r-- | zenhttp/httpasio.h | 2 | ||||
| -rw-r--r-- | zenhttp/httpnull.cpp | 4 | ||||
| -rw-r--r-- | zenhttp/httpnull.h | 2 | ||||
| -rw-r--r-- | zenhttp/httpsys.cpp | 55 | ||||
| -rw-r--r-- | zenhttp/httpsys.h | 4 | ||||
| -rw-r--r-- | zenhttp/include/zenhttp/httpserver.h | 2 |
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; }; |