From 876688e1aab536f5dc5af0c16aab99ad84c2c345 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 14:54:42 +0200 Subject: Fixed up bit scan logic for clang-cl --- zencore/include/zencore/intmath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zencore/include/zencore/intmath.h b/zencore/include/zencore/intmath.h index 85447c17a..814a03df4 100644 --- a/zencore/include/zencore/intmath.h +++ b/zencore/include/zencore/intmath.h @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////////// -#if ZEN_COMPILER_MSC +#if ZEN_COMPILER_MSC || ZEN_PLATFORM_WINDOWS # pragma intrinsic(_BitScanReverse) # pragma intrinsic(_BitScanReverse64) #else -- cgit v1.2.3 From f3417e09ac636f2aa487e557e8ed2b661d430120 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 14:55:25 +0200 Subject: Unsigned / signed comparison warning fixes --- zencore/compress.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zencore/compress.cpp b/zencore/compress.cpp index 55808375e..12a7b9ef8 100644 --- a/zencore/compress.cpp +++ b/zencore/compress.cpp @@ -103,7 +103,7 @@ struct BufferHeader constexpr uint64_t MethodOffset = offsetof(BufferHeader, Method); for (MemoryView View = HeaderView + MethodOffset; const uint64_t ViewSize = View.GetSize();) { - const int32_t Size = static_cast(zen::Min(ViewSize, INT_MAX)); + const int32_t Size = static_cast(zen::Min(ViewSize, /* INT_MAX */ 2147483647u)); Crc32 = zen::MemCrc32(View.GetData(), Size, Crc32); View += Size; } @@ -211,7 +211,7 @@ private: CompositeBuffer BlockEncoder::Compress(const CompositeBuffer& RawData, const uint64_t BlockSize) const { - ZEN_ASSERT(IsPow2(BlockSize) && BlockSize <= (1 << 31)); + ZEN_ASSERT(IsPow2(BlockSize) && (BlockSize <= (1u << 31))); const uint64_t RawSize = RawData.GetSize(); BLAKE3Stream RawHash; @@ -592,7 +592,7 @@ protected: const int Size = LZ4_decompress_safe(static_cast(CompressedData.GetData()), static_cast(RawData.GetData()), static_cast(CompressedData.GetSize()), - static_cast(zen::Min(RawData.GetSize(), LZ4_MAX_INPUT_SIZE))); + static_cast(zen::Min(RawData.GetSize(), uint64_t(LZ4_MAX_INPUT_SIZE)))); return static_cast(Size) == RawData.GetSize(); } return false; -- cgit v1.2.3 From 7fa42126867b0c2e87eac035179250bf51a3f5c4 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 14:56:47 +0200 Subject: Handle absence of std::source_location somewhat more gracefully (relies on client code also checking) --- zencore/except.cpp | 2 ++ zencore/include/zencore/except.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/zencore/except.cpp b/zencore/except.cpp index d57b539cd..834585522 100644 --- a/zencore/except.cpp +++ b/zencore/except.cpp @@ -40,6 +40,7 @@ GetWindowsErrorAsString(uint32_t Win32ErrorCode) return std::error_code(Win32ErrorCode, std::system_category()).message(); } +#if __cpp_lib_source_location void ThrowLastError(std::string_view Message, const std::source_location& Location) { @@ -47,5 +48,6 @@ ThrowLastError(std::string_view Message, const std::source_location& Location) throw std::system_error(std::error_code(zen::GetLastError(), std::system_category()), "{}({}): {}"_format(Location.file_name(), Location.line(), Message)); } +#endif } // namespace zen diff --git a/zencore/include/zencore/except.h b/zencore/include/zencore/except.h index 486f3e380..36cca895f 100644 --- a/zencore/include/zencore/except.h +++ b/zencore/include/zencore/except.h @@ -54,7 +54,11 @@ ZENCORE_API void ThrowSystemException(HRESULT hRes, std::string_view Message); #endif // ZEN_PLATFORM_WINDOWS ZENCORE_API void ThrowLastError(std::string_view Message); + +#if __cpp_lib_source_location ZENCORE_API void ThrowLastError(std::string_view Message, const std::source_location& Location); +#endif + ZENCORE_API std::string GetLastErrorAsString(); ZENCORE_API std::string GetWindowsErrorAsString(uint32_t Win32ErrorCode); -- cgit v1.2.3 From 02ab6e97cf6de3f21283f766a6f585d14965867c Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 14:57:03 +0200 Subject: Unused variable warning fix --- zencore/filesystem.cpp | 2 ++ zencore/uid.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/zencore/filesystem.cpp b/zencore/filesystem.cpp index 329cc241d..59300b7ad 100644 --- a/zencore/filesystem.cpp +++ b/zencore/filesystem.cpp @@ -617,6 +617,8 @@ PathFromHandle(void* NativeHandle) const DWORD FinalLength = GetFinalPathNameByHandleW(NativeHandle, FullPath.data(), RequiredLengthIncludingNul, FILE_NAME_OPENED); + ZEN_UNUSED(FinalLength); + return FullPath; } diff --git a/zencore/uid.cpp b/zencore/uid.cpp index 644d0aa77..acf9f9790 100644 --- a/zencore/uid.cpp +++ b/zencore/uid.cpp @@ -100,6 +100,7 @@ TEST_CASE("Oid") SUBCASE("Basic") { Oid id1 = Oid::NewOid(); + ZEN_UNUSED(id1); std::vector ids; std::set idset; -- cgit v1.2.3 From 07180ad240b52699a00f4edc38881bf905eabc52 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 14:57:39 +0200 Subject: Fixed up invalid fmt formatting strings --- zencore/iobuffer.cpp | 2 +- zenhttp/httpsys.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/zencore/iobuffer.cpp b/zencore/iobuffer.cpp index 14ba77ea6..758cf539c 100644 --- a/zencore/iobuffer.cpp +++ b/zencore/iobuffer.cpp @@ -220,7 +220,7 @@ IoBufferExtendedCore::Materialize() const { throw std::system_error( std::error_code(::GetLastError(), std::system_category()), - "MapViewOfFile failed (offset {#x}, size {#x}) file: '{}'"_format(MapOffset, MapSize, zen::PathFromHandle(m_FileHandle))); + "MapViewOfFile failed (offset {:#x}, size {:#x}) file: '{}'"_format(MapOffset, MapSize, zen::PathFromHandle(m_FileHandle))); } m_MappedPointer = MappedBase; diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp index e8da9cb90..00869a43b 100644 --- a/zenhttp/httpsys.cpp +++ b/zenhttp/httpsys.cpp @@ -605,7 +605,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create server session for '{}': {x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create server session for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); return; } @@ -614,7 +614,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create URL group for '{}': {x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create URL group for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); return; } @@ -625,7 +625,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to add base URL to URL group for '{}': {x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to add base URL to URL group for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); return; } @@ -640,7 +640,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create request queue for '{}': {x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create request queue for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); return; } @@ -652,7 +652,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to set server binding property for '{}': {x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to set server binding property for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); return; } -- cgit v1.2.3 From 18c112f96d7a9e033050bb83e3a523a6767e7b9f Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 15:08:49 +0200 Subject: Switched some Jupiter logging to not use `_format` - this is handled by the logging anyway so can just pass in the format string and args --- zenserver/upstream/jupiter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zenserver/upstream/jupiter.cpp b/zenserver/upstream/jupiter.cpp index 29fee1d32..0af92da6d 100644 --- a/zenserver/upstream/jupiter.cpp +++ b/zenserver/upstream/jupiter.cpp @@ -268,7 +268,7 @@ CloudCacheClient::CloudCacheClient(const CloudCacheClientOptions& Options) { if (!Options.OAuthProvider.starts_with("http://"sv) && !Options.OAuthProvider.starts_with("https://"sv)) { - ZEN_WARN("bad provider specification: '{}' - must be fully qualified"_format(Options.OAuthProvider).c_str()); + ZEN_WARN("bad provider specification: '{}' - must be fully qualified", Options.OAuthProvider); m_IsValid = false; return; -- cgit v1.2.3 From ffd45d6a5bd1e95065da71f00b6a9107b805c3ae Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 15:22:36 +0200 Subject: Made logging macros always append `sv` string_view literal suffix Fixed up the few instances of explicit string_view arguments to make sure they compile properly with the new macros --- zencore/include/zencore/logging.h | 14 ++++++++------ zencore/logging.cpp | 4 ++-- zenhttp/httpsys.cpp | 22 +++++++++++----------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/zencore/include/zencore/logging.h b/zencore/include/zencore/logging.h index eefed4efa..4996463fd 100644 --- a/zencore/include/zencore/logging.h +++ b/zencore/include/zencore/logging.h @@ -31,9 +31,11 @@ using zen::Log; // Helper macros for logging -#define ZEN_TRACE(...) Log().trace(__VA_ARGS__) -#define ZEN_DEBUG(...) Log().debug(__VA_ARGS__) -#define ZEN_INFO(...) Log().info(__VA_ARGS__) -#define ZEN_WARN(...) Log().warn(__VA_ARGS__) -#define ZEN_ERROR(...) Log().error(__VA_ARGS__) -#define ZEN_CRITICAL(...) Log().critical(__VA_ARGS__) +using namespace std::literals; + +#define ZEN_TRACE(fmtstr, ...) Log().trace(fmtstr##sv, __VA_ARGS__) +#define ZEN_DEBUG(fmtstr, ...) Log().debug(fmtstr##sv, __VA_ARGS__) +#define ZEN_INFO(fmtstr, ...) Log().info(fmtstr##sv, __VA_ARGS__) +#define ZEN_WARN(fmtstr, ...) Log().warn(fmtstr##sv, __VA_ARGS__) +#define ZEN_ERROR(fmtstr, ...) Log().error(fmtstr##sv, __VA_ARGS__) +#define ZEN_CRITICAL(fmtstr, ...) Log().critical(fmtstr##sv, __VA_ARGS__) diff --git a/zencore/logging.cpp b/zencore/logging.cpp index 9d5a726f5..00ec845b4 100644 --- a/zencore/logging.cpp +++ b/zencore/logging.cpp @@ -9,7 +9,7 @@ namespace zen { spdlog::logger& Log() { - return *spdlog::default_logger(); + return *spdlog::default_logger_raw(); } } // namespace zen @@ -19,7 +19,7 @@ namespace zen::logging { spdlog::logger& Default() { - return *spdlog::default_logger(); + return *spdlog::default_logger_raw(); } spdlog::logger& diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp index 00869a43b..8ae4fa602 100644 --- a/zenhttp/httpsys.cpp +++ b/zenhttp/httpsys.cpp @@ -554,7 +554,7 @@ HttpMessageResponseRequest::IssueRequest(std::error_code& ErrorCode) CancelThreadpoolIo(Iocp); - ZEN_ERROR("failed to send HTTP response (error: '{}'), request URL: {}"sv, SendResult, HttpReq->pRawUrl); + ZEN_ERROR("failed to send HTTP response (error: '{}'), request URL: {}", SendResult, HttpReq->pRawUrl); ErrorCode = MakeWin32ErrorCode(SendResult); } @@ -605,7 +605,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create server session for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create server session for '{}': {:#x}", WideToUtf8(UrlPath), Result); return; } @@ -614,7 +614,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create URL group for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create URL group for '{}': {:#x}", WideToUtf8(UrlPath), Result); return; } @@ -625,7 +625,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to add base URL to URL group for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to add base URL to URL group for '{}': {:#x}", WideToUtf8(UrlPath), Result); return; } @@ -640,7 +640,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to create request queue for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to create request queue for '{}': {:#x}", WideToUtf8(UrlPath), Result); return; } @@ -652,7 +652,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (Result != NO_ERROR) { - ZEN_ERROR("Failed to set server binding property for '{}': {:#x}"sv, WideToUtf8(UrlPath), Result); + ZEN_ERROR("Failed to set server binding property for '{}': {:#x}", WideToUtf8(UrlPath), Result); return; } @@ -664,7 +664,7 @@ HttpSysServer::Initialize(const wchar_t* UrlPath) if (ErrorCode) { - ZEN_ERROR("Failed to create IOCP for '{}': {}"sv, WideToUtf8(UrlPath), ErrorCode.message()); + ZEN_ERROR("Failed to create IOCP for '{}': {}", WideToUtf8(UrlPath), ErrorCode.message()); } else { @@ -803,7 +803,7 @@ HttpSysServer::RegisterService(const char* UrlPath, HttpService& Service) if (Result != NO_ERROR) { - ZEN_ERROR("HttpAddUrlToUrlGroup failed with result {}"sv, Result); + ZEN_ERROR("HttpAddUrlToUrlGroup failed with result {}", Result); return; } @@ -829,7 +829,7 @@ HttpSysServer::UnregisterService(const char* UrlPath, HttpService& Service) if (Result != NO_ERROR) { - ZEN_ERROR("HttpRemoveUrlFromUrlGroup failed with result {}"sv, Result); + ZEN_ERROR("HttpRemoveUrlFromUrlGroup failed with result {}", Result); } } @@ -917,7 +917,7 @@ HttpSysTransaction::HandleCompletion(ULONG IoResult, ULONG_PTR NumberOfBytesTran if (ErrorCode) { - ZEN_ERROR("IssueRequest() failed {}"sv, ErrorCode.message()); + ZEN_ERROR("IssueRequest() failed {}", ErrorCode.message()); } else { @@ -926,7 +926,7 @@ HttpSysTransaction::HandleCompletion(ULONG IoResult, ULONG_PTR NumberOfBytesTran } catch (std::exception& Ex) { - ZEN_ERROR("exception caught from IssueRequest(): {}"sv, Ex.what()); + ZEN_ERROR("exception caught from IssueRequest(): {}", Ex.what()); // something went wrong, no request is pending } -- cgit v1.2.3 From f34aa060d7da16d4e08644cf8572db979f3ea8d0 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 15:23:47 +0200 Subject: Changed `std::exception` into `std::runtime_error` since `std::exception` does not have a constructor which accepts a string argument in the standard (this appears to be an MSVC implementation thing) --- zen/cmds/copy.cpp | 10 +++++----- zen/cmds/deploy.cpp | 6 +++--- zenserver/compute/apply.cpp | 8 ++++---- zenserver/config.cpp | 2 +- zenserver/projectstore.cpp | 4 ++-- zenserver/testing/launch.cpp | 2 +- zenserver/zenserver.cpp | 2 +- zenstore/caslog.cpp | 2 +- zenutil/zenserverprocess.cpp | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/zen/cmds/copy.cpp b/zen/cmds/copy.cpp index 2830f8c28..4ce09c982 100644 --- a/zen/cmds/copy.cpp +++ b/zen/cmds/copy.cpp @@ -37,10 +37,10 @@ CopyCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) // Validate arguments if (m_CopySource.empty()) - throw std::exception("No source specified"); + throw std::runtime_error("No source specified"); if (m_CopyTarget.empty()) - throw std::exception("No target specified"); + throw std::runtime_error("No target specified"); std::filesystem::path FromPath; std::filesystem::path ToPath; @@ -53,12 +53,12 @@ CopyCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (!IsFileCopy && !IsDirCopy) { - throw std::exception("Invalid source specification (neither directory nor file)"); + throw std::runtime_error("Invalid source specification (neither directory nor file)"); } if (IsFileCopy && IsDirCopy) { - throw std::exception("Invalid source specification (both directory AND file!?)"); + throw std::runtime_error("Invalid source specification (both directory AND file!?)"); } if (IsDirCopy) @@ -70,7 +70,7 @@ CopyCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { if (std::filesystem::is_regular_file(ToPath)) { - throw std::exception("Attempted copy of directory into file"); + throw std::runtime_error("Attempted copy of directory into file"); } } } diff --git a/zen/cmds/deploy.cpp b/zen/cmds/deploy.cpp index bee7baf90..b8879fefb 100644 --- a/zen/cmds/deploy.cpp +++ b/zen/cmds/deploy.cpp @@ -38,10 +38,10 @@ DeployCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) // Validate arguments if (m_CopySource.empty()) - throw std::exception("No source specified"); + throw std::runtime_error("No source specified"); if (m_CopyTarget.empty()) - throw std::exception("No target specified"); + throw std::runtime_error("No target specified"); std::filesystem::path ToPath; @@ -52,7 +52,7 @@ DeployCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (!IsTargetNew && !IsTargetDir) { - throw std::exception("Invalid target specification (needs to be a directory)"); + throw std::runtime_error("Invalid target specification (needs to be a directory)"); } zen::ExtendableStringBuilder<128> Path8; diff --git a/zenserver/compute/apply.cpp b/zenserver/compute/apply.cpp index 6eeb6cf70..c3d83b2b5 100644 --- a/zenserver/compute/apply.cpp +++ b/zenserver/compute/apply.cpp @@ -114,7 +114,7 @@ BasicFunctionJob::Wait(uint32_t TimeoutMs) return true; } - throw std::exception("Failed wait on process handle"); + throw std::runtime_error("Failed wait on process handle"); } int @@ -667,7 +667,7 @@ HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action) if (!DataBuffer) { - throw std::exception("Chunk missing" /* ADD CONTEXT */); + throw std::runtime_error("Chunk missing" /* ADD CONTEXT */); } zen::WriteFile(FilePath, DataBuffer); @@ -693,7 +693,7 @@ HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action) if (!DataBuffer) { - throw std::exception("Chunk missing" /* ADD CONTEXT */); + throw std::runtime_error("Chunk missing" /* ADD CONTEXT */); } zen::WriteFile(FilePath, DataBuffer); @@ -712,7 +712,7 @@ HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action) if (!DataBuffer) { - throw std::exception("Chunk missing" /* ADD CONTEXT */); + throw std::runtime_error("Chunk missing" /* ADD CONTEXT */); } zen::WriteFile(FilePath, DataBuffer); diff --git a/zenserver/config.cpp b/zenserver/config.cpp index ae624b169..578a3a202 100644 --- a/zenserver/config.cpp +++ b/zenserver/config.cpp @@ -242,7 +242,7 @@ ParseServiceConfig(const std::filesystem::path& DataRoot, ZenServiceConfig& Serv { ZEN_ERROR("config script failure: {}", e.what()); - throw std::exception("fatal zen global config script ({}) failure: {}"_format(ConfigScript, e.what()).c_str()); + throw std::runtime_error("fatal zen global config script ({}) failure: {}"_format(ConfigScript, e.what()).c_str()); } ServiceConfig.MeshEnabled = lua["mesh"]["enable"].get_or(ServiceConfig.MeshEnabled); diff --git a/zenserver/projectstore.cpp b/zenserver/projectstore.cpp index 79cd250dc..404484edf 100644 --- a/zenserver/projectstore.cpp +++ b/zenserver/projectstore.cpp @@ -142,14 +142,14 @@ struct ProjectStore::OplogStorage : public RefCounted } else { - throw std::exception("column family iteration failed for '{}': '{}'"_format(RocksdbPath, Status.getState()).c_str()); + throw std::runtime_error("column family iteration failed for '{}': '{}'"_format(RocksdbPath, Status.getState()).c_str()); } Status = rocksdb::DB::Open(Options, RocksdbPath, ColumnDescriptors, &m_RocksDbColumnHandles, &Db); if (!Status.ok()) { - throw std::exception("database open failed for '{}': '{}'"_format(RocksdbPath, Status.getState()).c_str()); + throw std::runtime_error("database open failed for '{}': '{}'"_format(RocksdbPath, Status.getState()).c_str()); } m_RocksDb.reset(Db); diff --git a/zenserver/testing/launch.cpp b/zenserver/testing/launch.cpp index 608b515e1..55695ac9c 100644 --- a/zenserver/testing/launch.cpp +++ b/zenserver/testing/launch.cpp @@ -105,7 +105,7 @@ BasicJob::Wait(uint32_t TimeoutMs) return true; } - throw std::exception("Failed wait on process handle"); + throw std::runtime_error("Failed wait on process handle"); } int diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp index 931fe062e..3b56d8683 100644 --- a/zenserver/zenserver.cpp +++ b/zenserver/zenserver.cpp @@ -112,7 +112,7 @@ public: if (zen::NamedMutex::Exists(MutexName) || (m_ServerMutex.Create(MutexName) == false)) { - throw std::exception("Failed to create mutex '{}' - is another instance already running?"_format(MutexName).c_str()); + throw std::runtime_error("Failed to create mutex '{}' - is another instance already running?"_format(MutexName).c_str()); } // Ok so now we're configured, let's kick things off diff --git a/zenstore/caslog.cpp b/zenstore/caslog.cpp index 34860538a..70bcf4669 100644 --- a/zenstore/caslog.cpp +++ b/zenstore/caslog.cpp @@ -81,7 +81,7 @@ CasLogFile::Open(std::filesystem::path FileName, size_t RecordSize, bool IsCreat if ((0 != memcmp(Header.Magic, FileHeader::MagicSequence, sizeof Header.Magic)) || (Header.Checksum != Header.ComputeChecksum())) { // TODO: provide more context! - throw std::exception("Mangled log header"); + throw std::runtime_error("Mangled log header"); } ULONGLONG Sz; diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp index 3d8f33559..00f5d4c0d 100644 --- a/zenutil/zenserverprocess.cpp +++ b/zenutil/zenserverprocess.cpp @@ -524,7 +524,7 @@ ZenServerInstance::AttachToRunningServer(int BasePort) if (!State.InitializeReadOnly()) { // TODO: return success/error code instead? - throw std::exception("No zen state found"); + throw std::runtime_error("No zen state found"); } const ZenServerState::ZenServerEntry* Entry = nullptr; @@ -541,7 +541,7 @@ ZenServerInstance::AttachToRunningServer(int BasePort) if (!Entry) { // TODO: return success/error code instead? - throw std::exception("No server found"); + throw std::runtime_error("No server found"); } m_Process.Initialize(Entry->Pid); -- cgit v1.2.3 From 2fc15e320c934424bc03601551f34f26a38e40a3 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 16:17:22 +0200 Subject: Tweaked logging to streamline access, and simplified setup code for new loggers --- zencore/include/zencore/logging.h | 10 +++++++++- zencore/logging.cpp | 24 +++++++++++++----------- zenserver/diag/logging.cpp | 15 +++++++++------ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/zencore/include/zencore/logging.h b/zencore/include/zencore/logging.h index 4996463fd..4eee20414 100644 --- a/zencore/include/zencore/logging.h +++ b/zencore/include/zencore/logging.h @@ -13,6 +13,7 @@ namespace zen::logging { spdlog::logger& Default(); +void SetDefault(std::shared_ptr NewDefaultLogger); spdlog::logger& ConsoleLog(); spdlog::logger& Get(std::string_view Name); @@ -22,7 +23,14 @@ void ShutdownLogging(); } // namespace zen::logging namespace zen { -spdlog::logger& Log(); +extern spdlog::logger* TheDefaultLogger; + +inline spdlog::logger& +Log() +{ + return *TheDefaultLogger; +} + using logging::ConsoleLog; } // namespace zen diff --git a/zencore/logging.cpp b/zencore/logging.cpp index 00ec845b4..c5c0b6446 100644 --- a/zencore/logging.cpp +++ b/zencore/logging.cpp @@ -6,11 +6,8 @@ namespace zen { -spdlog::logger& -Log() -{ - return *spdlog::default_logger_raw(); -} +// We shadow the underlying spdlog default logger, in order to avoid a bunch of overhead +spdlog::logger* TheDefaultLogger; } // namespace zen @@ -19,20 +16,24 @@ namespace zen::logging { spdlog::logger& Default() { - return *spdlog::default_logger_raw(); + return *TheDefaultLogger; +} + +void +SetDefault(std::shared_ptr NewDefaultLogger) +{ + spdlog::set_default_logger(NewDefaultLogger); + TheDefaultLogger = spdlog::default_logger_raw(); } spdlog::logger& Get(std::string_view Name) { std::shared_ptr Logger = spdlog::get(std::string(Name)); + if (!Logger) { - Logger = std::make_shared(std::string(Name), - begin(spdlog::default_logger()->sinks()), - end(spdlog::default_logger()->sinks())); - - Logger->set_level(spdlog::default_logger()->level()); + Logger = Default().clone(std::string(Name)); spdlog::register_logger(Logger); } @@ -57,6 +58,7 @@ ConsoleLog() void InitializeLogging() { + TheDefaultLogger = spdlog::default_logger_raw(); } void diff --git a/zenserver/diag/logging.cpp b/zenserver/diag/logging.cpp index 5782ce582..48eda7512 100644 --- a/zenserver/diag/logging.cpp +++ b/zenserver/diag/logging.cpp @@ -211,7 +211,7 @@ InitializeLogging(const ZenServerOptions& GlobalOptions) spdlog::init_thread_pool(QueueSize, ThreadCount); auto AsyncLogger = spdlog::create_async("main"); - spdlog::set_default_logger(AsyncLogger); + zen::logging::SetDefault(AsyncLogger); } // Sinks @@ -220,16 +220,16 @@ InitializeLogging(const ZenServerOptions& GlobalOptions) auto FileSink = std::make_shared(zen::WideToUtf8(LogPath.c_str()), /* truncate */ true); // Default - auto DefaultLogger = spdlog::default_logger(); - auto& Sinks = spdlog::default_logger()->sinks(); - Sinks.clear(); + auto& DefaultLogger = zen::logging::Default(); + auto& Sinks = DefaultLogger.sinks(); + + Sinks.clear(); Sinks.push_back(ConsoleSink); Sinks.push_back(FileSink); - DefaultLogger->set_level(LogLevel); - DefaultLogger->flush_on(spdlog::level::err); // Jupiter - only log HTTP traffic to file + auto JupiterLogger = std::make_shared("jupiter", FileSink); spdlog::register_logger(JupiterLogger); JupiterLogger->set_level(LogLevel); @@ -238,7 +238,10 @@ InitializeLogging(const ZenServerOptions& GlobalOptions) spdlog::register_logger(ZenClientLogger); ZenClientLogger->set_level(LogLevel); + // Configure all registered loggers according to settings + spdlog::set_level(LogLevel); + spdlog::flush_on(spdlog::level::err); spdlog::set_formatter(std::make_unique(GlobalOptions.LogId, std::chrono::system_clock::now())); } -- cgit v1.2.3 From 802a3b8462a8e695c612b4cc390534ec0dbc1522 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 17:33:04 +0200 Subject: Corrected logic error in ValidateCbPackageAttachment() --- zencore/compactbinaryvalidation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zencore/compactbinaryvalidation.cpp b/zencore/compactbinaryvalidation.cpp index 316da76a6..dafd1bcc8 100644 --- a/zencore/compactbinaryvalidation.cpp +++ b/zencore/compactbinaryvalidation.cpp @@ -418,7 +418,7 @@ ValidateCbPackageAttachment(CbFieldView& Value, MemoryView& View, CbValidateMode { if (const CbObjectView ObjectView = Value.AsObjectView(); !Value.HasError()) { - return CbObject().GetHash(); + return ObjectView.GetHash(); } if (const IoHash ObjectAttachmentHash = Value.AsObjectAttachment(); !Value.HasError()) -- cgit v1.2.3 From 5f53b41dd7438906a43fb8ebf6984efe89862970 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 17:33:33 +0200 Subject: Fixed logging.h so it doesn't leak `using namespace std::literals` declaration --- zencore/include/zencore/logging.h | 49 ++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/zencore/include/zencore/logging.h b/zencore/include/zencore/logging.h index 4eee20414..8e6b3a244 100644 --- a/zencore/include/zencore/logging.h +++ b/zencore/include/zencore/logging.h @@ -39,11 +39,44 @@ using zen::Log; // Helper macros for logging -using namespace std::literals; - -#define ZEN_TRACE(fmtstr, ...) Log().trace(fmtstr##sv, __VA_ARGS__) -#define ZEN_DEBUG(fmtstr, ...) Log().debug(fmtstr##sv, __VA_ARGS__) -#define ZEN_INFO(fmtstr, ...) Log().info(fmtstr##sv, __VA_ARGS__) -#define ZEN_WARN(fmtstr, ...) Log().warn(fmtstr##sv, __VA_ARGS__) -#define ZEN_ERROR(fmtstr, ...) Log().error(fmtstr##sv, __VA_ARGS__) -#define ZEN_CRITICAL(fmtstr, ...) Log().critical(fmtstr##sv, __VA_ARGS__) +#define ZEN_TRACE(fmtstr, ...) \ + do \ + { \ + using namespace std::literals; \ + Log().trace(fmtstr##sv, __VA_ARGS__); \ + } while (false) + +#define ZEN_DEBUG(fmtstr, ...) \ + do \ + { \ + using namespace std::literals; \ + Log().debug(fmtstr##sv, __VA_ARGS__); \ + } while (false) + +#define ZEN_INFO(fmtstr, ...) \ + do \ + { \ + using namespace std::literals; \ + Log().info(fmtstr##sv, __VA_ARGS__); \ + } while (false) + +#define ZEN_WARN(fmtstr, ...) \ + do \ + { \ + using namespace std::literals; \ + Log().warn(fmtstr##sv, __VA_ARGS__); \ + } while (false) + +#define ZEN_ERROR(fmtstr, ...) \ + do \ + { \ + using namespace std::literals; \ + Log().error(fmtstr##sv, __VA_ARGS__); \ + } while (false) + +#define ZEN_CRITICAL(fmtstr, ...) \ + do \ + { \ + using namespace std::literals; \ + Log().critical(fmtstr##sv, __VA_ARGS__); \ + } while (false) -- cgit v1.2.3 From 9443c3a44741b192e4c57cb1157fbd260974fd10 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 19:46:34 +0200 Subject: Added GetSize/GetData functions to reduce cognitive load and bridge the gap between UE-style accessors and c++ style accessors --- zencore/include/zencore/iobuffer.h | 2 ++ zencore/include/zencore/stream.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/zencore/include/zencore/iobuffer.h b/zencore/include/zencore/iobuffer.h index 034c3566f..28772e219 100644 --- a/zencore/include/zencore/iobuffer.h +++ b/zencore/include/zencore/iobuffer.h @@ -321,7 +321,9 @@ public: [[nodiscard]] void* MutableData() const { return m_Core->MutableDataPointer(); } void MakeImmutable() { m_Core->SetIsImmutable(true); } [[nodiscard]] const void* Data() const { return m_Core->DataPointer(); } + [[nodiscard]] const void* GetData() const { return m_Core->DataPointer(); } [[nodiscard]] size_t Size() const { return m_Core->DataBytes(); } + [[nodiscard]] size_t GetSize() const { return m_Core->DataBytes(); } inline void SetContentType(ZenContentType ContentType) { m_Core->SetContentType(ContentType); } [[nodiscard]] inline ZenContentType GetContentType() const { return m_Core->GetContentType(); } [[nodiscard]] ZENCORE_API bool GetFileReference(IoBufferFileReference& OutRef) const; diff --git a/zencore/include/zencore/stream.h b/zencore/include/zencore/stream.h index 4e8c58382..a0e165bdc 100644 --- a/zencore/include/zencore/stream.h +++ b/zencore/include/zencore/stream.h @@ -36,6 +36,7 @@ class InStream : public RefCounted public: virtual void Read(void* DataPtr, size_t ByteCount, uint64_t Offset) = 0; virtual uint64_t Size() const = 0; + uint64_t GetSize() const { return Size(); } }; /** @@ -50,7 +51,9 @@ public: virtual void Write(const void* DataPtr, size_t ByteCount, uint64_t Offset) override; virtual void Flush() override; inline const uint8_t* Data() const { return m_Buffer.data(); } + inline const uint8_t* GetData() const { return m_Buffer.data(); } inline uint64_t Size() const { return m_Buffer.size(); } + inline uint64_t GetSize() const { return m_Buffer.size(); } private: RwLock m_Lock; @@ -76,6 +79,7 @@ public: virtual void Read(void* DataPtr, size_t ByteCount, uint64_t ReadOffset) override; virtual uint64_t Size() const override { return m_Buffer.size(); } inline const uint8_t* Data() const { return m_Buffer.data(); } + inline const uint8_t* GetData() const { return m_Buffer.data(); } private: RwLock m_Lock; -- cgit v1.2.3 From 681721f66359e90ee0e5d8967f6195230e361e5d Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 21:30:56 +0200 Subject: Added explicit logging initialization to main() of standalone executables, to make things work with the new default logger shadowing changes --- zen/zen.cpp | 2 ++ zencore-test/zencore-test.cpp | 4 +++- zenserver-test/zenserver-test.cpp | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/zen/zen.cpp b/zen/zen.cpp index 4b8d3adc1..d8bfa13e5 100644 --- a/zen/zen.cpp +++ b/zen/zen.cpp @@ -96,6 +96,8 @@ main(int argc, char** argv) { mi_version(); + zen::logging::InitializeLogging(); + #if TEST_UWS /* Overly simple hello world app, using multiple threads */ std::vector threads(4); diff --git a/zencore-test/zencore-test.cpp b/zencore-test/zencore-test.cpp index 8c53cf349..1782f1926 100644 --- a/zencore-test/zencore-test.cpp +++ b/zencore-test/zencore-test.cpp @@ -1,8 +1,8 @@ // zencore-test.cpp : Defines the entry point for the console application. // -#include #include +#include #define DOCTEST_CONFIG_IMPLEMENT #include @@ -17,5 +17,7 @@ forceLinkTests() int main(int argc, char* argv[]) { + zen::logging::InitializeLogging(); + return doctest::Context(argc, argv).run(); } diff --git a/zenserver-test/zenserver-test.cpp b/zenserver-test/zenserver-test.cpp index df17cc353..1ae3f39fa 100644 --- a/zenserver-test/zenserver-test.cpp +++ b/zenserver-test/zenserver-test.cpp @@ -659,6 +659,8 @@ main(int argc, char** argv) zencore_forcelinktests(); + zen::logging::InitializeLogging(); + spdlog::set_level(spdlog::level::debug); spdlog::set_formatter(std::make_unique("test", std::chrono::system_clock::now())); -- cgit v1.2.3 From d29b3ccba64944c9aa2ec3d08079170d47f9c4db Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 21:31:39 +0200 Subject: Added more context to missing chunk exceptions --- zenserver/compute/apply.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/zenserver/compute/apply.cpp b/zenserver/compute/apply.cpp index c3d83b2b5..7b76bb80b 100644 --- a/zenserver/compute/apply.cpp +++ b/zenserver/compute/apply.cpp @@ -647,6 +647,7 @@ CbPackage HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action) { using namespace std::literals; + using namespace fmt::literals; std::filesystem::path SandboxPath = CreateNewSandbox(); @@ -667,7 +668,7 @@ HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action) if (!DataBuffer) { - throw std::runtime_error("Chunk missing" /* ADD CONTEXT */); + throw std::runtime_error("worker CAS chunk '{}' missing"_format(Hash)); } zen::WriteFile(FilePath, DataBuffer); @@ -693,7 +694,7 @@ HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action) if (!DataBuffer) { - throw std::runtime_error("Chunk missing" /* ADD CONTEXT */); + throw std::runtime_error("worker CAS chunk '{}' missing"_format(Hash)); } zen::WriteFile(FilePath, DataBuffer); @@ -712,7 +713,7 @@ HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action) if (!DataBuffer) { - throw std::runtime_error("Chunk missing" /* ADD CONTEXT */); + throw std::runtime_error("input CID chunk '{}' missing"_format(Cid)); } zen::WriteFile(FilePath, DataBuffer); -- cgit v1.2.3 From 226233d813c96877669cf643c343ea0bfe0d4ba6 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 21:32:08 +0200 Subject: Added some more trace-level logging --- zenhttp/httpsys.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp index 8ae4fa602..4536d0ed9 100644 --- a/zenhttp/httpsys.cpp +++ b/zenhttp/httpsys.cpp @@ -980,14 +980,20 @@ HttpSysTransaction::InvokeRequestHandler(HttpService& Service, IoBuffer Payload) { // Should yield bad request response? + ZEN_WARN("found invalid entry in offer"); + continue; } - OfferCids.push_back(CidEntry.AsHash(IoHash::Zero)); + 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"); -- cgit v1.2.3 From 2f28b9bee4da0ddebe0f6de9419e3b3f80ca0911 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 21:39:53 +0200 Subject: Added session id generation and code to include it in HttpClient HTTP requests --- zencore/include/zencore/session.h | 11 +++++++++++ zencore/session.cpp | 21 +++++++++++++++++++++ zencore/zencore.vcxproj | 5 +++++ zencore/zencore.vcxproj.filters | 5 +++++ zenhttp/httpclient.cpp | 10 ++++++---- zenhttp/include/zenhttp/httpclient.h | 2 ++ 6 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 zencore/include/zencore/session.h create mode 100644 zencore/session.cpp diff --git a/zencore/include/zencore/session.h b/zencore/include/zencore/session.h new file mode 100644 index 000000000..e66794704 --- /dev/null +++ b/zencore/include/zencore/session.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace zen { + +struct Oid; + +ZENCORE_API Oid GetSessionId(); + +} diff --git a/zencore/session.cpp b/zencore/session.cpp new file mode 100644 index 000000000..195a9d97c --- /dev/null +++ b/zencore/session.cpp @@ -0,0 +1,21 @@ +#include "zencore/session.h" + +#include + +#include + +namespace zen { + +static Oid GlobalSessionId; +static std::once_flag SessionInitFlag; + +Oid GetSessionId() +{ + std::call_once(SessionInitFlag, [&] { + GlobalSessionId.Generate(); + }); + + return GlobalSessionId; +} + +} \ No newline at end of file diff --git a/zencore/zencore.vcxproj b/zencore/zencore.vcxproj index 4f1e63670..150c42cd6 100644 --- a/zencore/zencore.vcxproj +++ b/zencore/zencore.vcxproj @@ -132,6 +132,7 @@ + @@ -166,6 +167,7 @@ + MaxSpeed AnySuitable @@ -189,6 +191,9 @@ + + + diff --git a/zencore/zencore.vcxproj.filters b/zencore/zencore.vcxproj.filters index de3d915b8..ea0f8a912 100644 --- a/zencore/zencore.vcxproj.filters +++ b/zencore/zencore.vcxproj.filters @@ -41,6 +41,7 @@ + @@ -72,10 +73,14 @@ + {af5266fa-37a5-494c-9116-b15a3e6edd29} + + + \ No newline at end of file diff --git a/zenhttp/httpclient.cpp b/zenhttp/httpclient.cpp index b7df12026..78ecef2c0 100644 --- a/zenhttp/httpclient.cpp +++ b/zenhttp/httpclient.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,9 @@ FromCprResponse(cpr::Response& InResponse) HttpClient::HttpClient(std::string_view BaseUri) : m_BaseUri(BaseUri) { + StringBuilder<32> SessionId; + GetSessionId().ToString(SessionId); + m_SessionId = SessionId; } HttpClient::~HttpClient() @@ -68,8 +72,7 @@ HttpClient::TransactPackage(std::string_view Url, CbPackage Package) BinaryWriter MemWriter(MemOut); Writer.Save(MemWriter); - Sess.SetHeader( - {{"Content-Type", "application/x-ue-offer"}, {"UE-Session", "123456789012345678901234"}, {"UE-Request", RequestIdString}}); + Sess.SetHeader({{"Content-Type", "application/x-ue-offer"}, {"UE-Session", m_SessionId}, {"UE-Request", RequestIdString}}); Sess.SetBody(cpr::Body{(const char*)MemOut.Data(), MemOut.Size()}); cpr::Response FilterResponse = Sess.Post(); @@ -111,8 +114,7 @@ HttpClient::TransactPackage(std::string_view Url, CbPackage Package) CompositeBuffer Message = FormatPackageMessageBuffer(SendPackage); SharedBuffer FlatMessage = Message.Flatten(); - Sess.SetHeader( - {{"Content-Type", "application/x-ue-cbpkg"}, {"UE-Session", "123456789012345678901234"}, {"UE-Request", RequestIdString}}); + Sess.SetHeader({{"Content-Type", "application/x-ue-cbpkg"}, {"UE-Session", m_SessionId}, {"UE-Request", RequestIdString}}); Sess.SetBody(cpr::Body{(const char*)FlatMessage.GetData(), FlatMessage.GetSize()}); cpr::Response FilterResponse = Sess.Post(); diff --git a/zenhttp/include/zenhttp/httpclient.h b/zenhttp/include/zenhttp/httpclient.h index 8975f6fe1..c3bdf0506 100644 --- a/zenhttp/include/zenhttp/httpclient.h +++ b/zenhttp/include/zenhttp/httpclient.h @@ -5,6 +5,7 @@ #include "zenhttp.h" #include +#include #include #include @@ -41,6 +42,7 @@ public: private: std::string m_BaseUri; + std::string m_SessionId; }; } // namespace zen -- cgit v1.2.3 From 629462da1a74c760b966f30a3f0e038b1ad270bb Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 22:12:08 +0200 Subject: Made ZenContentType enum members have fixed value (for persistence), and added kCOUNT for iteration over the members --- zencore/include/zencore/iobuffer.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/zencore/include/zencore/iobuffer.h b/zencore/include/zencore/iobuffer.h index 28772e219..c3860f2b0 100644 --- a/zencore/include/zencore/iobuffer.h +++ b/zencore/include/zencore/iobuffer.h @@ -13,14 +13,16 @@ struct IoBufferExtendedCore; enum class ZenContentType : uint8_t { - kBinary, // Note that since this is zero, this will be the default value in IoBuffer - kText, - kJSON, - kCbObject, - kCbPackage, - kYAML, - kCbPackageOffer, - kUnknownContentType + kBinary = 0, // Note that since this is zero, this will be the default value in IoBuffer + kText = 1, + kJSON = 2, + kCbObject = 3, + kCbPackage = 4, + kYAML = 5, + kCbPackageOffer = 6, + kCompressedBinary = 7, + kUnknownContentType = 8, + kCOUNT }; struct IoBufferFileReference -- cgit v1.2.3 From d47dfe0c63d04348b0646567df4a2a4ae7b7732f Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 22:25:27 +0200 Subject: Added support for compressed binary MIME type conversion --- zenhttp/httpserver.cpp | 99 +++++++++++++++++++++++------------- zenhttp/include/zenhttp/httpcommon.h | 4 +- 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/zenhttp/httpserver.cpp b/zenhttp/httpserver.cpp index f97ac0067..5b5738fc4 100644 --- a/zenhttp/httpserver.cpp +++ b/zenhttp/httpserver.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -53,59 +54,81 @@ MapContentTypeToString(HttpContentType ContentType) case HttpContentType::kCbPackageOffer: return "application/x-ue-offer"sv; + case HttpContentType::kCompressedBinary: + return "application/x-ue-comp"sv; + case HttpContentType::kYAML: return "text/yaml"sv; } } -static const uint32_t HashBinary = HashStringDjb2("application/octet-stream"sv); -static const uint32_t HashJson = HashStringDjb2("application/json"sv); -static const uint32_t HashYaml = HashStringDjb2("text/yaml"sv); -static const uint32_t HashText = HashStringDjb2("text/plain"sv); -static const uint32_t HashCompactBinary = HashStringDjb2("application/x-ue-cb"sv); -static const uint32_t HashCompactBinaryPackage = HashStringDjb2("application/x-ue-cbpkg"sv); -static const uint32_t HashCompactBinaryPackageOffer = HashStringDjb2("application/x-ue-offer"sv); +////////////////////////////////////////////////////////////////////////// + +static constinit uint32_t HashBinary = HashStringDjb2("application/octet-stream"sv); +static constinit uint32_t HashJson = HashStringDjb2("application/json"sv); +static constinit uint32_t HashYaml = HashStringDjb2("text/yaml"sv); +static constinit uint32_t HashText = HashStringDjb2("text/plain"sv); +static constinit uint32_t HashCompactBinary = HashStringDjb2("application/x-ue-cb"sv); +static constinit uint32_t HashCompactBinaryPackage = HashStringDjb2("application/x-ue-cbpkg"sv); +static constinit uint32_t HashCompactBinaryPackageOffer = HashStringDjb2("application/x-ue-offer"sv); +static constinit uint32_t HashCompressedBinary = HashStringDjb2("application/x-ue-comp"sv); + +std::once_flag InitContentTypeLookup; + +struct HashedTypeEntry +{ + uint32_t Hash; + HttpContentType Type; +} TypeHashTable[] = {{HashBinary, HttpContentType::kBinary}, + {HashCompactBinary, HttpContentType::kCbObject}, + {HashCompactBinaryPackage, HttpContentType::kCbPackage}, + {HashCompactBinaryPackageOffer, HttpContentType::kCbPackageOffer}, + {HashJson, HttpContentType::kJSON}, + {HashYaml, HttpContentType::kYAML}, + {HashText, HttpContentType::kText}, + {HashCompressedBinary, HttpContentType::kCompressedBinary}}; HttpContentType -ParseContentType(const std::string_view& ContentTypeString) +ParseContentTypeImpl(const std::string_view& ContentTypeString) { if (!ContentTypeString.empty()) { const uint32_t CtHash = HashStringDjb2(ContentTypeString); - if (CtHash == HashBinary) - { - return HttpContentType::kBinary; - } - else if (CtHash == HashCompactBinary) - { - return HttpContentType::kCbObject; - } - else if (CtHash == HashCompactBinaryPackage) - { - return HttpContentType::kCbPackage; - } - else if (CtHash == HashCompactBinaryPackageOffer) - { - return HttpContentType::kCbPackageOffer; - } - else if (CtHash == HashJson) - { - return HttpContentType::kJSON; - } - else if (CtHash == HashYaml) - { - return HttpContentType::kYAML; - } - else if (CtHash == HashText) + if (auto It = std::lower_bound(std::begin(TypeHashTable), + std::end(TypeHashTable), + CtHash, + [](const HashedTypeEntry& Lhs, const uint32_t Rhs) { return Lhs.Hash < Rhs; }); + It != std::end(TypeHashTable)) { - return HttpContentType::kText; + if (It->Hash == CtHash) + { + return It->Type; + } } } return HttpContentType::kUnknownContentType; } +HttpContentType +ParseContentTypeInit(const std::string_view& ContentTypeString) +{ + std::call_once(InitContentTypeLookup, [] { + std::sort(std::begin(TypeHashTable), std::end(TypeHashTable), [](const HashedTypeEntry& Lhs, const HashedTypeEntry& Rhs) { + return Lhs.Hash < Rhs.Hash; + }); + }); + + ParseContentType = ParseContentTypeImpl; + + return ParseContentTypeImpl(ContentTypeString); +} + +HttpContentType (*ParseContentType)(const std::string_view& ContentTypeString) = &ParseContentTypeInit; + +////////////////////////////////////////////////////////////////////////// + const char* ReasonStringForHttpResultCode(int HttpCode) { @@ -523,6 +546,14 @@ TEST_CASE("http") // TestHttpServerRequest req{}; // r.HandleRequest(req); } + + SUBCASE("content-type") + { + for (uint8_t i = 0; i < uint8_t(HttpContentType::kCOUNT); ++i) + { + CHECK_EQ(HttpContentType(i), ParseContentType(MapContentTypeToString(HttpContentType(i)))); + } + } } void diff --git a/zenhttp/include/zenhttp/httpcommon.h b/zenhttp/include/zenhttp/httpcommon.h index 41ec706f4..08f1b47a9 100644 --- a/zenhttp/include/zenhttp/httpcommon.h +++ b/zenhttp/include/zenhttp/httpcommon.h @@ -18,8 +18,8 @@ class CbPackage; class StringBuilderBase; std::string_view MapContentTypeToString(HttpContentType ContentType); -HttpContentType ParseContentType(const std::string_view& ContentTypeString); -const char* ReasonStringForHttpResultCode(int HttpCode); +extern HttpContentType (*ParseContentType)(const std::string_view& ContentTypeString); +const char* ReasonStringForHttpResultCode(int HttpCode); [[nodiscard]] inline bool IsHttpSuccessCode(int HttpCode) -- cgit v1.2.3 From 645937ef98513fce77c68014e7ebb4088ba5d08b Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 22:26:18 +0200 Subject: Adde reminder that the content type is embedded in the IoBuffer --- zenhttp/include/zenhttp/httpclient.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zenhttp/include/zenhttp/httpclient.h b/zenhttp/include/zenhttp/httpclient.h index c3bdf0506..7d9db7198 100644 --- a/zenhttp/include/zenhttp/httpclient.h +++ b/zenhttp/include/zenhttp/httpclient.h @@ -34,7 +34,7 @@ public: struct Response { int StatusCode = 0; - IoBuffer ResponsePayload; + IoBuffer ResponsePayload; // Note: this also includes the content type }; [[nodiscard]] Response TransactPackage(std::string_view Url, CbPackage Package); -- cgit v1.2.3 From 8f889ca565f16f41420b5e9555d6479d6dddd725 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 22:44:32 +0200 Subject: Hooked up zenhttp to the test framework so tests actually run as part of zenserver-test --- zenhttp/httpserver.cpp | 9 +++++++-- zenhttp/include/zenhttp/httpserver.h | 4 ++-- zenhttp/include/zenhttp/zenhttp.h | 6 ++++++ zenhttp/zenhttp.cpp | 13 +++++++++++++ zenhttp/zenhttp.vcxproj | 1 + zenhttp/zenhttp.vcxproj.filters | 1 + zenserver-test/zenserver-test.cpp | 2 ++ 7 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 zenhttp/zenhttp.cpp diff --git a/zenhttp/httpserver.cpp b/zenhttp/httpserver.cpp index 5b5738fc4..f4a5f4345 100644 --- a/zenhttp/httpserver.cpp +++ b/zenhttp/httpserver.cpp @@ -525,7 +525,7 @@ CreateHttpServer() ////////////////////////////////////////////////////////////////////////// -TEST_CASE("http") +TEST_CASE("http.common") { using namespace std::literals; @@ -551,7 +551,12 @@ TEST_CASE("http") { for (uint8_t i = 0; i < uint8_t(HttpContentType::kCOUNT); ++i) { - CHECK_EQ(HttpContentType(i), ParseContentType(MapContentTypeToString(HttpContentType(i)))); + HttpContentType Ct{i}; + + if (Ct != HttpContentType::kUnknownContentType) + { + CHECK_EQ(Ct, ParseContentType(MapContentTypeToString(Ct))); + } } } } diff --git a/zenhttp/include/zenhttp/httpserver.h b/zenhttp/include/zenhttp/httpserver.h index de097ceb3..f656c69a8 100644 --- a/zenhttp/include/zenhttp/httpserver.h +++ b/zenhttp/include/zenhttp/httpserver.h @@ -268,6 +268,6 @@ private: std::unordered_map m_PatternMap; }; -} // namespace zen - void http_forcelink(); // internal + +} // namespace zen diff --git a/zenhttp/include/zenhttp/zenhttp.h b/zenhttp/include/zenhttp/zenhttp.h index c6ec92e7c..586fc98b4 100644 --- a/zenhttp/include/zenhttp/zenhttp.h +++ b/zenhttp/include/zenhttp/zenhttp.h @@ -5,3 +5,9 @@ #include #define ZENHTTP_API // Placeholder to allow DLL configs in the future + +namespace zen { + + ZENHTTP_API void zenhttp_forcelinktests(); + +} diff --git a/zenhttp/zenhttp.cpp b/zenhttp/zenhttp.cpp new file mode 100644 index 000000000..148cf4499 --- /dev/null +++ b/zenhttp/zenhttp.cpp @@ -0,0 +1,13 @@ +#include + +#include + +namespace zen { + +void +zenhttp_forcelinktests() +{ + http_forcelink(); +} + +} \ No newline at end of file diff --git a/zenhttp/zenhttp.vcxproj b/zenhttp/zenhttp.vcxproj index 3536d1929..eca9898d3 100644 --- a/zenhttp/zenhttp.vcxproj +++ b/zenhttp/zenhttp.vcxproj @@ -100,6 +100,7 @@ + diff --git a/zenhttp/zenhttp.vcxproj.filters b/zenhttp/zenhttp.vcxproj.filters index da292c18f..17f71bed1 100644 --- a/zenhttp/zenhttp.vcxproj.filters +++ b/zenhttp/zenhttp.vcxproj.filters @@ -8,6 +8,7 @@ + diff --git a/zenserver-test/zenserver-test.cpp b/zenserver-test/zenserver-test.cpp index 1ae3f39fa..213648319 100644 --- a/zenserver-test/zenserver-test.cpp +++ b/zenserver-test/zenserver-test.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -658,6 +659,7 @@ main(int argc, char** argv) mi_version(); zencore_forcelinktests(); + zen::zenhttp_forcelinktests(); zen::logging::InitializeLogging(); -- cgit v1.2.3 From 8bc12a6228c15f920b48dbf5bc146ea5ed33b5f4 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 15 Sep 2021 22:45:09 +0200 Subject: Added some placeholder HttpClient functions to be fleshed out --- zenhttp/httpclient.cpp | 15 +++++++++++++++ zenhttp/include/zenhttp/httpclient.h | 6 +++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/zenhttp/httpclient.cpp b/zenhttp/httpclient.cpp index 78ecef2c0..7e3e9d374 100644 --- a/zenhttp/httpclient.cpp +++ b/zenhttp/httpclient.cpp @@ -136,6 +136,21 @@ HttpClient::TransactPackage(std::string_view Url, CbPackage Package) return {.StatusCode = FilterResponse.status_code, .ResponsePayload = ResponseBuffer}; } +HttpClient::Response +HttpClient::Put(std::string_view Url, IoBuffer Payload) +{ + ZEN_UNUSED(Url); + ZEN_UNUSED(Payload); + return {}; +} + +HttpClient::Response +HttpClient::Get(std::string_view Url) +{ + ZEN_UNUSED(Url); + return {}; +} + HttpClient::Response HttpClient::Delete(std::string_view Url) { diff --git a/zenhttp/include/zenhttp/httpclient.h b/zenhttp/include/zenhttp/httpclient.h index 7d9db7198..3e342f2bd 100644 --- a/zenhttp/include/zenhttp/httpclient.h +++ b/zenhttp/include/zenhttp/httpclient.h @@ -23,7 +23,9 @@ namespace zen { class CbPackage; -/** Asynchronous HTTP client implementation for Zen use cases +/** HTTP client implementation for Zen use cases + + Currently simple and synchronous, should become lean and asynchronous */ class HttpClient { @@ -37,6 +39,8 @@ public: IoBuffer ResponsePayload; // Note: this also includes the content type }; + [[nodiscard]] Response Put(std::string_view Url, IoBuffer Payload); + [[nodiscard]] Response Get(std::string_view Url); [[nodiscard]] Response TransactPackage(std::string_view Url, CbPackage Package); [[nodiscard]] Response Delete(std::string_view Url); -- cgit v1.2.3