From 1356196f4b1e094ee03549654c6809f48ec538c9 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Mon, 9 Aug 2021 10:19:15 +0200 Subject: [PATCH 01/31] add httpserver to the remote cotrol --- .../score-plugin-remotecontrol/CMakeLists.txt | 8 +- .../RemoteControl/ApplicationPlugin.cpp | 6 + .../RemoteControl/Http_server.cpp | 326 ++++++++++++++++++ .../RemoteControl/Http_server.hpp | 138 ++++++++ 4 files changed, 477 insertions(+), 1 deletion(-) create mode 100644 src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp create mode 100644 src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp diff --git a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt index 0bebb7917c..363acd6568 100644 --- a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt +++ b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt @@ -37,6 +37,8 @@ set(HDRS "${CMAKE_CURRENT_SOURCE_DIR}/i-score-remote/RemoteApplication.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.hpp" + + "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/Http_server.hpp" ) set(SRCS @@ -57,12 +59,16 @@ set(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/ApplicationPlugin.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/Http_server.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.cpp" ) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/build-wasm/ DESTINATION ${CMAKE_BINARY_DIR}/src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/ ) + add_library(${PROJECT_NAME} ${SRCS} ${HDRS} ${QRCS}) -target_link_libraries(${PROJECT_NAME} PUBLIC score_plugin_scenario score_plugin_js ${QT_PREFIX}::WebSockets) +target_link_libraries(${PROJECT_NAME} PUBLIC score_plugin_scenario score_plugin_js ${QT_PREFIX}::WebSockets ossia) setup_score_plugin(${PROJECT_NAME}) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp index 43f56064d2..650b9fb8ca 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp @@ -7,9 +7,12 @@ #include #include + #include #include +#include + namespace RemoteControl { ApplicationPlugin::ApplicationPlugin(const score::GUIApplicationContext& app) @@ -22,6 +25,9 @@ void ApplicationPlugin::on_createdDocument(score::Document& doc) doc.model().addPluginModel(new WS::DocumentPlugin{doc.context(), &doc.model()}); doc.model().addPluginModel( new Controller::DocumentPlugin{doc.context(), &doc.model()}); + + Http_server Http_server; + Http_server.open_server(); } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp new file mode 100644 index 0000000000..7c6ab7636e --- /dev/null +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -0,0 +1,326 @@ +// +// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +//------------------------------------------------------------------------------ +// +// Example: HTTP server, synchronous +// +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ + +namespace RemoteControl +{ + +Http_server::Http_server() + : ioc{1} +{ + // auto th = [this] { this->ioc.run(); }; + + //th(&Http_server::open_server, this); + + open_server(); + + //th = [this] { this->ioc.run(); }; + +} + +Http_server::~Http_server() +{ + //ioc.stop(); + th.join(); +} + +// Return a reasonable mime type based on the extension of a file. +beast::string_view +Http_server::mime_type(beast::string_view path) +{ + using beast::iequals; + auto const ext = [&path] + { + auto const pos = path.rfind("."); + if(pos == beast::string_view::npos) + return beast::string_view{}; + return path.substr(pos); + }(); + if(iequals(ext, ".htm")) return "text/html"; + if(iequals(ext, ".html")) return "text/html"; + if(iequals(ext, ".php")) return "text/html"; + if(iequals(ext, ".css")) return "text/css"; + if(iequals(ext, ".txt")) return "text/plain"; + if(iequals(ext, ".js")) return "application/javascript"; + if(iequals(ext, ".json")) return "application/json"; + if(iequals(ext, ".xml")) return "application/xml"; + if(iequals(ext, ".swf")) return "application/x-shockwave-flash"; + if(iequals(ext, ".flv")) return "video/x-flv"; + if(iequals(ext, ".png")) return "image/png"; + if(iequals(ext, ".jpe")) return "image/jpeg"; + if(iequals(ext, ".jpeg")) return "image/jpeg"; + if(iequals(ext, ".jpg")) return "image/jpeg"; + if(iequals(ext, ".gif")) return "image/gif"; + if(iequals(ext, ".bmp")) return "image/bmp"; + if(iequals(ext, ".ico")) return "image/vnd.microsoft.icon"; + if(iequals(ext, ".tiff")) return "image/tiff"; + if(iequals(ext, ".tif")) return "image/tiff"; + if(iequals(ext, ".svg")) return "image/svg+xml"; + if(iequals(ext, ".svgz")) return "image/svg+xml"; + return "application/text"; +} + +// Append an HTTP rel-path to a local filesystem path. +// The returned path is normalized for the platform. +std::string +Http_server::path_cat( + beast::string_view base, + beast::string_view path) +{ + if (base.empty()) + 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); + result.append(path.data(), path.size()); + for(auto& c : result) + if(c == '/') + c = path_separator; +#else + char constexpr path_separator = '/'; + if(result.back() == path_separator) + result.resize(result.size() - 1); + result.append(path.data(), path.size()); +#endif + return result; +} + +// This function produces an HTTP response for the given +// request. The type of the response object depends on the +// contents of the request, so the interface requires the +// caller to pass a generic lambda for receiving the response. +template< + class Body, class Allocator, + class Send> +void +Http_server::handle_request( + beast::string_view doc_root, + http::request>&& req, + Send&& send) +{ + // Returns a bad request response + auto const bad_request = + [&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() = std::string(why); + res.prepare_payload(); + return res; + }; + + // Returns a not found response + auto const not_found = + [&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 '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/remote.html."; + res.prepare_payload(); + return res; + }; + + // Returns a server error response + auto const server_error = + [&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: '" + std::string(what) + "'"; + res.prepare_payload(); + return res; + }; + + // Make sure we can handle the method + if( req.method() != http::verb::get && + req.method() != http::verb::head) + return send(bad_request("Unknown HTTP-method")); + + // Request path must be absolute and not contain "..". + if( req.target().empty() || + req.target()[0] != '/' || + req.target().find("..") != beast::string_view::npos) + return send(bad_request("Illegal request-target")); + + // Build the path to the requested file + std::string path = path_cat(doc_root, req.target()); + if(req.target().back() == '/') + path.append("index.html"); + + // Attempt to open the file + beast::error_code ec; + http::file_body::value_type body; + body.open(path.c_str(), beast::file_mode::scan, ec); + + // Handle the case where the file doesn't exist + if(ec == beast::errc::no_such_file_or_directory) + return send(not_found(req.target())); + + // Handle an unknown error + if(ec) + return send(server_error(ec.message())); + + // Cache the size since we need it after the move + auto const size = body.size(); + + // Respond to HEAD request + if(req.method() == http::verb::head) + { + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, mime_type(path)); + res.content_length(size); + res.keep_alive(req.keep_alive()); + return send(std::move(res)); + } + + // Respond to GET request + http::response res{ + std::piecewise_construct, + std::make_tuple(std::move(body)), + std::make_tuple(http::status::ok, req.version())}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, mime_type(path)); + res.content_length(size); + res.keep_alive(req.keep_alive()); + return send(std::move(res)); +} + +//------------------------------------------------------------------------------ + +// Report a failure +void +Http_server::fail(beast::error_code ec, char const* what) +{ + std::cerr << what << ": " << ec.message() << "\n"; +} + +// Handles an HTTP server connection +void +Http_server::do_session( + tcp::socket& socket, + std::shared_ptr const& doc_root) +{ + bool close = false; + beast::error_code ec; + + // This buffer is required to persist across reads + beast::flat_buffer buffer; + + // This lambda is used to send messages + send_lambda lambda{socket, close, ec}; + + for(;;) + { + // Read a request + http::request req; + http::read(socket, buffer, req, ec); + if(ec == http::error::end_of_stream) + break; + if(ec) + return Http_server::fail(ec, "read"); + + // Send the response + Http_server::handle_request(*doc_root, std::move(req), lambda); + if(ec) + return Http_server::fail(ec, "write"); + if(close) + { + // This means we should close the connection, usually because + // the response indicated the "Connection: close" semantic. + break; + } + } + + // Send a TCP shutdown + socket.shutdown(tcp::socket::shutdown_send, ec); + + // At this point the connection is closed gracefully +} + +//------------------------------------------------------------------------------ + +std::string +Http_server::get_ip_address() +{ + std::string ip_address; + + QList list = QNetworkInterface::allAddresses(); + + for(int nIter=0; nIter(std::atoi("8080")); + auto const doc_root = std::make_shared("./build-wasm/"); + + // The acceptor receives incoming connections + tcp::acceptor acceptor{ioc, {address, port}}; + for(;;) + { + // This will receive the new connection + tcp::socket socket{ioc}; + + // Block until we get a connection + acceptor.accept(socket); + + // Launch the session, transferring ownership of the socket + std::thread{std::bind( + &Http_server::do_session, + this, + std::move(socket), + doc_root)}.detach(); + } + } + catch (const std::exception& e) + { + std::cerr << "Error: " << e.what() << std::endl; + return EXIT_FAILURE; + } +} + +} diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp new file mode 100644 index 0000000000..3ac3da6a2f --- /dev/null +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -0,0 +1,138 @@ +// +// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +//------------------------------------------------------------------------------ +// +// Example: HTTP server, synchronous +// +//------------------------------------------------------------------------------ +#pragma once + +#define BOOST_DATE_TIME_NO_LIB 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace beast = boost::beast; // from +namespace http = beast::http; // from +namespace net = boost::asio; // from +using tcp = boost::asio::ip::tcp; // from + +//------------------------------------------------------------------------------ + +namespace RemoteControl +{ +class Http_server +{ +public: + std::thread th; + net::io_context ioc; + + // std::thread th1; + + Http_server(); + + ~Http_server(); + + //------------------------------------------------------------------------------ + + // Return a reasonable mime type based on the extension of a file. + beast::string_view + mime_type(beast::string_view path); + + // Append an HTTP rel-path to a local filesystem path. + // The returned path is normalized for the platform. + std::string + path_cat( + beast::string_view base, + beast::string_view path); + + // This function produces an HTTP response for the given + // request. The type of the response object depends on the + // contents of the request, so the interface requires the + // caller to pass a generic lambda for receiving the response. + template< + class Body, class Allocator, + class Send> + void + handle_request( + beast::string_view doc_root, + http::request>&& req, + Send&& send); + + //------------------------------------------------------------------------------ + + // Report a failure + void + fail(beast::error_code ec, char const* what); + + // This is the C++11 equivalent of a generic lambda. + // The function object is used to send an HTTP message. + template + struct send_lambda + { + Stream& stream_; + bool& close_; + beast::error_code& ec_; + + explicit + send_lambda( + Stream& stream, + bool& close, + beast::error_code& ec) + : stream_(stream) + , close_(close) + , ec_(ec) + { + } + + template + void + operator()(http::message&& msg) const + { + // Determine if we should close the connection after + close_ = msg.need_eof(); + + // We need the serializer here because the serializer requires + // a non-const file_body, and the message oriented version of + // http::write only works with const messages. + http::serializer sr{msg}; + http::write(stream_, sr, ec_); + } + }; + + // Handles an HTTP server connection + void + do_session( + tcp::socket& socket, + std::shared_ptr const& doc_root); + + //------------------------------------------------------------------------------ + + std::string get_ip_address(); + + //------------------------------------------------------------------------------ + + int open_server(); + + //void open_server_thread(); +}; +} From 9e9e16af2117aebddcd94613bde7335dcbf9be32 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Mon, 9 Aug 2021 15:07:19 +0200 Subject: [PATCH 02/31] try to add a thread for the web socket connection --- .../RemoteControl/Http_server.cpp | 9 +++++++-- .../RemoteControl/Http_server.hpp | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 7c6ab7636e..5c2f77ccc0 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -35,7 +35,7 @@ Http_server::Http_server() Http_server::~Http_server() { - //ioc.stop(); + ioc.stop(); th.join(); } @@ -313,8 +313,13 @@ Http_server::open_server() &Http_server::do_session, this, std::move(socket), - doc_root)}.detach(); + doc_root)}.join(); + + // auto th1 = [this] { this->do_session(std::move(socket), doc_root); }; + } + + auto th = [this] { this->ioc.run(); }; } catch (const std::exception& e) { diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index 3ac3da6a2f..6790b1bf94 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -46,7 +46,7 @@ class Http_server std::thread th; net::io_context ioc; - // std::thread th1; + //std::thread th1; Http_server(); From d56f42e1feb6daf53e9ed093bda5a04f194f2226 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Mon, 9 Aug 2021 16:52:05 +0200 Subject: [PATCH 03/31] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9415fe5cab..de40f52401 100755 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ .clangd ./*.cache *.zip -build-* AppRun* *.AppImage *.txz From 142b45f28944b7b70d2077a5d4698cfc6606baaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Wed, 11 Aug 2021 15:05:56 +0200 Subject: [PATCH 04/31] Do not block score with the http server for the remotecontrol --- .../RemoteControl/ApplicationPlugin.cpp | 1 - .../RemoteControl/ApplicationPlugin.hpp | 2 + .../RemoteControl/Http_server.cpp | 39 +++++-------------- .../RemoteControl/Http_server.hpp | 8 ++-- 4 files changed, 17 insertions(+), 33 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp index 650b9fb8ca..d504ff8853 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp @@ -11,7 +11,6 @@ #include #include -#include namespace RemoteControl { diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp index 1e562545ea..9e119eff29 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace RemoteControl { class ApplicationPlugin final : public score::GUIApplicationPlugin @@ -10,5 +11,6 @@ class ApplicationPlugin final : public score::GUIApplicationPlugin protected: void on_createdDocument(score::Document& doc) override; + Http_server m_server; }; } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 5c2f77ccc0..75ce90112a 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -16,27 +16,21 @@ #include //------------------------------------------------------------------------------ - +#include namespace RemoteControl { Http_server::Http_server() - : ioc{1} { - // auto th = [this] { this->ioc.run(); }; - - //th(&Http_server::open_server, this); - - open_server(); - - //th = [this] { this->ioc.run(); }; - + m_docRoot = "/tmp"; + m_serverThread = std::thread{[this] { open_server(); }}; } Http_server::~Http_server() { + shutdown(m_listenSocket, SHUT_RDWR); ioc.stop(); - th.join(); + m_serverThread.join(); } // Return a reasonable mime type based on the extension of a file. @@ -221,8 +215,7 @@ Http_server::fail(beast::error_code ec, char const* what) // Handles an HTTP server connection void Http_server::do_session( - tcp::socket& socket, - std::shared_ptr const& doc_root) + tcp::socket& socket) { bool close = false; beast::error_code ec; @@ -244,7 +237,7 @@ Http_server::do_session( return Http_server::fail(ec, "read"); // Send the response - Http_server::handle_request(*doc_root, std::move(req), lambda); + Http_server::handle_request(m_docRoot, std::move(req), lambda); if(ec) return Http_server::fail(ec, "write"); if(close) @@ -291,15 +284,12 @@ Http_server::open_server() { try { - //std::string ip_address = get_ip_address(); - - // auto const address = net::ip::make_address(ip_address); - auto const address = net::ip::make_address("127.0.0.1"); + auto const address = net::ip::make_address("0.0.0.0"); auto const port = static_cast(std::atoi("8080")); - auto const doc_root = std::make_shared("./build-wasm/"); // The acceptor receives incoming connections tcp::acceptor acceptor{ioc, {address, port}}; + m_listenSocket = acceptor.native_handle(); for(;;) { // This will receive the new connection @@ -309,17 +299,8 @@ Http_server::open_server() acceptor.accept(socket); // Launch the session, transferring ownership of the socket - std::thread{std::bind( - &Http_server::do_session, - this, - std::move(socket), - doc_root)}.join(); - - // auto th1 = [this] { this->do_session(std::move(socket), doc_root); }; - + do_session(socket); } - - auto th = [this] { this->ioc.run(); }; } catch (const std::exception& e) { diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index 6790b1bf94..a52762cc3d 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -43,7 +43,6 @@ namespace RemoteControl class Http_server { public: - std::thread th; net::io_context ioc; //std::thread th1; @@ -122,8 +121,7 @@ class Http_server // Handles an HTTP server connection void do_session( - tcp::socket& socket, - std::shared_ptr const& doc_root); + tcp::socket& socket); //------------------------------------------------------------------------------ @@ -134,5 +132,9 @@ class Http_server int open_server(); //void open_server_thread(); + std::thread m_serverThread; + std::string m_docRoot; + + int m_listenSocket{}; }; } From 3918fa90bea606d640912079bf4f76053d1c5ff6 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Thu, 12 Aug 2021 09:49:36 +0200 Subject: [PATCH 05/31] rm some useless include --- .../score-plugin-remotecontrol/RemoteControl/Http_server.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index a52762cc3d..3407c539df 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -27,6 +27,10 @@ #include #include +#ifdef _WIN32 +#define SHUT_RDWR 2 +#endif + #include #include #include From 96d54b22641afc2899dce0a6087d15a2588e0d10 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Thu, 12 Aug 2021 15:14:49 +0200 Subject: [PATCH 06/31] modify some variable and path --- .../score-plugin-remotecontrol/CMakeLists.txt | 4 +-- .../RemoteControl/ApplicationPlugin.cpp | 3 +-- .../RemoteControl/Http_server.cpp | 26 ++++++++++++++----- .../RemoteControl/Http_server.hpp | 16 +++++++++--- 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt index 363acd6568..75774c040b 100644 --- a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt +++ b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt @@ -40,8 +40,8 @@ set(HDRS "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/Http_server.hpp" ) -set(SRCS +set(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/Controller/RemoteControlProvider.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/Controller/DocumentPlugin.cpp" @@ -64,7 +64,7 @@ set(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.cpp" ) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/build-wasm/ DESTINATION ${CMAKE_BINARY_DIR}/src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/ ) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/build-wasm/ DESTINATION ${CMAKE_BINARY_DIR}/src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/) add_library(${PROJECT_NAME} ${SRCS} ${HDRS} ${QRCS}) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp index d504ff8853..6b1de100ca 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp @@ -25,8 +25,7 @@ void ApplicationPlugin::on_createdDocument(score::Document& doc) doc.model().addPluginModel( new Controller::DocumentPlugin{doc.context(), &doc.model()}); - Http_server Http_server; - Http_server.open_server(); + m_server.start_thread(); } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 75ce90112a..39f75b0278 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -22,8 +22,7 @@ namespace RemoteControl Http_server::Http_server() { - m_docRoot = "/tmp"; - m_serverThread = std::thread{[this] { open_server(); }}; + // m_docRoot = "/tmp"; } Http_server::~Http_server() @@ -122,6 +121,8 @@ Http_server::handle_request( return res; }; + QDir::currentPath(); + // Returns a not found response auto const not_found = [&req](beast::string_view target) @@ -130,7 +131,7 @@ Http_server::handle_request( 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 '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/remote.html."; + res.body() = "The resource '" + std::string(target) + "' was not found.
Current repository :" + QDir::currentPath().toUtf8().constData() +".
Go to the following address : http://ip_address:port/remote.html."; res.prepare_payload(); return res; }; @@ -215,7 +216,8 @@ Http_server::fail(beast::error_code ec, char const* what) // Handles an HTTP server connection void Http_server::do_session( - tcp::socket& socket) + tcp::socket& socket, + std::shared_ptr const& doc_root) { bool close = false; beast::error_code ec; @@ -237,7 +239,7 @@ Http_server::do_session( return Http_server::fail(ec, "read"); // Send the response - Http_server::handle_request(m_docRoot, std::move(req), lambda); + Http_server::handle_request(*doc_root, std::move(req), lambda); if(ec) return Http_server::fail(ec, "write"); if(close) @@ -279,13 +281,23 @@ Http_server::get_ip_address() //------------------------------------------------------------------------------ +void +Http_server::start_thread() +{ + m_serverThread = std::thread{[this] { open_server(); }}; +} + +//------------------------------------------------------------------------------ + int Http_server::open_server() { try { - auto const address = net::ip::make_address("0.0.0.0"); + // auto const address = net::ip::make_address("0.0.0.0"); + auto const address = net::ip::make_address("127.0.0.1"); auto const port = static_cast(std::atoi("8080")); + auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); // The acceptor receives incoming connections tcp::acceptor acceptor{ioc, {address, port}}; @@ -299,7 +311,7 @@ Http_server::open_server() acceptor.accept(socket); // Launch the session, transferring ownership of the socket - do_session(socket); + do_session(socket, m_docRoot); } } catch (const std::exception& e) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index 3407c539df..f689728b3b 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -125,7 +125,8 @@ class Http_server // Handles an HTTP server connection void do_session( - tcp::socket& socket); + tcp::socket& socket, + std::shared_ptr const& doc_root); //------------------------------------------------------------------------------ @@ -133,11 +134,20 @@ class Http_server //------------------------------------------------------------------------------ - int open_server(); + void + start_thread(); + + //------------------------------------------------------------------------------ + + int + open_server(); + + //------------------------------------------------------------------------------ //void open_server_thread(); std::thread m_serverThread; - std::string m_docRoot; + //std::string m_docRoot; + //auto const m_docRoot = std::make_shared("./build-wasm/"); int m_listenSocket{}; }; From 4e230f4a606f4cdbb59dc13b85f3a57b0717b298 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Thu, 12 Aug 2021 16:18:45 +0200 Subject: [PATCH 07/31] clean code --- .../RemoteControl/Http_server.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 39f75b0278..ece25170a7 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -121,8 +121,6 @@ Http_server::handle_request( return res; }; - QDir::currentPath(); - // Returns a not found response auto const not_found = [&req](beast::string_view target) @@ -131,7 +129,7 @@ Http_server::handle_request( 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 '" + std::string(target) + "' was not found.
Current repository :" + QDir::currentPath().toUtf8().constData() +".
Go to the following address : http://ip_address:port/remote.html."; + res.body() = "The resource '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/remote.html."; res.prepare_payload(); return res; }; @@ -270,12 +268,10 @@ Http_server::get_ip_address() if(!list[nIter].isLoopback()) { if (list[nIter].protocol() == QAbstractSocket::IPv4Protocol ){ - qDebug() << list[nIter].toString(); ip_address = list[nIter].toString().toUtf8().constData(); } } } - return ip_address; } @@ -294,8 +290,8 @@ Http_server::open_server() { try { - // auto const address = net::ip::make_address("0.0.0.0"); - auto const address = net::ip::make_address("127.0.0.1"); + auto const address = net::ip::make_address("0.0.0.0"); + // auto const address = net::ip::make_address("127.0.0.1"); auto const port = static_cast(std::atoi("8080")); auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); From 64ca2ecc5ed2b732433c661f790bcba764576240 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Mon, 16 Aug 2021 10:30:41 +0200 Subject: [PATCH 08/31] get ip address and set in remote.html --- .../RemoteControl/Http_server.cpp | 54 ++++++++++++++----- .../RemoteControl/Http_server.hpp | 7 +++ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index ece25170a7..21c688b64a 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -129,7 +129,7 @@ Http_server::handle_request( 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 '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/remote.html."; + res.body() = "The resource '" + std::string(target) + "' was not found.y
Go to the following address : http://ip_address:port/remote.html."; res.prepare_payload(); return res; }; @@ -259,20 +259,42 @@ Http_server::do_session( std::string Http_server::get_ip_address() { - std::string ip_address; + std::string ip_address = "127.0.0.1"; + std::string tmp_ip_address; + const QHostAddress &localhost = QHostAddress(QHostAddress::LocalHost); + for (const QHostAddress &address: QNetworkInterface::allAddresses()) { + if (address.protocol() == QAbstractSocket::IPv4Protocol && address != localhost) { + tmp_ip_address = address.toString().toUtf8().constData(); + qDebug() << "Address : " << address.toString(); + if((tmp_ip_address.find("192.168")) == 0 || (tmp_ip_address.find("172.16")) == 0 ) { + ip_address = tmp_ip_address; + qDebug() << "Address : " << address.toString(); + } + } + } - QList list = QNetworkInterface::allAddresses(); + return ip_address; +} - for(int nIter=0; nIter(std::atoi("8080")); auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); + set_ip_address(string_address); + // The acceptor receives incoming connections tcp::acceptor acceptor{ioc, {address, port}}; m_listenSocket = acceptor.native_handle(); diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index f689728b3b..aa81f7adfd 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef _WIN32 #define SHUT_RDWR 2 @@ -34,6 +35,7 @@ #include #include #include +#include namespace beast = boost::beast; // from namespace http = beast::http; // from @@ -144,6 +146,11 @@ class Http_server //------------------------------------------------------------------------------ + void + set_ip_address(std::string address); + + //------------------------------------------------------------------------------ + //void open_server_thread(); std::thread m_serverThread; //std::string m_docRoot; From 60e41cf75d516538ae8d894413d343d8a3f6f250 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Mon, 16 Aug 2021 11:13:44 +0200 Subject: [PATCH 09/31] add comments and clean code --- .../RemoteControl/Http_server.cpp | 14 ++++------- .../RemoteControl/Http_server.hpp | 24 ++++++++----------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 21c688b64a..6840917cc3 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -7,16 +7,10 @@ // Official repository: https://github.com/boostorg/beast // -//------------------------------------------------------------------------------ -// -// Example: HTTP server, synchronous -// -//------------------------------------------------------------------------------ - #include //------------------------------------------------------------------------------ -#include + namespace RemoteControl { @@ -256,6 +250,7 @@ Http_server::do_session( //------------------------------------------------------------------------------ +// Get the IP address. It is an heuristic function std::string Http_server::get_ip_address() { @@ -278,6 +273,7 @@ Http_server::get_ip_address() //------------------------------------------------------------------------------ +// Set the IP address in the remote.html file void Http_server::set_ip_address(std::string address) { @@ -299,6 +295,7 @@ Http_server::set_ip_address(std::string address) //------------------------------------------------------------------------------ +// Launch the open_server function in a thread void Http_server::start_thread() { @@ -307,6 +304,7 @@ Http_server::start_thread() //------------------------------------------------------------------------------ +// Open a server using sockets int Http_server::open_server() { @@ -314,8 +312,6 @@ Http_server::open_server() { std::string string_address = get_ip_address(); auto const address = net::ip::make_address(string_address); - //auto const address = net::ip::make_address("192.168.0.40"); - //auto const address = net::ip::make_address("127.0.0.1"); auto const port = static_cast(std::atoi("8080")); auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index aa81f7adfd..317b4a8f56 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -7,11 +7,6 @@ // Official repository: https://github.com/boostorg/beast // -//------------------------------------------------------------------------------ -// -// Example: HTTP server, synchronous -// -//------------------------------------------------------------------------------ #pragma once #define BOOST_DATE_TIME_NO_LIB 1 @@ -36,6 +31,7 @@ #include #include #include +#include namespace beast = boost::beast; // from namespace http = beast::http; // from @@ -132,30 +128,30 @@ class Http_server //------------------------------------------------------------------------------ + // Get the IP address. It is an heuristic function std::string get_ip_address(); //------------------------------------------------------------------------------ + // Set the IP address in the remote.html file void - start_thread(); + set_ip_address(std::string address); //------------------------------------------------------------------------------ - int - open_server(); + // Launch the open_server function in a thread + void + start_thread(); //------------------------------------------------------------------------------ - void - set_ip_address(std::string address); + // Open a server using sockets + int + open_server(); //------------------------------------------------------------------------------ - //void open_server_thread(); std::thread m_serverThread; - //std::string m_docRoot; - //auto const m_docRoot = std::make_shared("./build-wasm/"); - int m_listenSocket{}; }; } From ea4347ae0bde33b1803af0271b71d6482caf3bd8 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Mon, 16 Aug 2021 11:22:07 +0200 Subject: [PATCH 10/31] detect ip address which start with 172. --- .../score-plugin-remotecontrol/RemoteControl/Http_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 6840917cc3..603214aad5 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -261,7 +261,7 @@ Http_server::get_ip_address() if (address.protocol() == QAbstractSocket::IPv4Protocol && address != localhost) { tmp_ip_address = address.toString().toUtf8().constData(); qDebug() << "Address : " << address.toString(); - if((tmp_ip_address.find("192.168")) == 0 || (tmp_ip_address.find("172.16")) == 0 ) { + if((tmp_ip_address.find("192.168")) == 0 || (tmp_ip_address.find("172.")) == 0 ) { ip_address = tmp_ip_address; qDebug() << "Address : " << address.toString(); } From 39640cd7a8ca72e977486ceab813662d4ac26388 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Wed, 18 Aug 2021 12:35:34 +0200 Subject: [PATCH 11/31] detect ip address with socket / set keep_alive = false --- .../RemoteControl/Http_server.cpp | 43 ++++++------------- .../RemoteControl/Http_server.hpp | 5 --- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 603214aad5..dd4d053728 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -180,7 +180,8 @@ Http_server::handle_request( res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, mime_type(path)); res.content_length(size); - res.keep_alive(req.keep_alive()); + //res.keep_alive(req.keep_alive()); + res.keep_alive(false); return send(std::move(res)); } @@ -192,7 +193,8 @@ Http_server::handle_request( res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, mime_type(path)); res.content_length(size); - res.keep_alive(req.keep_alive()); + //res.keep_alive(req.keep_alive()); + res.keep_alive(false); return send(std::move(res)); } @@ -250,29 +252,6 @@ Http_server::do_session( //------------------------------------------------------------------------------ -// Get the IP address. It is an heuristic function -std::string -Http_server::get_ip_address() -{ - std::string ip_address = "127.0.0.1"; - std::string tmp_ip_address; - const QHostAddress &localhost = QHostAddress(QHostAddress::LocalHost); - for (const QHostAddress &address: QNetworkInterface::allAddresses()) { - if (address.protocol() == QAbstractSocket::IPv4Protocol && address != localhost) { - tmp_ip_address = address.toString().toUtf8().constData(); - qDebug() << "Address : " << address.toString(); - if((tmp_ip_address.find("192.168")) == 0 || (tmp_ip_address.find("172.")) == 0 ) { - ip_address = tmp_ip_address; - qDebug() << "Address : " << address.toString(); - } - } - } - - return ip_address; -} - -//------------------------------------------------------------------------------ - // Set the IP address in the remote.html file void Http_server::set_ip_address(std::string address) @@ -310,15 +289,14 @@ Http_server::open_server() { try { - std::string string_address = get_ip_address(); - auto const address = net::ip::make_address(string_address); + auto const address2 = net::ip::make_address("0.0.0.0"); auto const port = static_cast(std::atoi("8080")); auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); - set_ip_address(string_address); + bool is_ip_address_set = false; // The acceptor receives incoming connections - tcp::acceptor acceptor{ioc, {address, port}}; + tcp::acceptor acceptor{ioc, {address2, port}}; m_listenSocket = acceptor.native_handle(); for(;;) { @@ -328,6 +306,13 @@ Http_server::open_server() // Block until we get a connection acceptor.accept(socket); + // Set ip address + if(!is_ip_address_set) + { + set_ip_address(socket.local_endpoint().address().to_string()); + is_ip_address_set = true; + } + // Launch the session, transferring ownership of the socket do_session(socket, m_docRoot); } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index 317b4a8f56..adee0e6a66 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -128,11 +128,6 @@ class Http_server //------------------------------------------------------------------------------ - // Get the IP address. It is an heuristic function - std::string get_ip_address(); - - //------------------------------------------------------------------------------ - // Set the IP address in the remote.html file void set_ip_address(std::string address); From 68c57a4487a2b09453588dd0c90beb72f3975be7 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Wed, 18 Aug 2021 14:21:57 +0200 Subject: [PATCH 12/31] clean code --- .../score-plugin-remotecontrol/RemoteControl/Http_server.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index dd4d053728..a24838cf3f 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -180,7 +180,6 @@ Http_server::handle_request( res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, mime_type(path)); res.content_length(size); - //res.keep_alive(req.keep_alive()); res.keep_alive(false); return send(std::move(res)); } @@ -193,7 +192,6 @@ Http_server::handle_request( res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, mime_type(path)); res.content_length(size); - //res.keep_alive(req.keep_alive()); res.keep_alive(false); return send(std::move(res)); } From 082d7be87b6472e9c757ee69b3ce46c1e5ab6aca Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:41:58 +0200 Subject: [PATCH 13/31] changes from the review --- .../score-plugin-remotecontrol/CMakeLists.txt | 2 +- .../RemoteControl/ApplicationPlugin.cpp | 6 ++++++ .../RemoteControl/ApplicationPlugin.hpp | 1 + .../RemoteControl/Http_server.cpp | 15 +++++++++++---- .../RemoteControl/Http_server.hpp | 1 + 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt index 75774c040b..b654198007 100644 --- a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt +++ b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt @@ -64,7 +64,7 @@ set(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.cpp" ) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/build-wasm/ DESTINATION ${CMAKE_BINARY_DIR}/src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/) +#file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/build-wasm/ DESTINATION ${CMAKE_BINARY_DIR}/src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/) add_library(${PROJECT_NAME} ${SRCS} ${HDRS} ${QRCS}) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp index 6b1de100ca..6f4a3576e4 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp @@ -19,6 +19,12 @@ ApplicationPlugin::ApplicationPlugin(const score::GUIApplicationContext& app) { } +ApplicationPlugin::~ApplicationPlugin() +{ + std::remove((m_server.m_buildWasmPath + "remote.html").c_str()); + std::rename((m_server.m_buildWasmPath + "remote.html~").c_str(), (m_server.m_buildWasmPath + "remote.html").c_str()); +} + void ApplicationPlugin::on_createdDocument(score::Document& doc) { doc.model().addPluginModel(new WS::DocumentPlugin{doc.context(), &doc.model()}); diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp index 9e119eff29..d8de745e5a 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp @@ -8,6 +8,7 @@ class ApplicationPlugin final : public score::GUIApplicationPlugin { public: ApplicationPlugin(const score::GUIApplicationContext& app); + ~ApplicationPlugin(); protected: void on_createdDocument(score::Document& doc) override; diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index a24838cf3f..847286fbab 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -254,11 +254,11 @@ Http_server::do_session( void Http_server::set_ip_address(std::string address) { - std::rename("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/remote.html", - "./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/remote.html~"); + qDebug() << "buildWasmPath :" << QString::fromStdString(m_buildWasmPath); + std::rename((m_buildWasmPath + "remote.html").c_str(), (m_buildWasmPath + "remote.html~").c_str()); - std::ifstream old_file("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/remote.html~"); - std::ofstream new_file("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/remote.html"); + std::ifstream old_file(m_buildWasmPath + "remote.html~"); + std::ofstream new_file(m_buildWasmPath + "remote.html"); std::string addr = "\"" + address + "\""; @@ -289,7 +289,14 @@ Http_server::open_server() { auto const address2 = net::ip::make_address("0.0.0.0"); auto const port = static_cast(std::atoi("8080")); +<<<<<<< HEAD:src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); +======= + std::string packagesPath = score::AppContext().settings().getPackagesPath().toStdString(); + qDebug() << "packagesPath :" << QString::fromStdString(packagesPath); + m_buildWasmPath = packagesPath + "/build-wasm/"; + auto const m_docRoot = std::make_shared(m_buildWasmPath); +>>>>>>> c8b914cd2 (changes from the review):src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer.cpp bool is_ip_address_set = false; diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index adee0e6a66..3628353566 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -148,5 +148,6 @@ class Http_server std::thread m_serverThread; int m_listenSocket{}; + std::string m_buildWasmPath; }; } From 086141092be9f4fd420b3ba1e3a0ea260c21d371 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Fri, 20 Aug 2021 22:09:11 +0200 Subject: [PATCH 14/31] load remote.html, read and write ip address --- .../RemoteControl/ApplicationPlugin.cpp | 4 ++-- .../RemoteControl/Http_server.cpp | 21 ++++++++++++++++++- .../RemoteControl/Http_server.hpp | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp index 6f4a3576e4..07d51f4292 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp @@ -21,8 +21,8 @@ ApplicationPlugin::ApplicationPlugin(const score::GUIApplicationContext& app) ApplicationPlugin::~ApplicationPlugin() { - std::remove((m_server.m_buildWasmPath + "remote.html").c_str()); - std::rename((m_server.m_buildWasmPath + "remote.html~").c_str(), (m_server.m_buildWasmPath + "remote.html").c_str()); + //std::remove((m_server.m_buildWasmPath + "remote.html").c_str()); + //std::rename((m_server.m_buildWasmPath + "remote.html~").c_str(), (m_server.m_buildWasmPath + "remote.html").c_str()); } void ApplicationPlugin::on_createdDocument(score::Document& doc) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 847286fbab..638f086227 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -160,6 +160,7 @@ Http_server::handle_request( // Attempt to open the file beast::error_code ec; http::file_body::value_type body; + body.open(path.c_str(), beast::file_mode::scan, ec); // Handle the case where the file doesn't exist @@ -173,6 +174,21 @@ Http_server::handle_request( // Cache the size since we need it after the move auto const size = body.size(); + if ( req.target().find("remote.html") != std::string::npos ) + { + qDebug() << "Path name:" << req.target().data(); + QFile f(path.c_str()); + f.open(QIODevice::ReadOnly); + QByteArray remote = f.readAll(); + std::string string_remote = remote.toStdString(); + qDebug() << QString::fromStdString(string_remote); + std::string::size_type position = string_remote.find("%SCORE_IP_ADDRESS%"); + std::string address = "192.168.0.40"; + std::string addr = "\"" + address + "\""; + string_remote = string_remote.replace(position, 18, addr); + qDebug() << QString::fromStdString(string_remote); + } + // Respond to HEAD request if(req.method() == http::verb::head) { @@ -265,7 +281,10 @@ Http_server::set_ip_address(std::string address) for( std::string contents_of_file; std::getline(old_file, contents_of_file); ) { std::string::size_type position = contents_of_file.find("%SCORE_IP_ADDRESS%"); if( position != std::string::npos ) - contents_of_file = contents_of_file.replace(position, 18, addr); + { + //contents_of_file = contents_of_file.replace(position, 18, addr); + contents_of_file = contents_of_file.replace(position, 18, "%SCORE_IP_ADDRESS%"); + } new_file << contents_of_file << '\n'; } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index 3628353566..f0025a0d69 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace beast = boost::beast; // from namespace http = beast::http; // from From 1bbdf605ea739066789074d10859b3b58a06f483 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Fri, 20 Aug 2021 22:12:27 +0200 Subject: [PATCH 15/31] Update CMakeLists.txt --- src/plugins/score-plugin-remotecontrol/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt index b654198007..4c7e231e7b 100644 --- a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt +++ b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt @@ -64,8 +64,6 @@ set(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.cpp" ) -#file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/build-wasm/ DESTINATION ${CMAKE_BINARY_DIR}/src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/) - add_library(${PROJECT_NAME} ${SRCS} ${HDRS} ${QRCS}) target_link_libraries(${PROJECT_NAME} PUBLIC score_plugin_scenario score_plugin_js ${QT_PREFIX}::WebSockets ossia) From f53c43dc2a7aef28e6edbd78a7966e75f5fea15a Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Fri, 20 Aug 2021 22:12:55 +0200 Subject: [PATCH 16/31] Update ApplicationPlugin.cpp --- .../RemoteControl/ApplicationPlugin.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp index 07d51f4292..6b1de100ca 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp @@ -19,12 +19,6 @@ ApplicationPlugin::ApplicationPlugin(const score::GUIApplicationContext& app) { } -ApplicationPlugin::~ApplicationPlugin() -{ - //std::remove((m_server.m_buildWasmPath + "remote.html").c_str()); - //std::rename((m_server.m_buildWasmPath + "remote.html~").c_str(), (m_server.m_buildWasmPath + "remote.html").c_str()); -} - void ApplicationPlugin::on_createdDocument(score::Document& doc) { doc.model().addPluginModel(new WS::DocumentPlugin{doc.context(), &doc.model()}); From 53f134a3f52935d670c98dd7393fe1f817db2141 Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Fri, 20 Aug 2021 22:13:25 +0200 Subject: [PATCH 17/31] Update ApplicationPlugin.hpp --- .../RemoteControl/ApplicationPlugin.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp index d8de745e5a..9e119eff29 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp @@ -8,7 +8,6 @@ class ApplicationPlugin final : public score::GUIApplicationPlugin { public: ApplicationPlugin(const score::GUIApplicationContext& app); - ~ApplicationPlugin(); protected: void on_createdDocument(score::Document& doc) override; From daa4d2bd012e04d94ce5e0e3e9b5e7a7f553d9af Mon Sep 17 00:00:00 2001 From: Toine-ddt <65868237+Toine-ddt@users.noreply.github.com> Date: Fri, 20 Aug 2021 22:22:20 +0200 Subject: [PATCH 18/31] clean code --- .../RemoteControl/Http_server.cpp | 14 ++++++-------- .../RemoteControl/Http_server.hpp | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 638f086227..6af5b458a4 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -176,17 +176,16 @@ Http_server::handle_request( if ( req.target().find("remote.html") != std::string::npos ) { - qDebug() << "Path name:" << req.target().data(); + // Load file QFile f(path.c_str()); f.open(QIODevice::ReadOnly); QByteArray remote = f.readAll(); + + // Write ip address in the std::string std::string string_remote = remote.toStdString(); - qDebug() << QString::fromStdString(string_remote); std::string::size_type position = string_remote.find("%SCORE_IP_ADDRESS%"); - std::string address = "192.168.0.40"; - std::string addr = "\"" + address + "\""; + std::string addr = "\"" + m_ipAddress + "\""; string_remote = string_remote.replace(position, 18, addr); - qDebug() << QString::fromStdString(string_remote); } // Respond to HEAD request @@ -276,7 +275,7 @@ Http_server::set_ip_address(std::string address) std::ifstream old_file(m_buildWasmPath + "remote.html~"); std::ofstream new_file(m_buildWasmPath + "remote.html"); - std::string addr = "\"" + address + "\""; + std::string addr = "\"" + m_ipAddress + "\""; for( std::string contents_of_file; std::getline(old_file, contents_of_file); ) { std::string::size_type position = contents_of_file.find("%SCORE_IP_ADDRESS%"); @@ -312,7 +311,6 @@ Http_server::open_server() auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); ======= std::string packagesPath = score::AppContext().settings().getPackagesPath().toStdString(); - qDebug() << "packagesPath :" << QString::fromStdString(packagesPath); m_buildWasmPath = packagesPath + "/build-wasm/"; auto const m_docRoot = std::make_shared(m_buildWasmPath); >>>>>>> c8b914cd2 (changes from the review):src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer.cpp @@ -333,7 +331,7 @@ Http_server::open_server() // Set ip address if(!is_ip_address_set) { - set_ip_address(socket.local_endpoint().address().to_string()); + m_ipAddress = socket.local_endpoint().address().to_string(); is_ip_address_set = true; } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index f0025a0d69..e4a8d151ee 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -150,5 +150,6 @@ class Http_server std::thread m_serverThread; int m_listenSocket{}; std::string m_buildWasmPath; + std::string m_ipAddress; }; } From 371393d30c2c68b9f29eb208b55958744e6099f6 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Fri, 3 Jul 2026 23:45:40 +0100 Subject: [PATCH 19/31] [remote] update path for new qml-remote --- .../RemoteControl/Http_server.cpp | 14 ++++++++------ .../RemoteControl/Http_server.hpp | 4 +--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 6af5b458a4..8ec971f21b 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -7,8 +7,14 @@ // Official repository: https://github.com/boostorg/beast // +#include #include +#include +#include +#include + + //------------------------------------------------------------------------------ namespace RemoteControl @@ -174,7 +180,7 @@ Http_server::handle_request( // Cache the size since we need it after the move auto const size = body.size(); - if ( req.target().find("remote.html") != std::string::npos ) + if ( req.target().find("ossia_remote.html") != std::string::npos ) { // Load file QFile f(path.c_str()); @@ -307,13 +313,9 @@ Http_server::open_server() { auto const address2 = net::ip::make_address("0.0.0.0"); auto const port = static_cast(std::atoi("8080")); -<<<<<<< HEAD:src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp - auto const m_docRoot = std::make_shared("./src/plugins/score-plugin-remotecontrol/CMakeFiles/score_plugin_remotecontrol.dir/RemoteControl/build-wasm/"); -======= std::string packagesPath = score::AppContext().settings().getPackagesPath().toStdString(); - m_buildWasmPath = packagesPath + "/build-wasm/"; + m_buildWasmPath = packagesPath + "/wasm-remote/"; auto const m_docRoot = std::make_shared(m_buildWasmPath); ->>>>>>> c8b914cd2 (changes from the review):src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer.cpp bool is_ip_address_set = false; diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp index e4a8d151ee..5d3162b970 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp @@ -16,12 +16,10 @@ #include #include #include -#include -#include + #include #include #include -#include #ifdef _WIN32 #define SHUT_RDWR 2 From 31beb647e64a44c971cfe88ba302aa6d4cdd7b43 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Mon, 6 Jul 2026 14:59:00 +0100 Subject: [PATCH 20/31] [http_server] setup server for autoconnect .was remote --- .../RemoteControl/Http_server.cpp | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp index 8ec971f21b..0b3bd715eb 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp @@ -53,6 +53,7 @@ Http_server::mime_type(beast::string_view path) if(iequals(ext, ".json")) return "application/json"; if(iequals(ext, ".xml")) return "application/xml"; if(iequals(ext, ".swf")) return "application/x-shockwave-flash"; + if(iequals(ext, ".wasm")) return "application/wasm"; if(iequals(ext, ".flv")) return "video/x-flv"; if(iequals(ext, ".png")) return "image/png"; if(iequals(ext, ".jpe")) return "image/jpeg"; @@ -129,7 +130,7 @@ Http_server::handle_request( 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 '" + std::string(target) + "' was not found.y
Go to the following address : http://ip_address:port/remote.html."; + res.body() = "The resource '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/ossia_remote.html."; res.prepare_payload(); return res; }; @@ -180,20 +181,6 @@ Http_server::handle_request( // Cache the size since we need it after the move auto const size = body.size(); - if ( req.target().find("ossia_remote.html") != std::string::npos ) - { - // Load file - QFile f(path.c_str()); - f.open(QIODevice::ReadOnly); - QByteArray remote = f.readAll(); - - // Write ip address in the std::string - std::string string_remote = remote.toStdString(); - std::string::size_type position = string_remote.find("%SCORE_IP_ADDRESS%"); - std::string addr = "\"" + m_ipAddress + "\""; - string_remote = string_remote.replace(position, 18, addr); - } - // Respond to HEAD request if(req.method() == http::verb::head) { @@ -210,6 +197,12 @@ Http_server::handle_request( std::piecewise_construct, std::make_tuple(std::move(body)), std::make_tuple(http::status::ok, req.version())}; + + // Allow Cross-Origin Resource Sharing (CORS). + res.set(http::field::access_control_allow_headers, "*"); + res.set(http::field::access_control_allow_origin, "*"); + res.set(http::field::access_control_allow_methods, "GET"); + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, mime_type(path)); res.content_length(size); @@ -343,7 +336,7 @@ Http_server::open_server() } catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << std::endl; + std::cerr << "Error: " << e.what() << '\n'; return EXIT_FAILURE; } } From a98fb0701e6a4a2ba95f823f79089fa0f8ae09d6 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Wed, 8 Jul 2026 00:19:55 +0100 Subject: [PATCH 21/31] [RemoteControl] begin re-structuring Http_server --- .../score-plugin-remotecontrol/CMakeLists.txt | 6 +- .../RemoteControl/ApplicationPlugin.cpp | 5 +- .../RemoteControl/ApplicationPlugin.hpp | 2 - .../HttpServer/DocumentPlugin.cpp | 26 ++++++++ .../HttpServer/DocumentPlugin.hpp | 19 ++++++ .../{ => HttpServer}/Http_server.cpp | 65 ++++++++++--------- .../{ => HttpServer}/Http_server.hpp | 12 +++- .../RemoteControl/Settings/Model.cpp | 8 ++- .../RemoteControl/Settings/Model.hpp | 12 +++- .../RemoteControl/Settings/Presenter.cpp | 9 +++ .../RemoteControl/Settings/View.cpp | 37 +++++++++++ .../RemoteControl/Settings/View.hpp | 3 + 12 files changed, 163 insertions(+), 41 deletions(-) create mode 100644 src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp create mode 100644 src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp rename src/plugins/score-plugin-remotecontrol/RemoteControl/{ => HttpServer}/Http_server.cpp (89%) rename src/plugins/score-plugin-remotecontrol/RemoteControl/{ => HttpServer}/Http_server.hpp (94%) diff --git a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt index 4c7e231e7b..1a30a39b1b 100644 --- a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt +++ b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt @@ -38,7 +38,8 @@ set(HDRS "${CMAKE_CURRENT_SOURCE_DIR}/i-score-remote/RemoteApplication.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/Http_server.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/DocumentPlugin.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/Http_server.hpp" ) set(SRCS @@ -59,7 +60,8 @@ set(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/ApplicationPlugin.cpp" -"${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/Http_server.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/DocumentPlugin.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/Http_server.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.cpp" ) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp index 6b1de100ca..3e2af491bb 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace RemoteControl @@ -24,8 +25,8 @@ void ApplicationPlugin::on_createdDocument(score::Document& doc) doc.model().addPluginModel(new WS::DocumentPlugin{doc.context(), &doc.model()}); doc.model().addPluginModel( new Controller::DocumentPlugin{doc.context(), &doc.model()}); - - m_server.start_thread(); + doc.model().addPluginModel( + new HttpServer::DocumentPlugin{doc.context(), &doc.model()}); } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp index 9e119eff29..1e562545ea 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/ApplicationPlugin.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include namespace RemoteControl { class ApplicationPlugin final : public score::GUIApplicationPlugin @@ -11,6 +10,5 @@ class ApplicationPlugin final : public score::GUIApplicationPlugin protected: void on_createdDocument(score::Document& doc) override; - Http_server m_server; }; } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp new file mode 100644 index 0000000000..a122a4213d --- /dev/null +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp @@ -0,0 +1,26 @@ +#include "DocumentPlugin.hpp" +#include + +#include + +namespace RemoteControl::HttpServer +{ +DocumentPlugin::DocumentPlugin(const score::DocumentContext& doc, QObject* parent) + : score::DocumentPlugin{doc, "RemoteControl::HttpServer::DocumentPlugin", parent} +{ + auto& model{m_context.app.settings()}; + + if (model.getServerEnabled()) + m_server.start_thread(); + + con(model + , &Settings::Model::ServerEnabledChanged + , this + , [this] (bool e) + { e ? m_server.start_thread() : m_server.stop_thread(); } + , Qt::QueuedConnection); +} + +DocumentPlugin::~DocumentPlugin() { } + +} // namespace RemoteControl::HttpServer \ No newline at end of file diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp new file mode 100644 index 0000000000..30fb6168f1 --- /dev/null +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "Http_server.hpp" + +#include +#include + +namespace RemoteControl::HttpServer +{ +struct SCORE_PLUGIN_REMOTECONTROL_EXPORT DocumentPlugin : score::DocumentPlugin +{ +public: + DocumentPlugin(const score::DocumentContext& doc, QObject* parent); + ~DocumentPlugin(); + +private: + Http_server m_server; +}; + +} // namespace RemoteControl::HttpServer \ No newline at end of file diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp similarity index 89% rename from src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp rename to src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp index 0b3bd715eb..310855b615 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp @@ -7,8 +7,8 @@ // Official repository: https://github.com/boostorg/beast // +#include "Http_server.hpp" #include -#include #include #include @@ -21,15 +21,11 @@ namespace RemoteControl { Http_server::Http_server() -{ - // m_docRoot = "/tmp"; -} +{ } Http_server::~Http_server() { - shutdown(m_listenSocket, SHUT_RDWR); - ioc.stop(); - m_serverThread.join(); + stop_thread(); } // Return a reasonable mime type based on the extension of a file. @@ -264,28 +260,28 @@ Http_server::do_session( //------------------------------------------------------------------------------ -// Set the IP address in the remote.html file -void -Http_server::set_ip_address(std::string address) -{ - qDebug() << "buildWasmPath :" << QString::fromStdString(m_buildWasmPath); - std::rename((m_buildWasmPath + "remote.html").c_str(), (m_buildWasmPath + "remote.html~").c_str()); - - std::ifstream old_file(m_buildWasmPath + "remote.html~"); - std::ofstream new_file(m_buildWasmPath + "remote.html"); - - std::string addr = "\"" + m_ipAddress + "\""; - - for( std::string contents_of_file; std::getline(old_file, contents_of_file); ) { - std::string::size_type position = contents_of_file.find("%SCORE_IP_ADDRESS%"); - if( position != std::string::npos ) - { - //contents_of_file = contents_of_file.replace(position, 18, addr); - contents_of_file = contents_of_file.replace(position, 18, "%SCORE_IP_ADDRESS%"); - } - new_file << contents_of_file << '\n'; - } -} +// // Set the IP address in the remote.html file +// void +// Http_server::set_ip_address(std::string address) +// { +// qDebug() << "buildWasmPath :" << QString::fromStdString(m_buildWasmPath); +// std::rename((m_buildWasmPath + "remote.html").c_str(), (m_buildWasmPath + "remote.html~").c_str()); + +// std::ifstream old_file(m_buildWasmPath + "remote.html~"); +// std::ofstream new_file(m_buildWasmPath + "remote.html"); + +// std::string addr = "\"" + m_ipAddress + "\""; + +// for( std::string contents_of_file; std::getline(old_file, contents_of_file); ) { +// std::string::size_type position = contents_of_file.find("%SCORE_IP_ADDRESS%"); +// if( position != std::string::npos ) +// { +// //contents_of_file = contents_of_file.replace(position, 18, addr); +// contents_of_file = contents_of_file.replace(position, 18, "%SCORE_IP_ADDRESS%"); +// } +// new_file << contents_of_file << '\n'; +// } +// } //------------------------------------------------------------------------------ @@ -298,6 +294,17 @@ Http_server::start_thread() //------------------------------------------------------------------------------ +void Http_server::stop_thread() +{ + if (!m_serverThread.joinable()) return; + + shutdown(m_listenSocket, SHUT_RDWR); + ioc.stop(); + m_serverThread.join(); +} + +//------------------------------------------------------------------------------ + // Open a server using sockets int Http_server::open_server() diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp similarity index 94% rename from src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp rename to src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp index 5d3162b970..08b6fe1c8b 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp @@ -127,9 +127,9 @@ class Http_server //------------------------------------------------------------------------------ - // Set the IP address in the remote.html file - void - set_ip_address(std::string address); + // // Set the IP address in the remote.html file + // set_ip_address(std::string address); + // void //------------------------------------------------------------------------------ @@ -139,6 +139,12 @@ class Http_server //------------------------------------------------------------------------------ + // Launch the open_server function in a thread + void + stop_thread(); + + //------------------------------------------------------------------------------ + // Open a server using sockets int open_server(); diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp index 034945b651..d8e9fa57d9 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp @@ -12,9 +12,12 @@ namespace Settings namespace Parameters { SETTINGS_PARAMETER_IMPL(Enabled){QStringLiteral("RemoteControl/Enabled"), false}; +SETTINGS_PARAMETER_IMPL(ServerEnabled){QStringLiteral("RemoteControl/ServerEnabled"), false}; +SETTINGS_PARAMETER_IMPL(ServerAddress){QStringLiteral("RemoteControl/ServerAddress"), "0.0.0.0"}; +SETTINGS_PARAMETER_IMPL(ServerPort){QStringLiteral("RemoteControl/ServerPort"), 8080}; static auto list() { - return std::tie(Enabled); + return std::tie(Enabled, ServerEnabled, ServerAddress, ServerPort); } } @@ -27,5 +30,8 @@ Model::Model( } SCORE_SETTINGS_PARAMETER_CPP(bool, Model, Enabled) +SCORE_SETTINGS_PARAMETER_CPP(bool, Model, ServerEnabled) +SCORE_SETTINGS_PARAMETER_CPP(QString, Model, ServerAddress) +SCORE_SETTINGS_PARAMETER_CPP(unsigned short, Model, ServerPort) } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp index 49c01155f1..79d1ba72dd 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp @@ -10,7 +10,10 @@ namespace Settings class SCORE_PLUGIN_REMOTECONTROL_EXPORT Model : public score::SettingsDelegateModel { W_OBJECT(Model) - bool m_Enabled = false; + bool m_Enabled{false}; + bool m_ServerEnabled{false}; + QString m_ServerAddress{"0.0.0.0"}; + unsigned short m_ServerPort{8080}; public: Model( @@ -18,9 +21,14 @@ class SCORE_PLUGIN_REMOTECONTROL_EXPORT Model : public score::SettingsDelegateMo const score::ApplicationContext& ctx); SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, bool, Enabled) + SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, bool, ServerEnabled) + SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, QString, ServerAddress) + SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, unsigned short, ServerPort) }; SCORE_SETTINGS_PARAMETER(Model, Enabled) - +SCORE_SETTINGS_PARAMETER(Model, ServerEnabled) +SCORE_SETTINGS_PARAMETER(Model, ServerAddress) +SCORE_SETTINGS_PARAMETER(Model, ServerPort) } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp index d079eb9728..611a06e3d1 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp @@ -27,11 +27,20 @@ Presenter::Presenter(Model& m, View& v, QObject* parent) } }); + con(v, &View::serverEnabledChanged, this, [&](auto val) { + if(val != m.getServerEnabled()) + { + m_disp.submit(this->model(this), val); + } + }); + // model -> view con(m, &Model::EnabledChanged, &v, &View::setEnabled); + con(m, &Model::ServerEnabledChanged, &v, &View::setServerEnabled); // initial value v.setEnabled(m.getEnabled()); + v.setServerEnabled(m.getServerEnabled()); } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp index 3de1d02c8f..3137762c4e 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp @@ -37,6 +37,26 @@ View::View() lay->addRow(m_enabled); } + + { + m_server_enabled = new QCheckBox{tr("Enable HTTP server")}; + + connect(m_server_enabled, SignalUtils::QCheckBox_checkStateChanged(), this, [&](int t) { + switch(t) + { + case Qt::Unchecked: + serverEnabledChanged(false); + break; + case Qt::Checked: + serverEnabledChanged(true); + break; + default: + break; + } + }); + + lay->addRow(m_server_enabled); + } } void View::setEnabled(bool val) @@ -56,6 +76,23 @@ void View::setEnabled(bool val) } } +void View::setServerEnabled(bool val) +{ + switch(m_server_enabled->checkState()) + { + case Qt::Unchecked: + if(val) + m_server_enabled->setChecked(true); + break; + case Qt::Checked: + if(!val) + m_server_enabled->setChecked(false); + break; + default: + break; + } +} + QWidget* View::getWidget() { return m_widg; diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp index 93171f6b70..18ea67a039 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp @@ -19,14 +19,17 @@ class View : public score::GlobalSettingsView public: View(); void setEnabled(bool); + void setServerEnabled(bool); void enabledChanged(bool b) W_SIGNAL(enabledChanged, b); + void serverEnabledChanged(bool b) W_SIGNAL(serverEnabledChanged, b); private: QWidget* getWidget() override; score::FormWidget* m_widg{}; QCheckBox* m_enabled{}; + QCheckBox* m_server_enabled{}; }; } From 76c5886329b21a738362e043a2eafa6ef01530e5 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Thu, 9 Jul 2026 23:44:25 +0100 Subject: [PATCH 22/31] [remote control] all settings --- .../RemoteControl/Settings/Model.cpp | 14 ++-- .../RemoteControl/Settings/Model.hpp | 7 +- .../RemoteControl/Settings/Presenter.cpp | 27 ++++++++ .../RemoteControl/Settings/View.cpp | 68 ++++++++++++++++++- .../RemoteControl/Settings/View.hpp | 13 ++++ 5 files changed, 122 insertions(+), 7 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp index d8e9fa57d9..2dd6d8bec1 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp @@ -12,26 +12,32 @@ namespace Settings namespace Parameters { SETTINGS_PARAMETER_IMPL(Enabled){QStringLiteral("RemoteControl/Enabled"), false}; -SETTINGS_PARAMETER_IMPL(ServerEnabled){QStringLiteral("RemoteControl/ServerEnabled"), false}; +SETTINGS_PARAMETER_IMPL(WebUiPath){QStringLiteral("RemoteControl/WebUiPath"), ""}; SETTINGS_PARAMETER_IMPL(ServerAddress){QStringLiteral("RemoteControl/ServerAddress"), "0.0.0.0"}; SETTINGS_PARAMETER_IMPL(ServerPort){QStringLiteral("RemoteControl/ServerPort"), 8080}; +SETTINGS_PARAMETER_IMPL(ServerEnabled){QStringLiteral("RemoteControl/ServerEnabled"), false}; static auto list() { - return std::tie(Enabled, ServerEnabled, ServerAddress, ServerPort); + return std::tie(Enabled + , WebUiPath + , ServerAddress + , ServerPort + , ServerEnabled); } } Model::Model( const UuidKey& k, QSettings& set, const score::ApplicationContext& ctx) - : score::SettingsDelegateModel{k, nullptr} + : score::SettingsDelegateModel{k, nullptr} { score::setupDefaultSettings(set, Parameters::list(), *this); } SCORE_SETTINGS_PARAMETER_CPP(bool, Model, Enabled) -SCORE_SETTINGS_PARAMETER_CPP(bool, Model, ServerEnabled) +SCORE_SETTINGS_PARAMETER_CPP(QString, Model, WebUiPath) SCORE_SETTINGS_PARAMETER_CPP(QString, Model, ServerAddress) SCORE_SETTINGS_PARAMETER_CPP(unsigned short, Model, ServerPort) +SCORE_SETTINGS_PARAMETER_CPP(bool, Model, ServerEnabled) } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp index 79d1ba72dd..ad0bd1fa28 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.hpp @@ -12,6 +12,7 @@ class SCORE_PLUGIN_REMOTECONTROL_EXPORT Model : public score::SettingsDelegateMo W_OBJECT(Model) bool m_Enabled{false}; bool m_ServerEnabled{false}; + QString m_WebUiPath{}; QString m_ServerAddress{"0.0.0.0"}; unsigned short m_ServerPort{8080}; @@ -21,14 +22,16 @@ class SCORE_PLUGIN_REMOTECONTROL_EXPORT Model : public score::SettingsDelegateMo const score::ApplicationContext& ctx); SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, bool, Enabled) - SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, bool, ServerEnabled) + SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, QString, WebUiPath) SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, QString, ServerAddress) SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, unsigned short, ServerPort) + SCORE_SETTINGS_PARAMETER_HPP(SCORE_PLUGIN_REMOTECONTROL_EXPORT, bool, ServerEnabled) }; SCORE_SETTINGS_PARAMETER(Model, Enabled) -SCORE_SETTINGS_PARAMETER(Model, ServerEnabled) +SCORE_SETTINGS_PARAMETER(Model, WebUiPath) SCORE_SETTINGS_PARAMETER(Model, ServerAddress) SCORE_SETTINGS_PARAMETER(Model, ServerPort) +SCORE_SETTINGS_PARAMETER(Model, ServerEnabled) } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp index 611a06e3d1..bc60258824 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Presenter.cpp @@ -27,6 +27,27 @@ Presenter::Presenter(Model& m, View& v, QObject* parent) } }); + con(v, &View::webUiPathChanged, this, [&](auto val) { + if(val != m.getWebUiPath()) + { + m_disp.submit(this->model(this), val); + } + }); + + con(v, &View::serverAddressChanged, this, [&](auto val) { + if(val != m.getServerAddress()) + { + m_disp.submit(this->model(this), val); + } + }); + + con(v, &View::serverPortChanged, this, [&](auto val) { + if(val != m.getServerPort()) + { + m_disp.submit(this->model(this), val); + } + }); + con(v, &View::serverEnabledChanged, this, [&](auto val) { if(val != m.getServerEnabled()) { @@ -36,10 +57,16 @@ Presenter::Presenter(Model& m, View& v, QObject* parent) // model -> view con(m, &Model::EnabledChanged, &v, &View::setEnabled); + con(m, &Model::WebUiPathChanged, &v, &View::setWebUiPath); + con(m, &Model::ServerAddressChanged, &v, &View::setServerAddress); + con(m, &Model::ServerPortChanged, &v, &View::setServerPort); con(m, &Model::ServerEnabledChanged, &v, &View::setServerEnabled); // initial value v.setEnabled(m.getEnabled()); + v.setWebUiPath(m.getWebUiPath()); + v.setServerAddress(m.getServerAddress()); + v.setServerPort(m.getServerPort()); v.setServerEnabled(m.getServerEnabled()); } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp index 3137762c4e..1403bf9e45 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp @@ -1,10 +1,15 @@ #include "View.hpp" +#include "score/widgets/MarginLess.hpp" #include #include +#include #include #include +#include +#include +#include #include W_OBJECT_IMPL(RemoteControl::Settings::View) @@ -39,6 +44,48 @@ View::View() } { + m_web_ui = new score::FormWidget{tr("Web UI")}; + auto web_lay = m_web_ui->layout(); + + auto subw{new QWidget}; + auto sublay{new score::MarginLess{subw}}; + m_web_ui_path = new QLineEdit{}; + + auto browse{new QPushButton{tr("Browse...")}}; + browse->setMaximumWidth(100); + + const QString webUiPath{score::AppContext() + .settings() + .getPackagesPath() + + "/wasm-remote/"}; + + connect(browse, &QPushButton::clicked, this, [this, webUiPath] + { + auto f{QFileDialog::getExistingDirectory( + nullptr, tr("Web UI folder"), webUiPath)}; + if(!f.isEmpty()) + { + webUiPathChanged(f); + } + }); + + sublay->addWidget(m_web_ui_path); + sublay->addWidget(browse); + web_lay->addRow(tr("Web UI folder"), subw); + + subw = new QWidget; + sublay = new score::MarginLess{subw}; + m_server_address = new QLineEdit{}; + m_server_address->setPlaceholderText("0.0.0.0"); + + m_server_port = new QSpinBox{}; + m_server_port->setRange(0, 9999); + m_server_port->setMinimumWidth(200); + + sublay->addWidget(m_server_address); + sublay->addWidget(m_server_port); + web_lay->addRow(tr("HTTP server address/port"), subw); + m_server_enabled = new QCheckBox{tr("Enable HTTP server")}; connect(m_server_enabled, SignalUtils::QCheckBox_checkStateChanged(), this, [&](int t) { @@ -55,7 +102,8 @@ View::View() } }); - lay->addRow(m_server_enabled); + web_lay->addRow(m_server_enabled); + lay->addRow(m_web_ui); } } @@ -76,6 +124,24 @@ void View::setEnabled(bool val) } } +void View::setWebUiPath(const QString& val) +{ + if (val != m_web_ui_path->displayText()) + m_web_ui_path->setText(val); +} + +void View::setServerAddress(const QString& val) +{ + if (val != m_server_address->displayText()) + m_server_address->setText(val); +} + +void View::setServerPort(unsigned short val) +{ + if (val != m_server_port->value()) + m_server_port->setValue(val); +} + void View::setServerEnabled(bool val) { switch(m_server_enabled->checkState()) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp index 18ea67a039..cdf0d4b8ca 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.hpp @@ -3,6 +3,8 @@ #include class QCheckBox; +class QLineEdit; +class QVBoxLayout; namespace score { @@ -19,9 +21,15 @@ class View : public score::GlobalSettingsView public: View(); void setEnabled(bool); + void setWebUiPath(const QString&); + void setServerAddress(const QString&); + void setServerPort(unsigned short); void setServerEnabled(bool); void enabledChanged(bool b) W_SIGNAL(enabledChanged, b); + void webUiPathChanged(QString s) W_SIGNAL(webUiPathChanged, s); + void serverAddressChanged(QString s) W_SIGNAL(serverAddressChanged, s); + void serverPortChanged(unsigned short s) W_SIGNAL(serverPortChanged, s); void serverEnabledChanged(bool b) W_SIGNAL(serverEnabledChanged, b); private: @@ -29,6 +37,11 @@ class View : public score::GlobalSettingsView score::FormWidget* m_widg{}; QCheckBox* m_enabled{}; + + score::FormWidget* m_web_ui{}; + QLineEdit* m_web_ui_path{}; + QLineEdit* m_server_address{}; + QSpinBox* m_server_port{}; QCheckBox* m_server_enabled{}; }; From 5a2e645b43b3a57590e24985ad01ad53d4f777db Mon Sep 17 00:00:00 2001 From: thibaudk Date: Fri, 10 Jul 2026 15:24:53 +0100 Subject: [PATCH 23/31] [remote control] more settings for the HTTP_server --- .../RemoteControl/Settings/Model.cpp | 14 ++++++++++++++ .../RemoteControl/Settings/View.cpp | 19 ++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp index 2dd6d8bec1..f103ca2571 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp @@ -1,6 +1,9 @@ #include "Model.hpp" +#include + #include +#include #include W_OBJECT_IMPL(RemoteControl::Settings::Model) @@ -32,6 +35,17 @@ Model::Model( : score::SettingsDelegateModel{k, nullptr} { score::setupDefaultSettings(set, Parameters::list(), *this); + + if (m_WebUiPath.isEmpty()) + { + const auto path{score::AppContext() + .settings() + .getPackagesPath() + + "/wasm-remote/"}; + + if (QDir{path}.exists()) + setWebUiPath(path); + } } SCORE_SETTINGS_PARAMETER_CPP(bool, Model, Enabled) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp index 1403bf9e45..2c23702ace 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -31,9 +30,11 @@ View::View() { case Qt::Unchecked: enabledChanged(false); + m_web_ui->setEnabled(false); break; case Qt::Checked: enabledChanged(true); + m_web_ui->setEnabled(true); break; default: break; @@ -54,19 +55,11 @@ View::View() auto browse{new QPushButton{tr("Browse...")}}; browse->setMaximumWidth(100); - const QString webUiPath{score::AppContext() - .settings() - .getPackagesPath() - + "/wasm-remote/"}; - - connect(browse, &QPushButton::clicked, this, [this, webUiPath] + connect(browse, &QPushButton::clicked, this, [this] { auto f{QFileDialog::getExistingDirectory( - nullptr, tr("Web UI folder"), webUiPath)}; - if(!f.isEmpty()) - { - webUiPathChanged(f); - } + nullptr, tr("Web UI folder"), m_web_ui_path->displayText())}; + if (!f.isEmpty()) webUiPathChanged(f); }); sublay->addWidget(m_web_ui_path); @@ -80,7 +73,7 @@ View::View() m_server_port = new QSpinBox{}; m_server_port->setRange(0, 9999); - m_server_port->setMinimumWidth(200); + m_server_port->setMaximumWidth(100); sublay->addWidget(m_server_address); sublay->addWidget(m_server_port); From 5cff16d6bd02859059aee53b5b220dc76d51f158 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Fri, 10 Jul 2026 15:44:48 +0100 Subject: [PATCH 24/31] [Http_server] re-format --- .../RemoteControl/HttpServer/Http_server.cpp | 481 ++++++++---------- .../RemoteControl/HttpServer/Http_server.hpp | 188 +++---- 2 files changed, 301 insertions(+), 368 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp index 310855b615..0add363ee8 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp @@ -12,8 +12,6 @@ #include #include -#include - //------------------------------------------------------------------------------ @@ -29,267 +27,235 @@ Http_server::~Http_server() } // Return a reasonable mime type based on the extension of a file. -beast::string_view -Http_server::mime_type(beast::string_view path) +beast::string_view Http_server::mime_type(beast::string_view path) { - using beast::iequals; - auto const ext = [&path] - { - auto const pos = path.rfind("."); - if(pos == beast::string_view::npos) - return beast::string_view{}; - return path.substr(pos); - }(); - if(iequals(ext, ".htm")) return "text/html"; - if(iequals(ext, ".html")) return "text/html"; - if(iequals(ext, ".php")) return "text/html"; - if(iequals(ext, ".css")) return "text/css"; - if(iequals(ext, ".txt")) return "text/plain"; - if(iequals(ext, ".js")) return "application/javascript"; - if(iequals(ext, ".json")) return "application/json"; - if(iequals(ext, ".xml")) return "application/xml"; - if(iequals(ext, ".swf")) return "application/x-shockwave-flash"; - if(iequals(ext, ".wasm")) return "application/wasm"; - if(iequals(ext, ".flv")) return "video/x-flv"; - if(iequals(ext, ".png")) return "image/png"; - if(iequals(ext, ".jpe")) return "image/jpeg"; - if(iequals(ext, ".jpeg")) return "image/jpeg"; - if(iequals(ext, ".jpg")) return "image/jpeg"; - if(iequals(ext, ".gif")) return "image/gif"; - if(iequals(ext, ".bmp")) return "image/bmp"; - if(iequals(ext, ".ico")) return "image/vnd.microsoft.icon"; - if(iequals(ext, ".tiff")) return "image/tiff"; - if(iequals(ext, ".tif")) return "image/tiff"; - if(iequals(ext, ".svg")) return "image/svg+xml"; - if(iequals(ext, ".svgz")) return "image/svg+xml"; - return "application/text"; + using beast::iequals; + auto const ext = [&path] + { + auto const pos = path.rfind("."); + if(pos == beast::string_view::npos) + return beast::string_view{}; + return path.substr(pos); + }(); + if(iequals(ext, ".htm")) return "text/html"; + if(iequals(ext, ".html")) return "text/html"; + if(iequals(ext, ".php")) return "text/html"; + if(iequals(ext, ".css")) return "text/css"; + if(iequals(ext, ".txt")) return "text/plain"; + if(iequals(ext, ".js")) return "application/javascript"; + if(iequals(ext, ".json")) return "application/json"; + if(iequals(ext, ".xml")) return "application/xml"; + if(iequals(ext, ".swf")) return "application/x-shockwave-flash"; + if(iequals(ext, ".wasm")) return "application/wasm"; + if(iequals(ext, ".flv")) return "video/x-flv"; + if(iequals(ext, ".png")) return "image/png"; + if(iequals(ext, ".jpe")) return "image/jpeg"; + if(iequals(ext, ".jpeg")) return "image/jpeg"; + if(iequals(ext, ".jpg")) return "image/jpeg"; + if(iequals(ext, ".gif")) return "image/gif"; + if(iequals(ext, ".bmp")) return "image/bmp"; + if(iequals(ext, ".ico")) return "image/vnd.microsoft.icon"; + if(iequals(ext, ".tiff")) return "image/tiff"; + if(iequals(ext, ".tif")) return "image/tiff"; + if(iequals(ext, ".svg")) return "image/svg+xml"; + if(iequals(ext, ".svgz")) return "image/svg+xml"; + return "application/text"; } // Append an HTTP rel-path to a local filesystem path. // The returned path is normalized for the platform. -std::string -Http_server::path_cat( - beast::string_view base, - beast::string_view path) +std::string Http_server::path_cat( + beast::string_view base + , beast::string_view path) { - if (base.empty()) - return std::string(path); - std::string result(base); + if (base.empty()) + 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); - result.append(path.data(), path.size()); - for(auto& c : result) - if(c == '/') - c = path_separator; + char constexpr path_separator = '\\'; + if(result.back() == path_separator) + result.resize(result.size() - 1); + result.append(path.data(), path.size()); + for(auto& c : result) + if(c == '/') + c = path_separator; #else - char constexpr path_separator = '/'; - if(result.back() == path_separator) - result.resize(result.size() - 1); - result.append(path.data(), path.size()); + char constexpr path_separator = '/'; + if(result.back() == path_separator) + result.resize(result.size() - 1); + result.append(path.data(), path.size()); #endif - return result; + return result; } // This function produces an HTTP response for the given // request. The type of the response object depends on the // contents of the request, so the interface requires the // caller to pass a generic lambda for receiving the response. -template< - class Body, class Allocator, - class Send> -void -Http_server::handle_request( - beast::string_view doc_root, - http::request>&& req, - Send&& send) +template +void Http_server::handle_request( + beast::string_view doc_root + , http::request>&& req + , Send&& send) { - // Returns a bad request response - auto const bad_request = - [&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() = std::string(why); - res.prepare_payload(); - return res; - }; - - // Returns a not found response - auto const not_found = - [&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 '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/ossia_remote.html."; - res.prepare_payload(); - return res; - }; - - // Returns a server error response - auto const server_error = - [&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: '" + std::string(what) + "'"; - res.prepare_payload(); - return res; - }; - - // Make sure we can handle the method - if( req.method() != http::verb::get && - req.method() != http::verb::head) - return send(bad_request("Unknown HTTP-method")); - - // Request path must be absolute and not contain "..". - if( req.target().empty() || - req.target()[0] != '/' || - req.target().find("..") != beast::string_view::npos) - return send(bad_request("Illegal request-target")); - - // Build the path to the requested file - std::string path = path_cat(doc_root, req.target()); - if(req.target().back() == '/') - path.append("index.html"); - - // Attempt to open the file - beast::error_code ec; - http::file_body::value_type body; - - body.open(path.c_str(), beast::file_mode::scan, ec); - - // Handle the case where the file doesn't exist - if(ec == beast::errc::no_such_file_or_directory) - return send(not_found(req.target())); - - // Handle an unknown error - if(ec) - return send(server_error(ec.message())); - - // Cache the size since we need it after the move - auto const size = body.size(); - - // Respond to HEAD request - if(req.method() == http::verb::head) - { - http::response res{http::status::ok, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, mime_type(path)); - res.content_length(size); - res.keep_alive(false); - return send(std::move(res)); - } - - // Respond to GET request - http::response res{ - std::piecewise_construct, - std::make_tuple(std::move(body)), - std::make_tuple(http::status::ok, req.version())}; - - // Allow Cross-Origin Resource Sharing (CORS). - res.set(http::field::access_control_allow_headers, "*"); - res.set(http::field::access_control_allow_origin, "*"); - res.set(http::field::access_control_allow_methods, "GET"); - + // Returns a bad request response + auto const bad_request = + [&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() = std::string(why); + res.prepare_payload(); + return res; + }; + + // Returns a not found response + auto const not_found = + [&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 '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/ossia_remote.html."; + res.prepare_payload(); + return res; + }; + + // Returns a server error response + auto const server_error = + [&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: '" + std::string(what) + "'"; + res.prepare_payload(); + return res; + }; + + // Make sure we can handle the method + if( req.method() != http::verb::get && + req.method() != http::verb::head) + return send(bad_request("Unknown HTTP-method")); + + // Request path must be absolute and not contain "..". + if( req.target().empty() || + req.target()[0] != '/' || + req.target().find("..") != beast::string_view::npos) + return send(bad_request("Illegal request-target")); + + // Build the path to the requested file + std::string path = path_cat(doc_root, req.target()); + if(req.target().back() == '/') + path.append("index.html"); + + // Attempt to open the file + beast::error_code ec; + http::file_body::value_type body; + + body.open(path.c_str(), beast::file_mode::scan, ec); + + // Handle the case where the file doesn't exist + if(ec == beast::errc::no_such_file_or_directory) + return send(not_found(req.target())); + + // Handle an unknown error + if(ec) + return send(server_error(ec.message())); + + // Cache the size since we need it after the move + auto const size = body.size(); + + // Respond to HEAD request + if(req.method() == http::verb::head) + { + http::response + res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, mime_type(path)); res.content_length(size); res.keep_alive(false); return send(std::move(res)); + } + + // Respond to GET request + http::response + res{std::piecewise_construct + , std::make_tuple(std::move(body)) + , std::make_tuple(http::status::ok, req.version())}; + + // Allow Cross-Origin Resource Sharing (CORS). + res.set(http::field::access_control_allow_headers, "*"); + res.set(http::field::access_control_allow_origin, "*"); + res.set(http::field::access_control_allow_methods, "GET"); + + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, mime_type(path)); + res.content_length(size); + res.keep_alive(false); + return send(std::move(res)); } //------------------------------------------------------------------------------ // Report a failure -void -Http_server::fail(beast::error_code ec, char const* what) +void Http_server::fail(beast::error_code ec, char const* what) { - std::cerr << what << ": " << ec.message() << "\n"; + std::cerr << what << ": " << ec.message() << "\n"; } // Handles an HTTP server connection -void -Http_server::do_session( - tcp::socket& socket, - std::shared_ptr const& doc_root) +void Http_server::do_session( + tcp::socket& socket + , std::shared_ptr const& doc_root) { - bool close = false; - beast::error_code ec; - - // This buffer is required to persist across reads - beast::flat_buffer buffer; - - // This lambda is used to send messages - send_lambda lambda{socket, close, ec}; + bool close = false; + beast::error_code ec; + + // This buffer is required to persist across reads + beast::flat_buffer buffer; + + // This lambda is used to send messages + send_lambda lambda{socket, close, ec}; + + for(;;) + { + // Read a request + http::request req; + http::read(socket, buffer, req, ec); + if(ec == http::error::end_of_stream) + break; + if(ec) + return Http_server::fail(ec, "read"); - for(;;) + // Send the response + Http_server::handle_request(*doc_root, std::move(req), lambda); + if(ec) + return Http_server::fail(ec, "write"); + if(close) { - // Read a request - http::request req; - http::read(socket, buffer, req, ec); - if(ec == http::error::end_of_stream) - break; - if(ec) - return Http_server::fail(ec, "read"); - - // Send the response - Http_server::handle_request(*doc_root, std::move(req), lambda); - if(ec) - return Http_server::fail(ec, "write"); - if(close) - { - // This means we should close the connection, usually because - // the response indicated the "Connection: close" semantic. - break; - } + // This means we should close the connection, usually because + // the response indicated the "Connection: close" semantic. + break; } + } - // Send a TCP shutdown - socket.shutdown(tcp::socket::shutdown_send, ec); + // Send a TCP shutdown + socket.shutdown(tcp::socket::shutdown_send, ec); - // At this point the connection is closed gracefully + // At this point the connection is closed gracefully } //------------------------------------------------------------------------------ -// // Set the IP address in the remote.html file -// void -// Http_server::set_ip_address(std::string address) -// { -// qDebug() << "buildWasmPath :" << QString::fromStdString(m_buildWasmPath); -// std::rename((m_buildWasmPath + "remote.html").c_str(), (m_buildWasmPath + "remote.html~").c_str()); - -// std::ifstream old_file(m_buildWasmPath + "remote.html~"); -// std::ofstream new_file(m_buildWasmPath + "remote.html"); - -// std::string addr = "\"" + m_ipAddress + "\""; - -// for( std::string contents_of_file; std::getline(old_file, contents_of_file); ) { -// std::string::size_type position = contents_of_file.find("%SCORE_IP_ADDRESS%"); -// if( position != std::string::npos ) -// { -// //contents_of_file = contents_of_file.replace(position, 18, addr); -// contents_of_file = contents_of_file.replace(position, 18, "%SCORE_IP_ADDRESS%"); -// } -// new_file << contents_of_file << '\n'; -// } -// } - -//------------------------------------------------------------------------------ - // Launch the open_server function in a thread -void -Http_server::start_thread() +void Http_server::start_thread() { - m_serverThread = std::thread{[this] { open_server(); }}; + m_serverThread = std::thread{[this] { open_server(); }}; } //------------------------------------------------------------------------------ @@ -306,46 +272,45 @@ void Http_server::stop_thread() //------------------------------------------------------------------------------ // Open a server using sockets -int -Http_server::open_server() +int Http_server::open_server() { - try - { - auto const address2 = net::ip::make_address("0.0.0.0"); - auto const port = static_cast(std::atoi("8080")); - std::string packagesPath = score::AppContext().settings().getPackagesPath().toStdString(); - m_buildWasmPath = packagesPath + "/wasm-remote/"; - auto const m_docRoot = std::make_shared(m_buildWasmPath); - - bool is_ip_address_set = false; - - // The acceptor receives incoming connections - tcp::acceptor acceptor{ioc, {address2, port}}; - m_listenSocket = acceptor.native_handle(); - for(;;) - { - // This will receive the new connection - tcp::socket socket{ioc}; - - // Block until we get a connection - acceptor.accept(socket); - - // Set ip address - if(!is_ip_address_set) - { - m_ipAddress = socket.local_endpoint().address().to_string(); - is_ip_address_set = true; - } - - // Launch the session, transferring ownership of the socket - do_session(socket, m_docRoot); - } - } - catch (const std::exception& e) + try + { + auto const address2 = net::ip::make_address("0.0.0.0"); + auto const port = static_cast(std::atoi("8080")); + std::string packagesPath = score::AppContext().settings().getPackagesPath().toStdString(); + m_buildWasmPath = packagesPath + "/wasm-remote/"; + auto const m_docRoot = std::make_shared(m_buildWasmPath); + + bool is_ip_address_set = false; + + // The acceptor receives incoming connections + tcp::acceptor acceptor{ioc, {address2, port}}; + m_listenSocket = acceptor.native_handle(); + for(;;) { - std::cerr << "Error: " << e.what() << '\n'; - return EXIT_FAILURE; + // This will receive the new connection + tcp::socket socket{ioc}; + + // Block until we get a connection + acceptor.accept(socket); + + // Set ip address + if(!is_ip_address_set) + { + m_ipAddress = socket.local_endpoint().address().to_string(); + is_ip_address_set = true; + } + + // Launch the session, transferring ownership of the socket + do_session(socket, m_docRoot); } + } + catch (const std::exception& e) + { + std::cerr << "Error: " << e.what() << '\n'; + return EXIT_FAILURE; + } } } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp index 08b6fe1c8b..4cf66ce26a 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp @@ -44,116 +44,84 @@ namespace RemoteControl class Http_server { public: - net::io_context ioc; - - //std::thread th1; - - Http_server(); - - ~Http_server(); - - //------------------------------------------------------------------------------ - - // Return a reasonable mime type based on the extension of a file. - beast::string_view - mime_type(beast::string_view path); - - // Append an HTTP rel-path to a local filesystem path. - // The returned path is normalized for the platform. - std::string - path_cat( - beast::string_view base, - beast::string_view path); - - // This function produces an HTTP response for the given - // request. The type of the response object depends on the - // contents of the request, so the interface requires the - // caller to pass a generic lambda for receiving the response. - template< - class Body, class Allocator, - class Send> - void - handle_request( - beast::string_view doc_root, - http::request>&& req, - Send&& send); - - //------------------------------------------------------------------------------ - - // Report a failure - void - fail(beast::error_code ec, char const* what); - - // This is the C++11 equivalent of a generic lambda. - // The function object is used to send an HTTP message. - template - struct send_lambda + Http_server(); + ~Http_server(); + + // Launch the open_server function in a thread + void start_thread(); + void stop_thread(); + +private: + // Return a reasonable mime type based on the extension of a file. + beast::string_view mime_type(beast::string_view path); + + // Append an HTTP rel-path to a local filesystem path. + // The returned path is normalized for the platform. + std::string path_cat(beast::string_view base + , beast::string_view path); + + // This function produces an HTTP response for the given + // request. The type of the response object depends on the + // contents of the request, so the interface requires the + // caller to pass a generic lambda for receiving the response. + template + void handle_request( + beast::string_view doc_root, + http::request>&& req, + Send&& send); + + //------------------------------------------------------------------------------ + + // Report a failure + void fail(beast::error_code ec, char const* what); + + // This is the C++11 equivalent of a generic lambda. + // The function object is used to send an HTTP message. + template + struct send_lambda + { + Stream& stream_; + bool& close_; + beast::error_code& ec_; + + explicit send_lambda( + Stream& stream, + bool& close, + beast::error_code& ec) + : stream_(stream) + , close_(close) + , ec_(ec) + { } + + template + void operator() + (http::message&& msg) const { - Stream& stream_; - bool& close_; - beast::error_code& ec_; - - explicit - send_lambda( - Stream& stream, - bool& close, - beast::error_code& ec) - : stream_(stream) - , close_(close) - , ec_(ec) - { - } - - template - void - operator()(http::message&& msg) const - { - // Determine if we should close the connection after - close_ = msg.need_eof(); - - // We need the serializer here because the serializer requires - // a non-const file_body, and the message oriented version of - // http::write only works with const messages. - http::serializer sr{msg}; - http::write(stream_, sr, ec_); - } - }; - - // Handles an HTTP server connection - void - do_session( - tcp::socket& socket, - std::shared_ptr const& doc_root); - - //------------------------------------------------------------------------------ - - // // Set the IP address in the remote.html file - // set_ip_address(std::string address); - // void - - //------------------------------------------------------------------------------ - - // Launch the open_server function in a thread - void - start_thread(); - - //------------------------------------------------------------------------------ - - // Launch the open_server function in a thread - void - stop_thread(); - - //------------------------------------------------------------------------------ - - // Open a server using sockets - int - open_server(); - - //------------------------------------------------------------------------------ - - std::thread m_serverThread; - int m_listenSocket{}; - std::string m_buildWasmPath; - std::string m_ipAddress; + // Determine if we should close the connection after + close_ = msg.need_eof(); + + // We need the serializer here because the serializer requires + // a non-const file_body, and the message oriented version of + // http::write only works with const messages. + http::serializer sr{msg}; + http::write(stream_, sr, ec_); + } + }; + + // Handles an HTTP server connection + void do_session( + tcp::socket& socket + , std::shared_ptr const& doc_root); + + //------------------------------------------------------------------------------ + + // Open a server using sockets + int open_server(); + + net::io_context ioc; + std::thread m_serverThread; + int m_listenSocket{}; + std::string m_buildWasmPath; + std::string m_ipAddress; }; } From fb49b7cd843184739feaf65cde5fbdd4c56d7811 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Fri, 10 Jul 2026 19:37:36 +0100 Subject: [PATCH 25/31] [Http_server] set port, address, and path --- .../HttpServer/DocumentPlugin.cpp | 46 +++++++++- .../RemoteControl/HttpServer/Http_server.cpp | 83 +++++++++---------- .../RemoteControl/HttpServer/Http_server.hpp | 29 +++---- .../RemoteControl/Settings/Model.cpp | 8 +- .../RemoteControl/Settings/View.cpp | 21 ++++- 5 files changed, 115 insertions(+), 72 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp index a122a4213d..319b5d2d29 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp @@ -10,15 +10,53 @@ DocumentPlugin::DocumentPlugin(const score::DocumentContext& doc, QObject* paren { auto& model{m_context.app.settings()}; - if (model.getServerEnabled()) + m_server.set_path(model.getWebUiPath().toStdString()); + m_server.set_address(model.getServerAddress().toStdString()); + m_server.set_port(model.getServerPort()); + + if (model.getEnabled() && model.getServerEnabled()) m_server.start_thread(); con(model - , &Settings::Model::ServerEnabledChanged + , &Settings::Model::EnabledChanged + , this + , [this, &model] (bool e) + { + e && model.getServerEnabled() + ? m_server.start_thread() + : m_server.stop_thread(); + }, Qt::QueuedConnection); + + con(model + , &Settings::Model::WebUiPathChanged + , this + , [this] (const QString& s) + { m_server.set_path(s.toStdString()); } + , Qt::QueuedConnection); + + con(model + , &Settings::Model::ServerAddressChanged , this - , [this] (bool e) - { e ? m_server.start_thread() : m_server.stop_thread(); } + , [this] (const QString& s) + { m_server.set_address(s.toStdString().c_str()); } , Qt::QueuedConnection); + + con(model + , &Settings::Model::ServerPortChanged + , this + , [this] (unsigned short s) + { m_server.set_port(s); } + , Qt::QueuedConnection); + + con(model + , &Settings::Model::ServerEnabledChanged + , this + , [this, &model] (bool e) + { + e && model.getEnabled() + ? m_server.start_thread() + : m_server.stop_thread(); + }, Qt::QueuedConnection); } DocumentPlugin::~DocumentPlugin() { } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp index 0add363ee8..2e4c2bf884 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp @@ -13,13 +13,9 @@ #include #include -//------------------------------------------------------------------------------ - namespace RemoteControl { - -Http_server::Http_server() -{ } +Http_server::Http_server() { } Http_server::~Http_server() { @@ -64,13 +60,11 @@ beast::string_view Http_server::mime_type(beast::string_view path) // Append an HTTP rel-path to a local filesystem path. // The returned path is normalized for the platform. -std::string Http_server::path_cat( - beast::string_view base - , beast::string_view path) +std::string Http_server::path_cat(beast::string_view path) { - if (base.empty()) + if (m_buildWasmPath.empty()) return std::string(path); - std::string result(base); + std::string result(m_buildWasmPath); #ifdef BOOST_MSVC char constexpr path_separator = '\\'; if(result.back() == path_separator) @@ -94,8 +88,7 @@ std::string Http_server::path_cat( // caller to pass a generic lambda for receiving the response. template void Http_server::handle_request( - beast::string_view doc_root - , http::request>&& req + http::request>&& req , Send&& send) { // Returns a bad request response @@ -149,7 +142,7 @@ void Http_server::handle_request( return send(bad_request("Illegal request-target")); // Build the path to the requested file - std::string path = path_cat(doc_root, req.target()); + std::string path = path_cat(req.target()); if(req.target().back() == '/') path.append("index.html"); @@ -200,8 +193,6 @@ void Http_server::handle_request( return send(std::move(res)); } -//------------------------------------------------------------------------------ - // Report a failure void Http_server::fail(beast::error_code ec, char const* what) { @@ -209,9 +200,7 @@ void Http_server::fail(beast::error_code ec, char const* what) } // Handles an HTTP server connection -void Http_server::do_session( - tcp::socket& socket - , std::shared_ptr const& doc_root) +void Http_server::do_session(tcp::socket& socket) { bool close = false; beast::error_code ec; @@ -233,7 +222,7 @@ void Http_server::do_session( return Http_server::fail(ec, "read"); // Send the response - Http_server::handle_request(*doc_root, std::move(req), lambda); + Http_server::handle_request(std::move(req), lambda); if(ec) return Http_server::fail(ec, "write"); if(close) @@ -250,60 +239,61 @@ void Http_server::do_session( // At this point the connection is closed gracefully } -//------------------------------------------------------------------------------ - // Launch the open_server function in a thread void Http_server::start_thread() { m_serverThread = std::thread{[this] { open_server(); }}; } -//------------------------------------------------------------------------------ - void Http_server::stop_thread() { - if (!m_serverThread.joinable()) return; + if (!running()) return; shutdown(m_listenSocket, SHUT_RDWR); - ioc.stop(); + m_ioc.stop(); m_serverThread.join(); } -//------------------------------------------------------------------------------ +void Http_server::set_path(const std::string& str) +{ + // FIXME : Not thread safe, but is it that bad ? + m_buildWasmPath = str; +} + +void Http_server::set_address(const std::string& str) +{ + bool is_runnig{running()}; + if (is_runnig) stop_thread(); + m_endpoint.address(net::ip::make_address(str.c_str())); + if (is_runnig) start_thread(); +} + +void Http_server::set_port(unsigned short prt) +{ + bool is_runnig{running()}; + if (is_runnig) stop_thread(); + m_endpoint.port(prt); + if (is_runnig) start_thread(); +} // Open a server using sockets int Http_server::open_server() { try { - auto const address2 = net::ip::make_address("0.0.0.0"); - auto const port = static_cast(std::atoi("8080")); - std::string packagesPath = score::AppContext().settings().getPackagesPath().toStdString(); - m_buildWasmPath = packagesPath + "/wasm-remote/"; - auto const m_docRoot = std::make_shared(m_buildWasmPath); - - bool is_ip_address_set = false; - // The acceptor receives incoming connections - tcp::acceptor acceptor{ioc, {address2, port}}; + tcp::acceptor acceptor{m_ioc, m_endpoint}; m_listenSocket = acceptor.native_handle(); for(;;) { // This will receive the new connection - tcp::socket socket{ioc}; + tcp::socket socket{m_ioc}; // Block until we get a connection acceptor.accept(socket); - // Set ip address - if(!is_ip_address_set) - { - m_ipAddress = socket.local_endpoint().address().to_string(); - is_ip_address_set = true; - } - // Launch the session, transferring ownership of the socket - do_session(socket, m_docRoot); + do_session(socket); } } catch (const std::exception& e) @@ -313,4 +303,9 @@ int Http_server::open_server() } } +bool Http_server::running() +{ + return m_serverThread.joinable(); +} + } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp index 4cf66ce26a..bb10c936f2 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp @@ -37,8 +37,6 @@ namespace http = beast::http; // from namespace net = boost::asio; // from using tcp = boost::asio::ip::tcp; // from -//------------------------------------------------------------------------------ - namespace RemoteControl { class Http_server @@ -47,9 +45,11 @@ class Http_server Http_server(); ~Http_server(); - // Launch the open_server function in a thread void start_thread(); void stop_thread(); + void set_path(const std::string& str); + void set_address(const std::string& str); + void set_port(unsigned short prt); private: // Return a reasonable mime type based on the extension of a file. @@ -57,8 +57,7 @@ class Http_server // Append an HTTP rel-path to a local filesystem path. // The returned path is normalized for the platform. - std::string path_cat(beast::string_view base - , beast::string_view path); + std::string path_cat(beast::string_view path); // This function produces an HTTP response for the given // request. The type of the response object depends on the @@ -66,11 +65,8 @@ class Http_server // caller to pass a generic lambda for receiving the response. template void handle_request( - beast::string_view doc_root, - http::request>&& req, - Send&& send); - - //------------------------------------------------------------------------------ + http::request>&& req + , Send&& send); // Report a failure void fail(beast::error_code ec, char const* what); @@ -109,19 +105,16 @@ class Http_server }; // Handles an HTTP server connection - void do_session( - tcp::socket& socket - , std::shared_ptr const& doc_root); - - //------------------------------------------------------------------------------ + void do_session(tcp::socket& socket); // Open a server using sockets int open_server(); + bool running(); - net::io_context ioc; + net::io_context m_ioc; + tcp::endpoint m_endpoint{}; std::thread m_serverThread; - int m_listenSocket{}; std::string m_buildWasmPath; - std::string m_ipAddress; + int m_listenSocket{}; }; } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp index f103ca2571..a3ce90bd19 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp @@ -11,7 +11,6 @@ namespace RemoteControl { namespace Settings { - namespace Parameters { SETTINGS_PARAMETER_IMPL(Enabled){QStringLiteral("RemoteControl/Enabled"), false}; @@ -27,7 +26,7 @@ static auto list() , ServerPort , ServerEnabled); } -} +} // namespace Parameters Model::Model( const UuidKey& k, QSettings& set, @@ -53,5 +52,6 @@ SCORE_SETTINGS_PARAMETER_CPP(QString, Model, WebUiPath) SCORE_SETTINGS_PARAMETER_CPP(QString, Model, ServerAddress) SCORE_SETTINGS_PARAMETER_CPP(unsigned short, Model, ServerPort) SCORE_SETTINGS_PARAMETER_CPP(bool, Model, ServerEnabled) -} -} + +} // namespace Settings +} // namespace RemoteControl diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp index 2c23702ace..2eb033e922 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/View.cpp @@ -25,7 +25,10 @@ View::View() { m_enabled = new QCheckBox{tr("Enabled")}; - connect(m_enabled, SignalUtils::QCheckBox_checkStateChanged(), this, [&](int t) { + connect(m_enabled + , SignalUtils::QCheckBox_checkStateChanged() + , this + , [&](int t) { switch(t) { case Qt::Unchecked: @@ -71,17 +74,31 @@ View::View() m_server_address = new QLineEdit{}; m_server_address->setPlaceholderText("0.0.0.0"); + connect(m_server_address + , &QLineEdit::textEdited + , this, [&](const QString& str) + { if (!str.isEmpty()) serverAddressChanged(str); }); + m_server_port = new QSpinBox{}; m_server_port->setRange(0, 9999); m_server_port->setMaximumWidth(100); + connect(m_server_port + , SignalUtils::QSpinBox_valueChanged_int() + , this + , [&](int t) + { serverPortChanged(t); }); + sublay->addWidget(m_server_address); sublay->addWidget(m_server_port); web_lay->addRow(tr("HTTP server address/port"), subw); m_server_enabled = new QCheckBox{tr("Enable HTTP server")}; - connect(m_server_enabled, SignalUtils::QCheckBox_checkStateChanged(), this, [&](int t) { + connect(m_server_enabled + , SignalUtils::QCheckBox_checkStateChanged() + , this + , [&](int t) { switch(t) { case Qt::Unchecked: From be142115a5765ab4bfe474945910bfc0bdb95a77 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Sun, 12 Jul 2026 11:43:20 +0100 Subject: [PATCH 26/31] [HttpServer] rename file and add proper lambda --- .../score-plugin-remotecontrol/CMakeLists.txt | 4 +- .../HttpServer/DocumentPlugin.hpp | 4 +- .../{Http_server.cpp => HttpServer.cpp} | 59 ++++++++++++------- .../{Http_server.hpp => HttpServer.hpp} | 51 ++-------------- 4 files changed, 46 insertions(+), 72 deletions(-) rename src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/{Http_server.cpp => HttpServer.cpp} (85%) rename src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/{Http_server.hpp => HttpServer.hpp} (63%) diff --git a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt index 1a30a39b1b..c984b8b501 100644 --- a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt +++ b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt @@ -39,7 +39,7 @@ set(HDRS "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/DocumentPlugin.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/Http_server.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/HttpServer.hpp" ) set(SRCS @@ -61,7 +61,7 @@ set(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/ApplicationPlugin.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/DocumentPlugin.cpp" -"${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/Http_server.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/RemoteControl/HttpServer/HttpServer.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_remotecontrol.cpp" ) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp index 30fb6168f1..89ed2ee88f 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp @@ -1,5 +1,5 @@ #pragma once -#include "Http_server.hpp" +#include "HttpServer.hpp" #include #include @@ -13,7 +13,7 @@ struct SCORE_PLUGIN_REMOTECONTROL_EXPORT DocumentPlugin : score::DocumentPlugin ~DocumentPlugin(); private: - Http_server m_server; + HttpServer m_server; }; } // namespace RemoteControl::HttpServer \ No newline at end of file diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp similarity index 85% rename from src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp rename to src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp index 2e4c2bf884..c6be5f3ca1 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp @@ -7,23 +7,23 @@ // Official repository: https://github.com/boostorg/beast // -#include "Http_server.hpp" +#include "HttpServer.hpp" #include #include #include -namespace RemoteControl +namespace RemoteControl::HttpServer { -Http_server::Http_server() { } +HttpServer::HttpServer() { } -Http_server::~Http_server() +HttpServer::~HttpServer() { stop_thread(); } // Return a reasonable mime type based on the extension of a file. -beast::string_view Http_server::mime_type(beast::string_view path) +beast::string_view HttpServer::mime_type(beast::string_view path) { using beast::iequals; auto const ext = [&path] @@ -60,7 +60,7 @@ beast::string_view Http_server::mime_type(beast::string_view path) // Append an HTTP rel-path to a local filesystem path. // The returned path is normalized for the platform. -std::string Http_server::path_cat(beast::string_view path) +std::string HttpServer::path_cat(beast::string_view path) { if (m_buildWasmPath.empty()) return std::string(path); @@ -87,9 +87,9 @@ std::string Http_server::path_cat(beast::string_view path) // contents of the request, so the interface requires the // caller to pass a generic lambda for receiving the response. template -void Http_server::handle_request( +void HttpServer::handle_request( http::request>&& req - , Send&& send) + , const Send& send) { // Returns a bad request response auto const bad_request = @@ -194,13 +194,13 @@ void Http_server::handle_request( } // Report a failure -void Http_server::fail(beast::error_code ec, char const* what) +void HttpServer::fail(beast::error_code ec, char const* what) { std::cerr << what << ": " << ec.message() << "\n"; } // Handles an HTTP server connection -void Http_server::do_session(tcp::socket& socket) +void HttpServer::do_session(tcp::socket& socket) { bool close = false; beast::error_code ec; @@ -209,7 +209,21 @@ void Http_server::do_session(tcp::socket& socket) beast::flat_buffer buffer; // This lambda is used to send messages - send_lambda lambda{socket, close, ec}; + const auto lambda{[&close, &socket, &ec] + + (http::message&& msg) + { + // Determine if we should close the connection after + close = msg.need_eof(); + + // We need the serializer here because the serializer requires + // a non-const file_body, and the message oriented version of + // http::write only works with const messages. + http::serializer sr{msg}; + http::write(socket, sr, ec); + }}; for(;;) { @@ -219,12 +233,13 @@ void Http_server::do_session(tcp::socket& socket) if(ec == http::error::end_of_stream) break; if(ec) - return Http_server::fail(ec, "read"); + return HttpServer::fail(ec, "read"); // Send the response - Http_server::handle_request(std::move(req), lambda); - if(ec) - return Http_server::fail(ec, "write"); + HttpServer::handle_request(std::move(req), lambda); + + if (ec) + return HttpServer::fail(ec, "write"); if(close) { // This means we should close the connection, usually because @@ -240,12 +255,12 @@ void Http_server::do_session(tcp::socket& socket) } // Launch the open_server function in a thread -void Http_server::start_thread() +void HttpServer::start_thread() { m_serverThread = std::thread{[this] { open_server(); }}; } -void Http_server::stop_thread() +void HttpServer::stop_thread() { if (!running()) return; @@ -254,13 +269,13 @@ void Http_server::stop_thread() m_serverThread.join(); } -void Http_server::set_path(const std::string& str) +void HttpServer::set_path(const std::string& str) { // FIXME : Not thread safe, but is it that bad ? m_buildWasmPath = str; } -void Http_server::set_address(const std::string& str) +void HttpServer::set_address(const std::string& str) { bool is_runnig{running()}; if (is_runnig) stop_thread(); @@ -268,7 +283,7 @@ void Http_server::set_address(const std::string& str) if (is_runnig) start_thread(); } -void Http_server::set_port(unsigned short prt) +void HttpServer::set_port(unsigned short prt) { bool is_runnig{running()}; if (is_runnig) stop_thread(); @@ -277,7 +292,7 @@ void Http_server::set_port(unsigned short prt) } // Open a server using sockets -int Http_server::open_server() +int HttpServer::open_server() { try { @@ -303,7 +318,7 @@ int Http_server::open_server() } } -bool Http_server::running() +bool HttpServer::running() { return m_serverThread.joinable(); } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp similarity index 63% rename from src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp rename to src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp index bb10c936f2..ea0102a906 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/Http_server.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp @@ -17,7 +17,6 @@ #include #include -#include #include #include @@ -25,25 +24,18 @@ #define SHUT_RDWR 2 #endif -#include -#include -#include -#include -#include -#include - namespace beast = boost::beast; // from namespace http = beast::http; // from namespace net = boost::asio; // from using tcp = boost::asio::ip::tcp; // from -namespace RemoteControl +namespace RemoteControl::HttpServer { -class Http_server +class HttpServer { public: - Http_server(); - ~Http_server(); + HttpServer(); + ~HttpServer(); void start_thread(); void stop_thread(); @@ -66,44 +58,11 @@ class Http_server template void handle_request( http::request>&& req - , Send&& send); + , const Send& send); // Report a failure void fail(beast::error_code ec, char const* what); - // This is the C++11 equivalent of a generic lambda. - // The function object is used to send an HTTP message. - template - struct send_lambda - { - Stream& stream_; - bool& close_; - beast::error_code& ec_; - - explicit send_lambda( - Stream& stream, - bool& close, - beast::error_code& ec) - : stream_(stream) - , close_(close) - , ec_(ec) - { } - - template - void operator() - (http::message&& msg) const - { - // Determine if we should close the connection after - close_ = msg.need_eof(); - - // We need the serializer here because the serializer requires - // a non-const file_body, and the message oriented version of - // http::write only works with const messages. - http::serializer sr{msg}; - http::write(stream_, sr, ec_); - } - }; - // Handles an HTTP server connection void do_session(tcp::socket& socket); From 76f2c9eb5517c32be81f1ded2bf0e666fb021ea1 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Sun, 12 Jul 2026 22:15:34 +0100 Subject: [PATCH 27/31] [remotecontrol] riun clang-format --- .../HttpServer/DocumentPlugin.cpp | 51 ++----- .../HttpServer/DocumentPlugin.hpp | 3 +- .../RemoteControl/HttpServer/HttpServer.cpp | 137 ++++++++++-------- .../RemoteControl/HttpServer/HttpServer.hpp | 15 +- 4 files changed, 99 insertions(+), 107 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp index 319b5d2d29..43937aa4d0 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp @@ -1,8 +1,9 @@ #include "DocumentPlugin.hpp" -#include #include +#include + namespace RemoteControl::HttpServer { DocumentPlugin::DocumentPlugin(const score::DocumentContext& doc, QObject* parent) @@ -14,48 +15,26 @@ DocumentPlugin::DocumentPlugin(const score::DocumentContext& doc, QObject* paren m_server.set_address(model.getServerAddress().toStdString()); m_server.set_port(model.getServerPort()); - if (model.getEnabled() && model.getServerEnabled()) + if(model.getEnabled() && model.getServerEnabled()) m_server.start_thread(); - con(model - , &Settings::Model::EnabledChanged - , this - , [this, &model] (bool e) - { - e && model.getServerEnabled() - ? m_server.start_thread() - : m_server.stop_thread(); + con(model, &Settings::Model::EnabledChanged, this, [this, &model](bool e) { + e&& model.getServerEnabled() ? m_server.start_thread() : m_server.stop_thread(); }, Qt::QueuedConnection); - con(model - , &Settings::Model::WebUiPathChanged - , this - , [this] (const QString& s) - { m_server.set_path(s.toStdString()); } - , Qt::QueuedConnection); + con(model, &Settings::Model::WebUiPathChanged, this, [this](const QString& s) { + m_server.set_path(s.toStdString()); + }, Qt::QueuedConnection); - con(model - , &Settings::Model::ServerAddressChanged - , this - , [this] (const QString& s) - { m_server.set_address(s.toStdString().c_str()); } - , Qt::QueuedConnection); + con(model, &Settings::Model::ServerAddressChanged, this, [this](const QString& s) { + m_server.set_address(s.toStdString().c_str()); + }, Qt::QueuedConnection); - con(model - , &Settings::Model::ServerPortChanged - , this - , [this] (unsigned short s) - { m_server.set_port(s); } - , Qt::QueuedConnection); + con(model, &Settings::Model::ServerPortChanged, this, + [this](unsigned short s) { m_server.set_port(s); }, Qt::QueuedConnection); - con(model - , &Settings::Model::ServerEnabledChanged - , this - , [this, &model] (bool e) - { - e && model.getEnabled() - ? m_server.start_thread() - : m_server.stop_thread(); + con(model, &Settings::Model::ServerEnabledChanged, this, [this, &model](bool e) { + e&& model.getEnabled() ? m_server.start_thread() : m_server.stop_thread(); }, Qt::QueuedConnection); } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp index 89ed2ee88f..64a0e86fcb 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp @@ -1,9 +1,10 @@ #pragma once #include "HttpServer.hpp" -#include #include +#include + namespace RemoteControl::HttpServer { struct SCORE_PLUGIN_REMOTECONTROL_EXPORT DocumentPlugin : score::DocumentPlugin diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp index c6be5f3ca1..81c9394c5b 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp @@ -8,6 +8,7 @@ // #include "HttpServer.hpp" + #include #include @@ -26,35 +27,56 @@ HttpServer::~HttpServer() beast::string_view HttpServer::mime_type(beast::string_view path) { using beast::iequals; - auto const ext = [&path] - { + auto const ext = [&path] { auto const pos = path.rfind("."); if(pos == beast::string_view::npos) return beast::string_view{}; return path.substr(pos); }(); - if(iequals(ext, ".htm")) return "text/html"; - if(iequals(ext, ".html")) return "text/html"; - if(iequals(ext, ".php")) return "text/html"; - if(iequals(ext, ".css")) return "text/css"; - if(iequals(ext, ".txt")) return "text/plain"; - if(iequals(ext, ".js")) return "application/javascript"; - if(iequals(ext, ".json")) return "application/json"; - if(iequals(ext, ".xml")) return "application/xml"; - if(iequals(ext, ".swf")) return "application/x-shockwave-flash"; - if(iequals(ext, ".wasm")) return "application/wasm"; - if(iequals(ext, ".flv")) return "video/x-flv"; - if(iequals(ext, ".png")) return "image/png"; - if(iequals(ext, ".jpe")) return "image/jpeg"; - if(iequals(ext, ".jpeg")) return "image/jpeg"; - if(iequals(ext, ".jpg")) return "image/jpeg"; - if(iequals(ext, ".gif")) return "image/gif"; - if(iequals(ext, ".bmp")) return "image/bmp"; - if(iequals(ext, ".ico")) return "image/vnd.microsoft.icon"; - if(iequals(ext, ".tiff")) return "image/tiff"; - if(iequals(ext, ".tif")) return "image/tiff"; - if(iequals(ext, ".svg")) return "image/svg+xml"; - if(iequals(ext, ".svgz")) return "image/svg+xml"; + if(iequals(ext, ".htm")) + return "text/html"; + if(iequals(ext, ".html")) + return "text/html"; + if(iequals(ext, ".php")) + return "text/html"; + if(iequals(ext, ".css")) + return "text/css"; + if(iequals(ext, ".txt")) + return "text/plain"; + if(iequals(ext, ".js")) + return "application/javascript"; + if(iequals(ext, ".json")) + return "application/json"; + if(iequals(ext, ".xml")) + return "application/xml"; + if(iequals(ext, ".swf")) + return "application/x-shockwave-flash"; + if(iequals(ext, ".wasm")) + return "application/wasm"; + if(iequals(ext, ".flv")) + return "video/x-flv"; + if(iequals(ext, ".png")) + return "image/png"; + if(iequals(ext, ".jpe")) + return "image/jpeg"; + if(iequals(ext, ".jpeg")) + return "image/jpeg"; + if(iequals(ext, ".jpg")) + return "image/jpeg"; + if(iequals(ext, ".gif")) + return "image/gif"; + if(iequals(ext, ".bmp")) + return "image/bmp"; + if(iequals(ext, ".ico")) + return "image/vnd.microsoft.icon"; + if(iequals(ext, ".tiff")) + return "image/tiff"; + if(iequals(ext, ".tif")) + return "image/tiff"; + if(iequals(ext, ".svg")) + return "image/svg+xml"; + if(iequals(ext, ".svgz")) + return "image/svg+xml"; return "application/text"; } @@ -62,7 +84,7 @@ beast::string_view HttpServer::mime_type(beast::string_view path) // The returned path is normalized for the platform. std::string HttpServer::path_cat(beast::string_view path) { - if (m_buildWasmPath.empty()) + if(m_buildWasmPath.empty()) return std::string(path); std::string result(m_buildWasmPath); #ifdef BOOST_MSVC @@ -86,15 +108,12 @@ std::string HttpServer::path_cat(beast::string_view path) // request. The type of the response object depends on the // contents of the request, so the interface requires the // caller to pass a generic lambda for receiving the response. -template +template void HttpServer::handle_request( - http::request>&& req - , const Send& send) + http::request>&& req, const Send& send) { // Returns a bad request response - auto const bad_request = - [&req](beast::string_view why) - { + auto const bad_request = [&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"); @@ -105,9 +124,7 @@ void HttpServer::handle_request( }; // Returns a not found response - auto const not_found = - [&req](beast::string_view target) - { + auto const not_found = [&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"); @@ -118,10 +135,9 @@ void HttpServer::handle_request( }; // Returns a server error response - auto const server_error = - [&req](beast::string_view what) - { - http::response res{http::status::internal_server_error, req.version()}; + auto const server_error = [&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()); @@ -131,14 +147,12 @@ void HttpServer::handle_request( }; // Make sure we can handle the method - if( req.method() != http::verb::get && - req.method() != http::verb::head) + if(req.method() != http::verb::get && req.method() != http::verb::head) return send(bad_request("Unknown HTTP-method")); // Request path must be absolute and not contain "..". - if( req.target().empty() || - req.target()[0] != '/' || - req.target().find("..") != beast::string_view::npos) + if(req.target().empty() || req.target()[0] != '/' + || req.target().find("..") != beast::string_view::npos) return send(bad_request("Illegal request-target")); // Build the path to the requested file @@ -166,8 +180,7 @@ void HttpServer::handle_request( // Respond to HEAD request if(req.method() == http::verb::head) { - http::response - res{http::status::ok, req.version()}; + http::response res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, mime_type(path)); res.content_length(size); @@ -176,10 +189,9 @@ void HttpServer::handle_request( } // Respond to GET request - http::response - res{std::piecewise_construct - , std::make_tuple(std::move(body)) - , std::make_tuple(http::status::ok, req.version())}; + http::response res{ + std::piecewise_construct, std::make_tuple(std::move(body)), + std::make_tuple(http::status::ok, req.version())}; // Allow Cross-Origin Resource Sharing (CORS). res.set(http::field::access_control_allow_headers, "*"); @@ -209,12 +221,8 @@ void HttpServer::do_session(tcp::socket& socket) beast::flat_buffer buffer; // This lambda is used to send messages - const auto lambda{[&close, &socket, &ec] - - (http::message&& msg) - { + const auto lambda{[&close, &socket, &ec]( + http::message&& msg) { // Determine if we should close the connection after close = msg.need_eof(); @@ -238,7 +246,7 @@ void HttpServer::do_session(tcp::socket& socket) // Send the response HttpServer::handle_request(std::move(req), lambda); - if (ec) + if(ec) return HttpServer::fail(ec, "write"); if(close) { @@ -262,7 +270,8 @@ void HttpServer::start_thread() void HttpServer::stop_thread() { - if (!running()) return; + if(!running()) + return; shutdown(m_listenSocket, SHUT_RDWR); m_ioc.stop(); @@ -278,17 +287,21 @@ void HttpServer::set_path(const std::string& str) void HttpServer::set_address(const std::string& str) { bool is_runnig{running()}; - if (is_runnig) stop_thread(); + if(is_runnig) + stop_thread(); m_endpoint.address(net::ip::make_address(str.c_str())); - if (is_runnig) start_thread(); + if(is_runnig) + start_thread(); } void HttpServer::set_port(unsigned short prt) { bool is_runnig{running()}; - if (is_runnig) stop_thread(); + if(is_runnig) + stop_thread(); m_endpoint.port(prt); - if (is_runnig) start_thread(); + if(is_runnig) + start_thread(); } // Open a server using sockets @@ -311,7 +324,7 @@ int HttpServer::open_server() do_session(socket); } } - catch (const std::exception& e) + catch(const std::exception& e) { std::cerr << "Error: " << e.what() << '\n'; return EXIT_FAILURE; diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp index ea0102a906..04c2e67425 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp @@ -11,10 +11,10 @@ #define BOOST_DATE_TIME_NO_LIB 1 +#include #include #include #include -#include #include #include @@ -24,10 +24,10 @@ #define SHUT_RDWR 2 #endif -namespace beast = boost::beast; // from -namespace http = beast::http; // from -namespace net = boost::asio; // from -using tcp = boost::asio::ip::tcp; // from +namespace beast = boost::beast; // from +namespace http = beast::http; // from +namespace net = boost::asio; // from +using tcp = boost::asio::ip::tcp; // from namespace RemoteControl::HttpServer { @@ -55,10 +55,9 @@ class HttpServer // request. The type of the response object depends on the // contents of the request, so the interface requires the // caller to pass a generic lambda for receiving the response. - template + template void handle_request( - http::request>&& req - , const Send& send); + http::request>&& req, const Send& send); // Report a failure void fail(beast::error_code ec, char const* what); From 610df2ac68db49aaa9f755a1773110ef4386c5cc Mon Sep 17 00:00:00 2001 From: thibaudk Date: Sun, 12 Jul 2026 22:40:14 +0100 Subject: [PATCH 28/31] [repo] more formatting --- .../score-plugin-remotecontrol/CMakeLists.txt | 2 +- .../RemoteControl/HttpServer/DocumentPlugin.cpp | 2 +- .../RemoteControl/HttpServer/DocumentPlugin.hpp | 6 ++---- .../RemoteControl/HttpServer/HttpServer.cpp | 12 ++++++------ .../RemoteControl/Settings/Model.cpp | 9 ++++----- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt index c984b8b501..b79fef6a62 100644 --- a/src/plugins/score-plugin-remotecontrol/CMakeLists.txt +++ b/src/plugins/score-plugin-remotecontrol/CMakeLists.txt @@ -68,7 +68,7 @@ set(SRCS add_library(${PROJECT_NAME} ${SRCS} ${HDRS} ${QRCS}) -target_link_libraries(${PROJECT_NAME} PUBLIC score_plugin_scenario score_plugin_js ${QT_PREFIX}::WebSockets ossia) +target_link_libraries(${PROJECT_NAME} PUBLIC score_plugin_scenario score_plugin_js ${QT_PREFIX}::WebSockets) setup_score_plugin(${PROJECT_NAME}) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp index 43937aa4d0..73aabf00ea 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.cpp @@ -40,4 +40,4 @@ DocumentPlugin::DocumentPlugin(const score::DocumentContext& doc, QObject* paren DocumentPlugin::~DocumentPlugin() { } -} // namespace RemoteControl::HttpServer \ No newline at end of file +} \ No newline at end of file diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp index 64a0e86fcb..b147aa47bd 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/DocumentPlugin.hpp @@ -3,11 +3,9 @@ #include -#include - namespace RemoteControl::HttpServer { -struct SCORE_PLUGIN_REMOTECONTROL_EXPORT DocumentPlugin : score::DocumentPlugin +struct DocumentPlugin : score::DocumentPlugin { public: DocumentPlugin(const score::DocumentContext& doc, QObject* parent); @@ -17,4 +15,4 @@ struct SCORE_PLUGIN_REMOTECONTROL_EXPORT DocumentPlugin : score::DocumentPlugin HttpServer m_server; }; -} // namespace RemoteControl::HttpServer \ No newline at end of file +} \ No newline at end of file diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp index 81c9394c5b..ca97f2d7ed 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp @@ -286,21 +286,21 @@ void HttpServer::set_path(const std::string& str) void HttpServer::set_address(const std::string& str) { - bool is_runnig{running()}; - if(is_runnig) + bool is_running{running()}; + if(is_running) stop_thread(); m_endpoint.address(net::ip::make_address(str.c_str())); - if(is_runnig) + if(is_running) start_thread(); } void HttpServer::set_port(unsigned short prt) { - bool is_runnig{running()}; - if(is_runnig) + bool is_running{running()}; + if(is_running) stop_thread(); m_endpoint.port(prt); - if(is_runnig) + if(is_running) start_thread(); } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp index a3ce90bd19..4a4aa4ddd1 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/Settings/Model.cpp @@ -26,12 +26,12 @@ static auto list() , ServerPort , ServerEnabled); } -} // namespace Parameters +} Model::Model( const UuidKey& k, QSettings& set, const score::ApplicationContext& ctx) - : score::SettingsDelegateModel{k, nullptr} + : score::SettingsDelegateModel{k, nullptr} { score::setupDefaultSettings(set, Parameters::list(), *this); @@ -52,6 +52,5 @@ SCORE_SETTINGS_PARAMETER_CPP(QString, Model, WebUiPath) SCORE_SETTINGS_PARAMETER_CPP(QString, Model, ServerAddress) SCORE_SETTINGS_PARAMETER_CPP(unsigned short, Model, ServerPort) SCORE_SETTINGS_PARAMETER_CPP(bool, Model, ServerEnabled) - -} // namespace Settings -} // namespace RemoteControl +} +} From 73aac9a1b22187146bc941cfa71c5bf90fccdc48 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Mon, 13 Jul 2026 10:03:42 +0100 Subject: [PATCH 29/31] [HttpServer] thread safety --- .../RemoteControl/HttpServer/HttpServer.cpp | 3 ++- .../RemoteControl/HttpServer/HttpServer.hpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp index ca97f2d7ed..8bc582367e 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp @@ -84,6 +84,7 @@ beast::string_view HttpServer::mime_type(beast::string_view path) // The returned path is normalized for the platform. std::string HttpServer::path_cat(beast::string_view path) { + std::lock_guard lock{mtx}; if(m_buildWasmPath.empty()) return std::string(path); std::string result(m_buildWasmPath); @@ -280,7 +281,7 @@ void HttpServer::stop_thread() void HttpServer::set_path(const std::string& str) { - // FIXME : Not thread safe, but is it that bad ? + std::lock_guard lock{mtx}; m_buildWasmPath = str; } diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp index 04c2e67425..4f2962f866 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp @@ -74,5 +74,6 @@ class HttpServer std::thread m_serverThread; std::string m_buildWasmPath; int m_listenSocket{}; + std::mutex mtx{}; }; } From 35bdd558596bb374280222f4bc1a8a6d5468e511 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Tue, 14 Jul 2026 09:13:12 +0100 Subject: [PATCH 30/31] [HttpServer] ossia_score_version_agent --- .../RemoteControl/HttpServer/HttpServer.cpp | 12 +++++++----- .../RemoteControl/HttpServer/HttpServer.hpp | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp index 8bc582367e..2b19773a1c 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp @@ -113,10 +113,12 @@ template void HttpServer::handle_request( http::request>&& req, const Send& send) { + using namespace score; + // Returns a bad request response auto const bad_request = [&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::server, ossia_score_verison_agent()); res.set(http::field::content_type, "text/html"); res.keep_alive(req.keep_alive()); res.body() = std::string(why); @@ -127,7 +129,7 @@ void HttpServer::handle_request( // Returns a not found response auto const not_found = [&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::server, ossia_score_verison_agent()); res.set(http::field::content_type, "text/html"); res.keep_alive(req.keep_alive()); res.body() = "The resource '" + std::string(target) + "' was not found.
Go to the following address : http://ip_address:port/ossia_remote.html."; @@ -139,7 +141,7 @@ void HttpServer::handle_request( auto const server_error = [&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::server, ossia_score_verison_agent()); res.set(http::field::content_type, "text/html"); res.keep_alive(req.keep_alive()); res.body() = "An error occurred: '" + std::string(what) + "'"; @@ -182,7 +184,7 @@ void HttpServer::handle_request( if(req.method() == http::verb::head) { http::response res{http::status::ok, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::server, ossia_score_verison_agent()); res.set(http::field::content_type, mime_type(path)); res.content_length(size); res.keep_alive(false); @@ -199,7 +201,7 @@ void HttpServer::handle_request( res.set(http::field::access_control_allow_origin, "*"); res.set(http::field::access_control_allow_methods, "GET"); - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::server, ossia_score_verison_agent()); res.set(http::field::content_type, mime_type(path)); res.content_length(size); res.keep_alive(false); diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp index 4f2962f866..b0e1c66b69 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.hpp @@ -24,6 +24,22 @@ #define SHUT_RDWR 2 #endif +#include + +namespace score +{ +static std::string ossia_score_verison_agent() +{ + static QString agent{QCoreApplication::organizationDomain() + + '.' + + QCoreApplication::applicationName() + + '/' + + QCoreApplication::applicationVersion()}; + + return agent.toStdString(); +}; +} + namespace beast = boost::beast; // from namespace http = beast::http; // from namespace net = boost::asio; // from From 13afe3fa94f268fa7e51f3ad707ead076b842ec8 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Tue, 14 Jul 2026 19:02:05 +0100 Subject: [PATCH 31/31] [HttpServer] qDebug instaed of cerr and rebase on master --- .../RemoteControl/HttpServer/HttpServer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp index 2b19773a1c..b9628b8f2d 100644 --- a/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp +++ b/src/plugins/score-plugin-remotecontrol/RemoteControl/HttpServer/HttpServer.cpp @@ -211,7 +211,7 @@ void HttpServer::handle_request( // Report a failure void HttpServer::fail(beast::error_code ec, char const* what) { - std::cerr << what << ": " << ec.message() << "\n"; + qDebug() << what << ": " << ec.message(); } // Handles an HTTP server connection @@ -244,13 +244,13 @@ void HttpServer::do_session(tcp::socket& socket) if(ec == http::error::end_of_stream) break; if(ec) - return HttpServer::fail(ec, "read"); + HttpServer::fail(ec, "read"); // Send the response HttpServer::handle_request(std::move(req), lambda); if(ec) - return HttpServer::fail(ec, "write"); + HttpServer::fail(ec, "write"); if(close) { // This means we should close the connection, usually because @@ -329,7 +329,7 @@ int HttpServer::open_server() } catch(const std::exception& e) { - std::cerr << "Error: " << e.what() << '\n'; + qDebug() << "Error: " << e.what(); return EXIT_FAILURE; } }