From 1cac04eae8496b687fc6e1b83903dbcb4cc1d0cb Mon Sep 17 00:00:00 2001 From: peachismomo Date: Thu, 1 Oct 2026 00:28:57 +0800 Subject: [PATCH] refactor: separate out networking infra --- src/slic3r/CMakeLists.txt | 2 +- src/slic3r/GUI/Monitor.cpp | 5 +-- src/slic3r/GUI/ReleaseNote.cpp | 38 ++++++++------------ src/slic3r/GUI/ReleaseNote.hpp | 2 +- src/slic3r/Utils/Http.cpp | 63 ++++------------------------------ src/slic3r/Utils/Http.hpp | 6 ---- src/slic3r/Utils/Moonraker.cpp | 25 +++----------- 7 files changed, 28 insertions(+), 113 deletions(-) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index bf0047644c..07c486242c 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -908,7 +908,7 @@ target_include_directories(libslic3r_gui PRIVATE Utils ${CMAKE_CURRENT_BINARY_DI if (WIN32) target_include_directories(libslic3r_gui SYSTEM PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../deps/WebView2/include) - target_link_libraries(libslic3r_gui Advapi32 Crypt32) + target_link_libraries(libslic3r_gui Advapi32) endif() source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SLIC3R_GUI_SOURCES}) diff --git a/src/slic3r/GUI/Monitor.cpp b/src/slic3r/GUI/Monitor.cpp index 91bbbf8930..eb5a8eb5e9 100644 --- a/src/slic3r/GUI/Monitor.cpp +++ b/src/slic3r/GUI/Monitor.cpp @@ -276,10 +276,7 @@ void MonitorPanel::select_machine(std::string machine_sn) void MonitorPanel::on_timer(wxTimerEvent& event) { - // MediaPlayCtrl may yield the event loop while it joins its camera worker - // during window teardown. Do not let a queued monitor refresh touch panels - // that are already being destroyed. - if (!wxGetApp().is_closing() && update_flag) { + if (update_flag) { update_all(); //Layout(); } diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index 17bb494b5f..cb49da461a 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -1777,7 +1777,7 @@ void InputIpAddressDialog::set_machine_obj(MachineObject* obj) auto str_ip = m_input_ip->GetTextCtrl()->GetValue(); auto str_access_code = m_input_access_code->GetTextCtrl()->GetValue(); // ORCA enabling / disabling buttons with conditions enough to change its style - m_button_ok->Enable(isValidEndpoint(str_ip.ToStdString()) && + m_button_ok->Enable(isIp(str_ip.ToStdString()) && (str_access_code.IsEmpty() || str_access_code.Length() >= 8)); Layout(); @@ -1815,29 +1815,19 @@ void InputIpAddressDialog::update_test_msg(wxString msg,bool connected) Fit(); } -bool InputIpAddressDialog::isValidEndpoint(std::string endpoint) +bool InputIpAddressDialog::isIp(std::string ipstr) { - if (endpoint.empty() || std::any_of(endpoint.begin(), endpoint.end(), [](unsigned char c) { - return std::isspace(c) != 0; - })) - return false; - - const bool has_http_scheme = endpoint.rfind("http://", 0) == 0; - const bool has_https_scheme = endpoint.rfind("https://", 0) == 0; - const auto scheme_pos = endpoint.find("://"); - if (scheme_pos != std::string::npos && !has_http_scheme && !has_https_scheme) - return false; - - std::string port; - const std::string host = Http::get_host_from_url(endpoint, &port); - if (host.empty()) - return false; - - // get_host_from_url returns its input when libcurl cannot parse it. For a - // URL with a scheme, that means a failed parse still needs to be rejected. - if (scheme_pos != std::string::npos && host == endpoint) - return false; - + istringstream ipstream(ipstr); + int num[4]; + char point[3]; + string end; + ipstream >> num[0] >> point[0] >> num[1] >> point[1] >> num[2] >> point[2] >> num[3] >> end; + for (int i = 0; i < 3; ++i) { + if (num[i] < 0 || num[i]>255) return false; + if (point[i] != '.') return false; + } + if (num[3] < 0 || num[3]>255) return false; + if (!end.empty()) return false; return true; } @@ -2140,7 +2130,7 @@ void InputIpAddressDialog::on_text(wxCommandEvent &evt) // ORCA enabling / disabling buttons with conditions enough to change its style bool valid_access_code_length = str_access_code.IsEmpty() || str_access_code.Length() >= 8; - bool enable_btns = isValidEndpoint(str_ip.ToStdString()) && valid_access_code_length && invalid_access_code; + bool enable_btns = isIp(str_ip.ToStdString()) && valid_access_code_length && invalid_access_code; m_button_manual_setup->Enable(enable_btns); m_button_ok->Enable(enable_btns); diff --git a/src/slic3r/GUI/ReleaseNote.hpp b/src/slic3r/GUI/ReleaseNote.hpp index 5d950005df..5d7c0b25c4 100644 --- a/src/slic3r/GUI/ReleaseNote.hpp +++ b/src/slic3r/GUI/ReleaseNote.hpp @@ -348,7 +348,7 @@ public: void update_title(wxString title); void set_machine_obj(MachineObject* obj); void update_test_msg(wxString msg, bool connected); - bool isValidEndpoint(std::string endpoint); + bool isIp(std::string ipstr); void check_ip_address_failed(int result); void on_check_ip_address_failed(wxCommandEvent& evt); void on_ok(wxMouseEvent& evt); diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index 05e1d6c77c..6f43df74e4 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -1,6 +1,5 @@ #include "Http.hpp" -#include #include #include #include @@ -15,19 +14,8 @@ #include -#include -#include +#ifdef OPENSSL_CERT_OVERRIDE #include -#include - -#ifdef _WIN32 -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include -# include -// wincrypt.h uses this token for a certificate-name property identifier. -# undef X509_NAME #endif namespace fs = boost::filesystem; @@ -134,7 +122,7 @@ struct Http::priv std::string error_buffer; // Used for CURLOPT_ERRORBUFFER std::string headers; size_t limit; - std::atomic_bool cancel; + bool cancel; std::unique_ptr putFile; std::thread io_thread; @@ -272,9 +260,9 @@ int Http::priv::xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_o self->progressfn(progress, cb_cancel); } - if (cb_cancel) { self->cancel.store(true); } + if (cb_cancel) { self->cancel = true; } - return self->cancel.load(); + return self->cancel; } int Http::priv::xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow) @@ -485,7 +473,7 @@ void Http::priv::http_perform() if (res != CURLE_OK) { if (res == CURLE_ABORTED_BY_CALLBACK) { - if (cancel.load()) { + if (cancel) { // The abort comes from the request being cancelled programatically Progress dummyprogress(0, 0, 0, 0, std::string()); bool cancel = true; @@ -796,7 +784,7 @@ void Http::perform_sync() void Http::cancel() { - if (p) { p->cancel.store(true); } + if (p) { p->cancel = true; } } void Http::print() const @@ -951,45 +939,6 @@ std::string Http::tls_system_cert_store() return ret; } -void Http::add_platform_root_certificates(SSL_CTX* ssl_context) -{ -#ifdef _WIN32 - X509_STORE* openssl_store = SSL_CTX_get_cert_store(ssl_context); - if (!openssl_store) - throw std::runtime_error("unable to get OpenSSL certificate store"); - - const auto load_store = [&](DWORD location) { - HCERTSTORE windows_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, - location | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, - L"ROOT"); - if (!windows_store) - return; - - PCCERT_CONTEXT windows_certificate = nullptr; - while ((windows_certificate = CertEnumCertificatesInStore(windows_store, windows_certificate)) != nullptr) { - const unsigned char* encoded = windows_certificate->pbCertEncoded; - X509* certificate = d2i_X509(nullptr, &encoded, static_cast(windows_certificate->cbCertEncoded)); - if (!certificate) { - ERR_clear_error(); - continue; - } - - ERR_clear_error(); - if (X509_STORE_add_cert(openssl_store, certificate) != 1) - ERR_clear_error(); - X509_free(certificate); - } - - CertCloseStore(windows_store, 0); - }; - - load_store(CERT_SYSTEM_STORE_CURRENT_USER); - load_store(CERT_SYSTEM_STORE_LOCAL_MACHINE); -#else - (void)ssl_context; -#endif -} - std::string Http::url_encode(const std::string &str) { ::CURL *curl = ::curl_easy_init(); diff --git a/src/slic3r/Utils/Http.hpp b/src/slic3r/Utils/Http.hpp index 87dd57d8cb..a44a95e605 100644 --- a/src/slic3r/Utils/Http.hpp +++ b/src/slic3r/Utils/Http.hpp @@ -11,8 +11,6 @@ #include "libslic3r/Exception.hpp" #include "libslic3r_version.h" -typedef struct ssl_ctx_st SSL_CTX; - #define MAX_SIZE_TO_FILE 3*1024 namespace Slic3r { @@ -200,10 +198,6 @@ public: // Return empty string on success or error message on fail. static std::string tls_global_init(); static std::string tls_system_cert_store(); - // Add platform root certificates to a standalone OpenSSL context. This - // supplements set_default_verify_paths() on platforms where OpenSSL does - // not use the native certificate store. - static void add_platform_root_certificates(SSL_CTX* ssl_context); // converts the given string to an url_encoded_string static std::string url_encode(const std::string &str); diff --git a/src/slic3r/Utils/Moonraker.cpp b/src/slic3r/Utils/Moonraker.cpp index f70be1906e..73fdb8486a 100644 --- a/src/slic3r/Utils/Moonraker.cpp +++ b/src/slic3r/Utils/Moonraker.cpp @@ -38,25 +38,12 @@ wxString Moonraker::get_test_failed_msg(wxString &msg) const std::string Moonraker::make_url(const std::string &path) const { - const bool has_scheme = m_host.find("http://") == 0 || m_host.find("https://") == 0; - const bool use_ssl = m_host.find("https://") == 0; - std::string base = has_scheme ? m_host : ("http://" + m_host); - - const size_t authority_start = base.find("://") + 3; - const size_t authority_end = base.find('/', authority_start); - const std::string authority = base.substr(authority_start, authority_end - authority_start); - const size_t closing_bracket = authority.rfind(']'); - const bool has_port = closing_bracket != std::string::npos - ? closing_bracket + 1 < authority.size() && authority[closing_bracket + 1] == ':' - : authority.find(':') != std::string::npos; - if (!has_port) { - const std::string default_port = use_ssl ? ":7130" : ":7125"; - base.insert(authority_end == std::string::npos ? base.size() : authority_end, default_port); + if (m_host.find("http://") == 0 || m_host.find("https://") == 0) { + if (m_host.back() == '/') + return (boost::format("%1%%2%") % m_host % path).str(); + return (boost::format("%1%/%2%") % m_host % path).str(); } - - if (base.back() == '/') - return (boost::format("%1%%2%") % base % path).str(); - return (boost::format("%1%/%2%") % base % path).str(); + return (boost::format("http://%1%/%2%") % m_host % path).str(); } void Moonraker::set_auth(Http &http) const @@ -66,8 +53,6 @@ void Moonraker::set_auth(Http &http) const // filled the user/password fields — those are PrusaLink/OctoPrint conventions. if (!m_apikey.empty()) http.header("X-Api-Key", m_apikey); - const bool use_ssl = m_host.find("https://") == 0; - http.tls_verify(use_ssl); if (!m_cafile.empty()) http.ca_file(m_cafile); }