diff options
| author | Per Larsson <[email protected]> | 2021-12-09 17:01:57 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2021-12-09 17:01:57 +0100 |
| commit | 20f3c16b0012cfb8ce7bf9b6dd06a2720b6885c6 (patch) | |
| tree | fbb0f274840a12c32d93c7e342c0427f2617a651 /zenhttp/httpsys.cpp | |
| parent | Disabled cache tracker. (diff) | |
| parent | Return status_code as ErrorCode from jupiter api if not successful (diff) | |
| download | zen-20f3c16b0012cfb8ce7bf9b6dd06a2720b6885c6.tar.xz zen-20f3c16b0012cfb8ce7bf9b6dd06a2720b6885c6.zip | |
Merged main.
Diffstat (limited to 'zenhttp/httpsys.cpp')
| -rw-r--r-- | zenhttp/httpsys.cpp | 167 |
1 files changed, 64 insertions, 103 deletions
diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp index cdf9e0a39..e9472e3b8 100644 --- a/zenhttp/httpsys.cpp +++ b/zenhttp/httpsys.cpp @@ -748,15 +748,20 @@ HttpSysServer::~HttpSysServer() } void -HttpSysServer::Initialize(const wchar_t* UrlPath) +HttpSysServer::InitializeServer(int BasePort) { + using namespace std::literals; + + WideStringBuilder<64> WildcardUrlPath; + WildcardUrlPath << u8"http://*:"sv << int64_t(BasePort) << u8"/"sv; + m_IsOk = false; ULONG Result = HttpCreateServerSession(HTTPAPI_VERSION_2, &m_HttpSessionId, 0); if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create server session for '{}': {:#x}", WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create server session for '{}': {:#x}", WideToUtf8(WildcardUrlPath), Result); return; } @@ -765,18 +770,44 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create URL group for '{}': {:#x}", WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create URL group for '{}': {:#x}", WideToUtf8(WildcardUrlPath), Result); return; } - m_BaseUri = UrlPath; + Result = HttpAddUrlToUrlGroup(m_HttpUrlGroupId, WildcardUrlPath.c_str(), HTTP_URL_CONTEXT(0), 0); - Result = HttpAddUrlToUrlGroup(m_HttpUrlGroupId, UrlPath, HTTP_URL_CONTEXT(0), 0); + m_BaseUris.clear(); + if (Result == NO_ERROR) + { + m_BaseUris.push_back(WildcardUrlPath.c_str()); + } + else + { + // 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 + // remote origin requests to function. This can be remedied by using netsh + // during an install process to grant permissions to route public access to the appropriate + // port for the current user. eg: + // netsh http add urlacl url=http://*:1337/ user=<some_user> - if (Result != NO_ERROR) + const std::u8string_view Hosts[] = { u8"[::1]"sv, u8"localhost"sv, u8"127.0.0.1"sv }; + + for (const std::u8string_view Host : Hosts) + { + WideStringBuilder<64> LocalUrlPath; + LocalUrlPath << u8"http://"sv << Host << u8":"sv << int64_t(BasePort) << u8"/"sv; + + if (HttpAddUrlToUrlGroup(m_HttpUrlGroupId, LocalUrlPath.c_str(), HTTP_URL_CONTEXT(0), 0) == NO_ERROR) + { + m_BaseUris.push_back(LocalUrlPath.c_str()); + } + } + } + + if (m_BaseUris.empty()) { - ZEN_ERROR("Failed to add base URL to URL group for '{}': {:#x}", WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to add base URL to URL group for '{}': {:#x}", WideToUtf8(WildcardUrlPath), Result); return; } @@ -791,7 +822,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create request queue for '{}': {:#x}", WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create request queue for '{}': {:#x}", WideToUtf8(m_BaseUris.front()), Result); return; } @@ -803,7 +834,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to set server binding property for '{}': {:#x}", WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to set server binding property for '{}': {:#x}", WideToUtf8(m_BaseUris.front()), Result); return; } @@ -815,13 +846,13 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (ErrorCode) { - ZEN_ERROR("Failed to create IOCP for '{}': {}", WideToUtf8(UrlPath), ErrorCode.message()); + ZEN_ERROR("Failed to create IOCP for '{}': {}", WideToUtf8(m_BaseUris.front()), ErrorCode.message()); } else { m_IsOk = true; - ZEN_INFO("Started http.sys server at '{}'", WideToUtf8(UrlPath)); + ZEN_INFO("Started http.sys server at '{}'", WideToUtf8(m_BaseUris.front())); } } @@ -952,15 +983,18 @@ HttpSysServer::RegisterService(const char* UrlPath, HttpService& Service) // Convert to wide string - std::wstring Url16 = m_BaseUri + PathUtf16; + for (const std::wstring& BaseUri : m_BaseUris) + { + std::wstring Url16 = BaseUri + PathUtf16; - ULONG Result = HttpAddUrlToUrlGroup(m_HttpUrlGroupId, Url16.c_str(), HTTP_URL_CONTEXT(&Service), 0 /* Reserved */); + ULONG Result = HttpAddUrlToUrlGroup(m_HttpUrlGroupId, Url16.c_str(), HTTP_URL_CONTEXT(&Service), 0 /* Reserved */); - if (Result != NO_ERROR) - { - ZEN_ERROR("HttpAddUrlToUrlGroup failed with result: '{}'", GetSystemErrorAsString(Result)); + if (Result != NO_ERROR) + { + ZEN_ERROR("HttpAddUrlToUrlGroup failed with result: '{}'", GetSystemErrorAsString(Result)); - return; + return; + } } } @@ -978,13 +1012,16 @@ HttpSysServer::UnregisterService(const char* UrlPath, HttpService& Service) // Convert to wide string - std::wstring Url16 = m_BaseUri + PathUtf16; + for (const std::wstring& BaseUri : m_BaseUris) + { + std::wstring Url16 = BaseUri + PathUtf16; - ULONG Result = HttpRemoveUrlFromUrlGroup(m_HttpUrlGroupId, Url16.c_str(), 0); + ULONG Result = HttpRemoveUrlFromUrlGroup(m_HttpUrlGroupId, Url16.c_str(), 0); - if (Result != NO_ERROR) - { - ZEN_ERROR("HttpRemoveUrlFromUrlGroup failed with result: '{}'", GetSystemErrorAsString(Result)); + if (Result != NO_ERROR) + { + ZEN_ERROR("HttpRemoveUrlFromUrlGroup failed with result: '{}'", GetSystemErrorAsString(Result)); + } } } @@ -1131,83 +1168,12 @@ HttpSysTransaction::InvokeRequestHandler(HttpService& Service, IoBuffer Payload) { HttpSysServerRequest& ThisRequest = m_HandlerRequest.emplace(*this, Service, Payload); - if (ThisRequest.RequestVerb() == HttpVerb::kPost) - { - if (ThisRequest.RequestContentType() == HttpContentType::kCbPackageOffer) - { - // The client is presenting us with a package attachments offer, we need - // to filter it down to the list of attachments we need them to send in - // the follow-up request - - m_PackageHandler = Service.HandlePackageRequest(ThisRequest); - - if (m_PackageHandler) - { - CbObject OfferMessage = LoadCompactBinaryObject(Payload); - - std::vector<IoHash> OfferCids; - - for (auto& CidEntry : OfferMessage["offer"]) - { - if (!CidEntry.IsHash()) - { - // Should yield bad request response? - - ZEN_WARN("found invalid entry in offer"); - - continue; - } - - OfferCids.push_back(CidEntry.AsHash()); - } - - ZEN_TRACE("request #{} -> filtering offer of {} entries", ThisRequest.RequestId(), OfferCids.size()); - - m_PackageHandler->FilterOffer(OfferCids); - - ZEN_TRACE("request #{} -> filtered to {} entries", ThisRequest.RequestId(), OfferCids.size()); - - CbObjectWriter ResponseWriter; - ResponseWriter.BeginArray("need"); - - for (const IoHash& Cid : OfferCids) - { - ResponseWriter.AddHash(Cid); - } - - ResponseWriter.EndArray(); - - // Emit filter response - ThisRequest.WriteResponse(HttpResponseCode::OK, ResponseWriter.Save()); - - return ThisRequest; - } - } - else if (ThisRequest.RequestContentType() == HttpContentType::kCbPackage) - { - // Process chunks in package request - - m_PackageHandler = Service.HandlePackageRequest(ThisRequest); - - // TODO: this should really be done in a streaming fashion, currently this emulates - // the intended flow from an API perspective - - if (m_PackageHandler) - { - m_PackageHandler->OnRequestBegin(); - - auto CreateBuffer = [&](const IoHash& Cid, uint64_t Size) -> IoBuffer { return m_PackageHandler->CreateTarget(Cid, Size); }; - - CbPackage Package = ParsePackageMessage(ThisRequest.ReadPayload(), CreateBuffer); - - m_PackageHandler->OnRequestComplete(); - } - } - } - // Default request handling - Service.HandleRequest(ThisRequest); + if (!HandlePackageOffers(Service, ThisRequest, m_PackageHandler)) + { + Service.HandleRequest(ThisRequest); + } return ThisRequest; } @@ -1641,12 +1607,7 @@ InitialRequestHandler::HandleCompletion(ULONG IoResult, ULONG_PTR NumberOfBytesT void HttpSysServer::Initialize(int BasePort) { - using namespace std::literals; - - WideStringBuilder<64> BaseUri; - BaseUri << u8"http://*:"sv << int64_t(BasePort) << u8"/"sv; - - Initialize(BaseUri.c_str()); + InitializeServer(BasePort); StartServer(); } |