diff --git a/.gitignore b/.gitignore index e71c30a..6794cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /CCEngine/CCEngine.aps /CCEngine/build/ /CCEngineLoader/build/ +/out/ diff --git a/CCEngine.sln b/CCEngine.sln deleted file mode 100644 index df7ef2a..0000000 --- a/CCEngine.sln +++ /dev/null @@ -1,49 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2036 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CCEngine", "CCEngine\CCEngine.vcxproj", "{51637EB3-9942-43AE-9272-9DD85412EFC7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libLicenseClient", "..\libLicenseClient\libLicenseClient.vcxproj", "{51345E59-83E5-4389-93A9-0131B40522B7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libLicenseClientTest", "..\libLicenseClient\test\libLicenseClientTest.vcxproj", "{E781AE2E-4A02-4D63-9CAC-1AEBACD9CD73}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{44063F88-E25A-4C9D-AC11-9868D4CDD704}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CCEngineLoader", "CCEngineLoader\CCEngineLoader.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {51637EB3-9942-43AE-9272-9DD85412EFC7}.Debug|x86.ActiveCfg = Debug|Win32 - {51637EB3-9942-43AE-9272-9DD85412EFC7}.Debug|x86.Build.0 = Debug|Win32 - {51637EB3-9942-43AE-9272-9DD85412EFC7}.Release|x86.ActiveCfg = Release|Win32 - {51637EB3-9942-43AE-9272-9DD85412EFC7}.Release|x86.Build.0 = Release|Win32 - {51345E59-83E5-4389-93A9-0131B40522B7}.Debug|x86.ActiveCfg = Debug|Win32 - {51345E59-83E5-4389-93A9-0131B40522B7}.Debug|x86.Build.0 = Debug|Win32 - {51345E59-83E5-4389-93A9-0131B40522B7}.Release|x86.ActiveCfg = Release|Win32 - {51345E59-83E5-4389-93A9-0131B40522B7}.Release|x86.Build.0 = Release|Win32 - {E781AE2E-4A02-4D63-9CAC-1AEBACD9CD73}.Debug|x86.ActiveCfg = Debug|Win32 - {E781AE2E-4A02-4D63-9CAC-1AEBACD9CD73}.Debug|x86.Build.0 = Debug|Win32 - {E781AE2E-4A02-4D63-9CAC-1AEBACD9CD73}.Release|x86.ActiveCfg = Release|Win32 - {E781AE2E-4A02-4D63-9CAC-1AEBACD9CD73}.Release|x86.Build.0 = Release|Win32 - {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.ActiveCfg = Debug|Win32 - {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.Build.0 = Debug|Win32 - {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.ActiveCfg = Release|Win32 - {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {E781AE2E-4A02-4D63-9CAC-1AEBACD9CD73} = {44063F88-E25A-4C9D-AC11-9868D4CDD704} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - Qt5Version = $(DefaultQtVersion) - SolutionGuid = {4CBA44D0-8074-48F8-A6DD-5914FE3F0026} - EndGlobalSection -EndGlobal diff --git a/CCEngine/CCEngine.vcxproj b/CCEngine/CCEngine.vcxproj deleted file mode 100644 index 7adc3d3..0000000 --- a/CCEngine/CCEngine.vcxproj +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {51637EB3-9942-43AE-9272-9DD85412EFC7} - Qt4VSv1.0 - CCEngine - 8.1 - - - - Application - true - v141 - MultiByte - - - Application - false - v141 - true - MultiByte - - - - $(MSBuildProjectDirectory)\QtMsBuild - - - - - - - - - - - - - - - - - - - - - - - true - - - false - - - - NotUsing - Level3 - Disabled - true - _WIN32_WINNT=0x0601;WIN32;_SCL_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) - true - stdcpplatest - ProgramDatabase - MultiThreadedDebugDLL - true - %(AdditionalIncludeDirectories) - - - Windows - true - qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies) - - - %(AdditionalIncludeDirectories) - _WIN32_WINNT=0x0601;WIN32;_SCL_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) - - - - - NotUsing - Level3 - MaxSpeed - true - _WIN32_WINNT=0x0601;WIN32;_SCL_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions); - true - stdcpplatest - - - Windows - true - false - YES - false - - false - qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies) - - - _WIN32_WINNT=0x0601;WIN32;_SCL_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions); - %(AdditionalIncludeDirectories) - - - - - - - - - - - - - - - - - - .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp - Moc'ing %(Identity)... - $(ProjectDir)..\..\libLicenseClient\api;.\GeneratedFiles;$(Conan-qt-Root)\include\QtWidgets;$(ProjectDir)..\..\thirdparty\SingleApplication;$(USERPROFILE)\.conan\data\libzip\1.5.1\bincrafters\stable\package\dbbcb700636ed4dcef87df041870679358161bfa\include;$(USERPROFILE)\.conan\data\libcurl\7.61.1\bincrafters\stable\package\ad2605af224ca43af0e946078f4647e97ed84168\include;C:\.conan\uahlbm22\1\include;$(USERPROFILE)\.conan\data\cryptopp\7.0.0\bincrafters\stable\package\b786e9ece960c3a76378ca4d5b0d0e922f4cedc1\include;C:\.conan\hmd9bfi9\1\include;$(USERPROFILE)\.conan\data\bzip2\1.0.6\conan\stable\package\b786e9ece960c3a76378ca4d5b0d0e922f4cedc1\include;$(USERPROFILE)\.conan\data\OpenSSL\1.0.2o\conan\stable\package\312b5f5b013b9686179e3082c71ec55f20aea297\include;$(USERPROFILE)\.conan\data\zlib\1.2.11\conan\stable\package\b786e9ece960c3a76378ca4d5b0d0e922f4cedc1\include - _WIN32_WINNT=0x0601;WIN32;_SCL_SECURE_NO_WARNINGS;_DEBUG;QAPPLICATION_CLASS=QApplication;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;BOOST_USE_STATIC_LIBS;BOOST_ALL_NO_LIB;CURL_STATICLIB=1;_MBCS - .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp - Moc'ing %(Identity)... - $(ProjectDir)..\..\libLicenseClient\api;.\GeneratedFiles;$(Conan-qt-Root)\include\QtWidgets;$(ProjectDir)..\..\thirdparty\SingleApplication;$(USERPROFILE)\.conan\data\libzip\1.5.1\bincrafters\stable\package\fc750fec580977876c697df1eba7f91b3923261b\include;$(USERPROFILE)\.conan\data\libcurl\7.61.1\bincrafters\stable\package\e37072ee7d8e70a6842093ddc8fc71f26526e91f\include;C:\.conan\4gwcmfvt\1\include;$(USERPROFILE)\.conan\data\cryptopp\7.0.0\bincrafters\stable\package\2bb76c9adac7b8cd7c5e3b377ac9f06934aba606\include;C:\.conan\btu8fxq0\1\include;$(USERPROFILE)\.conan\data\bzip2\1.0.6\conan\stable\package\2bb76c9adac7b8cd7c5e3b377ac9f06934aba606\include;$(USERPROFILE)\.conan\data\OpenSSL\1.0.2o\conan\stable\package\b02659d133a8131c5433777813f6385a05a7ae8a\include;$(USERPROFILE)\.conan\data\zlib\1.2.11\conan\stable\package\2bb76c9adac7b8cd7c5e3b377ac9f06934aba606\include - _WIN32_WINNT=0x0601;WIN32;_SCL_SECURE_NO_WARNINGS;NDEBUG;QAPPLICATION_CLASS=QApplication;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;BOOST_USE_STATIC_LIBS;BOOST_ALL_NO_LIB;CURL_STATICLIB=1;_MBCS - - - - - - - - - - - - - - - - - - - - - - - {51345e59-83e5-4389-93a9-0131b40522b7} - - - {b12702ad-abfb-343a-a199-8e24837244a3} - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CCEngine/CCEngine.vcxproj.filters b/CCEngine/CCEngine.vcxproj.filters deleted file mode 100644 index e209d9a..0000000 --- a/CCEngine/CCEngine.vcxproj.filters +++ /dev/null @@ -1,110 +0,0 @@ - - - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {60322e81-4907-489e-87af-66b7f5778503} - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - true - - - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - - - src - - - src - - - src - - - src - - - - - Resource Files - - - - - Resource Files - - - - - Form Files - - - Form Files - - - - - src - - - src - - - src - - - src - - - src - - - src - - - - - Resource Files - - - \ No newline at end of file diff --git a/CCEngine/CMakeLists.txt b/CCEngine/CMakeLists.txt new file mode 100644 index 0000000..eee3aec --- /dev/null +++ b/CCEngine/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required (VERSION 3.8) + +set(PROJECT_NAME CCEngine) +project (${PROJECT_NAME}) + +# Download automatically, you can also just copy the conan.cmake file +if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake") + message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan") + file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.16.1/conan.cmake" + "${CMAKE_BINARY_DIR}/conan.cmake" + EXPECTED_HASH SHA256=396e16d0f5eabdc6a14afddbcfff62a54a7ee75c6da23f32f7a31bc85db23484 + TLS_VERIFY ON) +endif() + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOUIC_SEARCH_PATHS ${PROJECT_SOURCE_DIR}) + +set(CMAKE_PREFIX_PATH ${PROJECT_BINARY_DIR}) + +include(${CMAKE_BINARY_DIR}/conan.cmake) + +conan_cmake_run(CONANFILE conanfile.txt + BUILD missing + BASIC_SETUP) + +################################################################################ +# Source groups +################################################################################ +set(resource + "CCEngine.ui" + "CCEngine.qrc" +) +source_group("resource" FILES ${resource}) + +set(src + "src/CCEngine.cpp" + "src/CCEngine.h" + "src/CCLicenseController.cpp" + "src/CCLicenseController.h" + "src/CCServer.cpp" + "src/CCServer.h" + "src/CCServerManager.cpp" + "src/CCServerManager.h" + "src/main.cpp" + "src/ProcessUtils.cpp" + "src/ProcessUtils.h" + "src/RunGuard.cpp" + "src/RunGuard.h" + "src/SingleAppGuard.cpp" + "src/SingleAppGuard.h" + "src/SystemParamsDlg.cpp" + "src/SystemParamsDlg.h" + "src/SystemParamsModel.cpp" + "src/SystemParamsModel.h" + "src/version.h" +) +source_group("src" FILES ${src}) + +set(ALL_FILES + ${resource} + ${src} +) + +################################################################################ +# Target +################################################################################ + +include_directories(${libLicenseClient_INCLUDE_DIRS}) + +add_executable(${PROJECT_NAME} ${ALL_FILES}) + +# Find the QtWidgets library +message(STATUS "CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}") +find_package(Qt5 CONFIG REQUIRED COMPONENTS Core Gui Widgets) +find_package(yaml-cpp CONFIG) +find_package(boost CONFIG REQUIRED COMPONENTS log) + +target_link_libraries(${PROJECT_NAME} libLicenseClient Qt5::Core Qt5::Gui Qt5::Widgets yaml-cpp::yaml-cpp Boost::log) diff --git a/CCEngine/conanfile.txt b/CCEngine/conanfile.txt index 13ac927..6c80707 100644 --- a/CCEngine/conanfile.txt +++ b/CCEngine/conanfile.txt @@ -1,29 +1,23 @@ [requires] -libzip/1.8.0 -libcurl/7.78.0 boost/1.77.0 -cryptopp/8.5.0 qt/5.15.2 yaml-cpp/0.7.0 [generators] -visual_studio +cmake_find_package_multi +qt [options] -libzip:shared=False -libcurl:shared=False -libcurl:with_openssl=False -libcurl:with_winssl=True boost:shared=False -cryptopp:shared=False qt:shared=True +yaml-cpp:shared=False [imports] -bin, Qt5Cored.dll -> ./Debug @ root_package=qt -bin, Qt5Guid.dll -> ./Debug @ root_package=qt -bin, Qt5Widgetsd.dll -> ./Debug @ root_package=qt -bin, Qt5Core.dll -> ./Release @ root_package=qt -bin, Qt5Gui.dll -> ./Release @ root_package=qt -bin, Qt5Widgets.dll -> ./Release @ root_package=qt -plugins/platforms, qwindowsd.dll -> ./Debug/platforms @ root_package=qt -plugins/platforms, qwindows.dll -> ./Release/platforms @ root_package=qt +bin, Qt5Cored.dll -> ./bin @ root_package=qt +bin, Qt5Guid.dll -> ./bin @ root_package=qt +bin, Qt5Widgetsd.dll -> ./bin @ root_package=qt +bin, Qt5Core.dll -> ./bin @ root_package=qt +bin, Qt5Gui.dll -> ./bin @ root_package=qt +bin, Qt5Widgets.dll -> ./bin @ root_package=qt +bin/archdatadir/plugins/platforms, qwindowsd.dll -> ./bin/platforms @ root_package=qt +bin/archdatadir/plugins/platforms, qwindows.dll -> ./bin/platforms @ root_package=qt diff --git a/CCEngine/project-common.props b/CCEngine/project-common.props deleted file mode 100644 index 370b77c..0000000 --- a/CCEngine/project-common.props +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - $(ProjectDir)..\..\libLicenseClient\api;$(ProjectDir)GeneratedFiles;%(AdditionalIncludeDirectories) - %(AdditionalOptions) - _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;%(PreprocessorDefinitions) - - - %(AdditionalLibraryDirectories) - %(AdditionalDependencies) - %(AdditionalOptions) - - - - \ No newline at end of file diff --git a/CCEngine/src/CCServer.cpp b/CCEngine/src/CCServer.cpp index 4272780..f58c2f2 100644 --- a/CCEngine/src/CCServer.cpp +++ b/CCEngine/src/CCServer.cpp @@ -1,15 +1,19 @@ -#include "CCServer.h" +#include "CCServer.h" #include "CryptoUtils.h" +//------------------------------------------------------------------------------ +// +// Based on Beast example: Advanced server +// +//------------------------------------------------------------------------------ #include #include #include #include -#include +#include +#include #include -#include -#include #include #include #include @@ -21,12 +25,18 @@ #include #include #include +#include +#include #include +#include #include namespace fs = boost::filesystem; // from + +namespace beast = boost::beast; // from +namespace http = beast::http; // from +namespace net = boost::asio; // from using tcp = boost::asio::ip::tcp; // from -namespace http = boost::beast::http; // from static constexpr auto APIS_UINT8_MIN = std::numeric_limits::min(); static constexpr auto APIS_UINT8_MAX = std::numeric_limits::max(); @@ -169,15 +179,15 @@ private: }; // Return a reasonable mime type based on the extension of a file. -boost::beast::string_view -mime_type(boost::beast::string_view path) +beast::string_view +mime_type(beast::string_view path) { - using boost::beast::iequals; + using beast::iequals; auto const ext = [&path] { auto const pos = path.rfind("."); - if (pos == boost::beast::string_view::npos) - return boost::beast::string_view{}; + if (pos == beast::string_view::npos) + return beast::string_view{}; return path.substr(pos); }(); if (iequals(ext, ".htm")) return "text/html"; @@ -208,13 +218,13 @@ mime_type(boost::beast::string_view path) // The returned path is normalized for the platform. std::string path_cat( - boost::beast::string_view base, - boost::beast::string_view path) + beast::string_view base, + beast::string_view path) { if (base.empty()) - return path.to_string(); - std::string result = base.to_string(); -#if BOOST_MSVC + return std::string(path); + std::string result(base); +#ifdef BOOST_MSVC char constexpr path_separator = '\\'; if (result.back() == path_separator) result.resize(result.size() - 1); @@ -240,51 +250,51 @@ template< class Send> void handle_request( - boost::beast::string_view doc_root, + beast::string_view doc_root, etag_cache& cache, http::request>&& req, Send&& send) { // Returns a bad request response auto const bad_request = - [&req](boost::beast::string_view why) + [&req](beast::string_view why) { http::response res{ http::status::bad_request, req.version() }; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/html"); res.keep_alive(req.keep_alive()); - res.body() = why.to_string(); + res.body() = std::string(why); res.prepare_payload(); return res; }; // Returns a not found response auto const not_found = - [&req](boost::beast::string_view target) + [&req](beast::string_view target) { http::response res{ http::status::not_found, req.version() }; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/html"); res.keep_alive(req.keep_alive()); - res.body() = "The resource '" + target.to_string() + "' was not found."; + res.body() = "The resource '" + std::string(target) + "' was not found."; res.prepare_payload(); return res; }; // Returns a server error response auto const server_error = - [&req](boost::beast::string_view what) + [&req](beast::string_view what) { http::response res{ http::status::internal_server_error, req.version() }; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/html"); res.keep_alive(req.keep_alive()); - res.body() = "An error occurred: '" + what.to_string() + "'"; + res.body() = "An error occurred: '" + std::string(what) + "'"; res.prepare_payload(); return res; }; - // Returns a server error response + // Returns a not modified response auto const not_modified = [&req](boost::beast::string_view etag) { @@ -304,7 +314,7 @@ template< // Request path must be absolute and not contain "..". if (req.target().empty() || req.target()[0] != '/' || - req.target().find("..") != boost::beast::string_view::npos) + req.target().find("..") != beast::string_view::npos) return send(bad_request("Illegal request-target")); auto it = req.find(http::field::if_none_match); @@ -333,7 +343,7 @@ template< } // Build the path to the requested file - boost::beast::string_view targetPath = req.target(); + beast::string_view targetPath = req.target(); auto pos = targetPath.find_first_of('?'); if (pos != std::string::npos) { @@ -398,11 +408,12 @@ template< // Report a failure void -fail(boost::system::error_code ec, char const* what) +fail(beast::error_code ec, char const* what) { std::cerr << what << ": " << ec.message() << "\n"; } + // Handles an HTTP server connection class http_session : public std::enable_shared_from_this { @@ -462,8 +473,7 @@ class http_session : public std::enable_shared_from_this // This holds a work item struct work_impl : work { - // workaround. remove the value initialization after msvc fixes their bug - http_session& self_ = *(http_session*)nullptr; + http_session& self_; http::message msg_; work_impl( @@ -478,20 +488,18 @@ class http_session : public std::enable_shared_from_this operator()() { http::async_write( - self_.socket_, + self_.stream_, msg_, - boost::asio::bind_executor( - self_.strand_, - std::bind( - &http_session::on_write, - self_.shared_from_this(), - std::placeholders::_1, - msg_.need_eof()))); + beast::bind_front_handler( + &http_session::on_write, + self_.shared_from_this(), + msg_.need_eof())); } }; // Allocate and store the work - items_.push_back(std::make_unique(self_, std::move(msg))); + items_.push_back( + boost::make_unique(self_, std::move(msg))); // If there was no previous work, start this one if (items_.size() == 1) @@ -499,92 +507,75 @@ class http_session : public std::enable_shared_from_this } }; - tcp::socket socket_; - boost::asio::strand< - boost::asio::io_context::executor_type> strand_; - boost::asio::steady_timer timer_; - boost::beast::flat_buffer buffer_; - std::string const& doc_root_; + beast::tcp_stream stream_; + beast::flat_buffer buffer_; + std::shared_ptr doc_root_; etag_cache& etag_cache_; - http::request req_; queue queue_; + // The parser is stored in an optional container so we can + // construct it from scratch it at the beginning of each new message. + boost::optional> parser_; + public: // Take ownership of the socket - explicit - http_session( - tcp::socket socket, - std::string const& doc_root, - etag_cache& etagCache) - : socket_(std::move(socket)) - , strand_(socket_.get_executor()) - , timer_(socket_.get_executor().context(), - (std::chrono::steady_clock::time_point::max)()) + http_session( + tcp::socket&& socket, + std::shared_ptr const& doc_root, + etag_cache& etag_cache) + : stream_(std::move(socket)) , doc_root_(doc_root) - , etag_cache_(etagCache) + , etag_cache_(etag_cache) , queue_(*this) { } - // Start the asynchronous operation + // Start the session void run() { - // Run the timer. The timer is operated - // continuously, this simplifies the code. - on_timer({}); - - do_read(); + // We need to be executing within a strand to perform async operations + // on the I/O objects in this session. Although not strictly necessary + // for single-threaded contexts, this example code is written to be + // thread-safe by default. + net::dispatch( + stream_.get_executor(), + beast::bind_front_handler( + &http_session::do_read, + this->shared_from_this())); } + +private: void do_read() { - // Set the timer - timer_.expires_after(std::chrono::seconds(15)); + // Construct a new parser for each message + parser_.emplace(); - // Read a request - http::async_read(socket_, buffer_, req_, - boost::asio::bind_executor( - strand_, - std::bind( - &http_session::on_read, - shared_from_this(), - std::placeholders::_1))); - } + // Apply a reasonable limit to the allowed size + // of the body in bytes to prevent abuse. + parser_->body_limit(10000); - // Called when the timer expires. - void - on_timer(boost::system::error_code ec) - { - if (ec && ec != boost::asio::error::operation_aborted) - return fail(ec, "timer"); + // Set the timeout. + stream_.expires_after(std::chrono::seconds(30)); - // Verify that the timer really expired since the deadline may have moved. - if (timer_.expiry() <= std::chrono::steady_clock::now()) - { - // Closing the socket cancels all outstanding operations. They - // will complete with boost::asio::error::operation_aborted - socket_.shutdown(tcp::socket::shutdown_both, ec); - socket_.close(ec); - return; - } - - // Wait on the timer - timer_.async_wait( - boost::asio::bind_executor( - strand_, - std::bind( - &http_session::on_timer, - shared_from_this(), - std::placeholders::_1))); + // Read a request using the parser-oriented interface + http::async_read( + stream_, + buffer_, + *parser_, + beast::bind_front_handler( + &http_session::on_read, + shared_from_this())); } void - on_read(boost::system::error_code ec) + on_read(beast::error_code ec, std::size_t bytes_transferred) { - // Happens when the timer closes the socket - if (ec == boost::asio::error::operation_aborted) + boost::ignore_unused(bytes_transferred); + + if (ec == beast::error::timeout) return; // This means they closed the connection @@ -595,7 +586,7 @@ public: return fail(ec, "read"); // Send the response - handle_request(doc_root_, etag_cache_, std::move(req_), queue_); + handle_request(*doc_root_, etag_cache_, parser_->release(), queue_); // If we aren't at the queue limit, try to pipeline another request if (!queue_.is_full()) @@ -603,10 +594,11 @@ public: } void - on_write(boost::system::error_code ec, bool close) + on_write(bool close, beast::error_code ec, std::size_t bytes_transferred) { - // Happens when the timer closes the socket - if (ec == boost::asio::error::operation_aborted) + boost::ignore_unused(bytes_transferred); + + if (ec == beast::error::timeout) return; if (ec) @@ -631,8 +623,8 @@ public: do_close() { // Send a TCP shutdown - boost::system::error_code ec; - socket_.shutdown(tcp::socket::shutdown_send, ec); + beast::error_code ec; + stream_.socket().shutdown(tcp::socket::shutdown_send, ec); // At this point the connection is closed gracefully } @@ -643,23 +635,23 @@ public: // Accepts incoming connections and launches the sessions class listener : public std::enable_shared_from_this { + net::io_context& ioc_; tcp::acceptor acceptor_; - tcp::socket socket_; - std::string const& doc_root_; + std::shared_ptr doc_root_; etag_cache& etag_cache_; public: listener( - boost::asio::io_context& ioc, + net::io_context& ioc, tcp::endpoint endpoint, - std::string const& doc_root, + std::shared_ptr const& doc_root, etag_cache& etagCache) - : acceptor_(ioc) - , socket_(ioc) + : ioc_(ioc) + , acceptor_(net::make_strand(ioc)) , doc_root_(doc_root) , etag_cache_(etagCache) { - boost::system::error_code ec; + beast::error_code ec; // Open the acceptor acceptor_.open(endpoint.protocol(), ec); @@ -669,6 +661,14 @@ public: return; } +// // Allow address reuse +// acceptor_.set_option(net::socket_base::reuse_address(true), ec); +// if (ec) +// { +// fail(ec, "set_option"); +// return; +// } + // Bind to the server address acceptor_.bind(endpoint, ec); if (ec) @@ -679,7 +679,7 @@ public: // Start listening for connections acceptor_.listen( - boost::asio::socket_base::max_listen_connections, ec); + net::socket_base::max_listen_connections, ec); if (ec) { fail(ec, "listen"); @@ -691,24 +691,31 @@ public: void run() { - if (!acceptor_.is_open()) - return; - do_accept(); + // We need to be executing within a strand to perform async operations + // on the I/O objects in this session. Although not strictly necessary + // for single-threaded contexts, this example code is written to be + // thread-safe by default. + net::dispatch( + acceptor_.get_executor(), + beast::bind_front_handler( + &listener::do_accept, + this->shared_from_this())); } +private: void do_accept() { + // The new connection gets its own strand acceptor_.async_accept( - socket_, - std::bind( + net::make_strand(ioc_), + beast::bind_front_handler( &listener::on_accept, - shared_from_this(), - std::placeholders::_1)); + shared_from_this())); } void - on_accept(boost::system::error_code ec) + on_accept(beast::error_code ec, tcp::socket socket) { if (ec) { @@ -716,9 +723,9 @@ public: } else { - // Create the http_session and run it + // Create the http session and run it std::make_shared( - std::move(socket_), + std::move(socket), doc_root_, etag_cache_)->run(); } @@ -759,7 +766,7 @@ public: std::make_shared( m_ioc, m_endpoint, - m_docRoot, + std::make_shared(m_docRoot), m_etagCache)->run(); // Run the I/O service on the requested number of threads diff --git a/CCEngineLoader/CCEngineLoader.vcxproj b/CCEngineLoader/CCEngineLoader.vcxproj deleted file mode 100644 index 69e6a5c..0000000 --- a/CCEngineLoader/CCEngineLoader.vcxproj +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {B12702AD-ABFB-343A-A199-8E24837244A3} - Qt4VSv1.0 - 8.1 - - - - Application - true - v141 - MultiByte - - - Application - false - v141 - true - MultiByte - - - - $(MSBuildProjectDirectory)\QtMsBuild - - - - - - - - - - - - - - - - - - - - - - - true - - - false - - - - NotUsing - Level3 - Disabled - true - _WIN32_WINNT=0x0601;WIN32;_DEBUG;%(PreprocessorDefinitions) - true - stdcpplatest - ProgramDatabase - MultiThreadedDebugDLL - true - %(AdditionalIncludeDirectories) - - - Windows - true - qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies) - - - %(AdditionalIncludeDirectories) - _WIN32_WINNT=0x0601;WIN32;_DEBUG;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;CURL_STATICLIB;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING;_MBCS - - - - - NotUsing - Level3 - MaxSpeed - true - _WIN32_WINNT=0x0601;WIN32;NDEBUG;%(PreprocessorDefinitions) - true - stdcpplatest - - - Windows - true - false - YES - false - - false - qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies) - - - _WIN32_WINNT=0x0601;WIN32;NDEBUG;BOOST_EXCEPTION_DISABLE;QT_NO_DEBUG;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;CURL_STATICLIB;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING;_MBCS - %(AdditionalIncludeDirectories) - - - - - - - - - - - - - - - - - - - - - - {51345e59-83e5-4389-93a9-0131b40522b7} - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CCEngineLoader/CCEngineLoader.vcxproj.filters b/CCEngineLoader/CCEngineLoader.vcxproj.filters deleted file mode 100644 index 88d7d0f..0000000 --- a/CCEngineLoader/CCEngineLoader.vcxproj.filters +++ /dev/null @@ -1,64 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} - qrc;* - false - - - {99349809-55BA-4b9d-BF79-8FDBB0286EB3} - ui - - - {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} - qrc;* - false - - - {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} - moc;h;cpp - False - - - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - - - Form Files - - - - - Resource Files - - - - - - \ No newline at end of file diff --git a/CCEngineLoader/CMakeLists.txt b/CCEngineLoader/CMakeLists.txt new file mode 100644 index 0000000..bf51cba --- /dev/null +++ b/CCEngineLoader/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required (VERSION 3.8) + +set(PROJECT_NAME CCEngineLoader) +project (${PROJECT_NAME}) + +# Download automatically, you can also just copy the conan.cmake file +if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake") + message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan") + file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.16.1/conan.cmake" + "${CMAKE_BINARY_DIR}/conan.cmake" + EXPECTED_HASH SHA256=396e16d0f5eabdc6a14afddbcfff62a54a7ee75c6da23f32f7a31bc85db23484 + TLS_VERIFY ON) +endif() + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_PREFIX_PATH ${PROJECT_BINARY_DIR}) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +include(${CMAKE_BINARY_DIR}/conan.cmake) + +conan_cmake_run(CONANFILE conanfile.txt + BUILD missing + BASIC_SETUP) + +################################################################################ +# Source groups +################################################################################ +set(resource + "CCEngineLoader.ui" + "CCEngineLoader.qrc" +) +source_group("resource" FILES ${resource}) + +set(src + "CCEngineLoader.cpp" + "CCEngineLoader.h" + "main.cpp" + "UpdateWorker.cpp" + "UpdateWorker.h" +) +source_group("src" FILES ${src}) + +set(ALL_FILES + ${resource} + ${src} +) + +################################################################################ +# Target +################################################################################ +include_directories(${libLicenseClient_INCLUDE_DIRS}) + +add_executable(${PROJECT_NAME} ${ALL_FILES}) + +# Find the QtWidgets library +message(STATUS "CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}") +find_package(Qt5 CONFIG REQUIRED COMPONENTS Core Gui Widgets) + +target_link_libraries(${PROJECT_NAME} libLicenseClient Qt5::Core Qt5::Gui Qt5::Widgets) diff --git a/CCEngineLoader/conanfile.txt b/CCEngineLoader/conanfile.txt index 4d785e5..b02fa0d 100644 --- a/CCEngineLoader/conanfile.txt +++ b/CCEngineLoader/conanfile.txt @@ -1,18 +1,11 @@ [requires] -libzip/1.8.0 -libcurl/7.78.0 boost/1.77.0 -cryptopp/8.5.0 qt/5.15.2 [generators] -visual_studio +cmake_find_package_multi +qt [options] -libzip:shared=False -libcurl:shared=False -libcurl:with_openssl=False -libcurl:with_winssl=True boost:shared=False -cryptopp:shared=False qt:shared=True diff --git a/CCEngineLoader/project-common.props b/CCEngineLoader/project-common.props deleted file mode 100644 index ba7c3d2..0000000 --- a/CCEngineLoader/project-common.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - $(ProjectDir)..\..\libLicenseClient\api;$(ProjectDir)GeneratedFiles;%(AdditionalIncludeDirectories) - %(AdditionalOptions) - - - %(AdditionalDependencies) - %(AdditionalOptions) - - - - \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8de4103 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.8) + +# You can tweak some common (for all subprojects) stuff here. For example: + +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) +set(CMAKE_DISABLE_SOURCE_CHANGES ON) + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + message(SEND_ERROR "In-source builds are not allowed.") +endif () + +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_COLOR_MAKEFILE ON) + +# Remove 'lib' prefix for shared libraries on Windows +if (WIN32) + set(CMAKE_SHARED_LIBRARY_PREFIX "") + ADD_DEFINITIONS(/bigobj) +endif () + +# Force 8.1 SDK, to keep it compatible with win7 +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + set (CMAKE_SYSTEM_VERSION 8.1 CACHE TYPE INTERNAL FORCE) +endif() + +# When done tweaking common stuff, configure the components (subprojects). +# NOTE: The order matters! The most independent ones should go first. +add_subdirectory(../libLicenseClient libLicenseClient) +add_subdirectory(../libLicenseClient/test libLicenseClientTest) +add_subdirectory(CCEngine) +add_subdirectory(CCEngineLoader) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..3ea62fb --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,124 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 19, + "patch": 0 + }, + "configurePresets": [ + { + "name": "linux-gcc-debug", + "displayName": "Linux GCC Debug", + "description": "Sets Ninja generator, compilers, build and install directory, debug build type", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "c++" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Linux" ] + }, + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + }, + { + "name": "linux-gcc-release", + "displayName": "Linux GCC Release", + "description": "Sets Ninja generator, compilers, build and install directory, debug build type", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "c++" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Linux" ] + }, + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + }, + { + "name": "WSL-gcc-debug", + "displayName": "Linux Debug", + "description": "Target the Windows Subsystem for Linux (WSL) or a remote Linux system.", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Linux" ] }, + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" } + } + }, + { + "name": "win64-debug", + "displayName": "Windows x64 Debug", + "description": "Target Windows with the Visual Studio development environment.", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_SYSTEM_VERSION": "8.1" + }, + "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } } + }, + { + "name": "win64-release", + "displayName": "Windows x64 Release", + "description": "Target Windows with the Visual Studio development environment.", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "CMAKE_SYSTEM_VERSION": "8.1" + }, + "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } } + } + ], + "buildPresets": [ + { + "name": "linux-gcc-debug", + "configurePreset": "linux-gcc-debug" + }, + { + "name": "linux-gcc-release", + "configurePreset": "linux-gcc-release" + }, + { + "name": "win64-debug", + "configurePreset": "win64-debug" + }, + { + "name": "win64-release", + "configurePreset": "win64-release" + } + ], + "vendor": { + "example.com/ExampleIDE/1.0": { + "autoFormat": false + } + } +} diff --git a/non-debugable.props b/non-debugable.props deleted file mode 100644 index d44641b..0000000 --- a/non-debugable.props +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - false - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalOptions) - false - None - - - %(AdditionalDependencies) - %(AdditionalOptions) - true - false - YES - false - - false - UseLinkTimeCodeGeneration - - - - \ No newline at end of file diff --git a/qt-ui-common.props b/qt-ui-common.props deleted file mode 100644 index 7f610bc..0000000 --- a/qt-ui-common.props +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - false - - - - QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;$(ProjectDir)..\..\libLicenseClient\api;%(AdditionalIncludeDirectories) - - - $(QTDIR)\lib;%(AdditionalLibraryDirectories) - - - %(FullPath) - .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp - output - Moc'ing %(Identity)... - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName)\.;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(IncludePath) - QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(Define) - $(QTDIR) - - - Uic'ing %(Identity)... - .\GeneratedFiles\ui_%(Filename).h - - - Rcc'ing %(Identity)... - .\GeneratedFiles\qrc_%(Filename).cpp - - - - \ No newline at end of file diff --git a/qt-ui-debug.props b/qt-ui-debug.props deleted file mode 100644 index 7f22efa..0000000 --- a/qt-ui-debug.props +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - false - - - - %(PreprocessorDefinitions) - - - qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies) - - - - \ No newline at end of file diff --git a/qt-ui-release.props b/qt-ui-release.props deleted file mode 100644 index 4c9aef7..0000000 --- a/qt-ui-release.props +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - false - - - - QT_NO_DEBUG;%(PreprocessorDefinitions) - - - qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies) - - - QT_NO_DEBUG;NDEBUG;%(Define) - - - - \ No newline at end of file