diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 197de43eeb..c2dfcb24cc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2219,6 +2219,7 @@ Plater::priv::~priv() { if (config != nullptr) delete config; + // Saves the database of visited (already shown) hints into hints.ini. notification_manager->deactivate_loaded_hints(); } diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index 6aa753404a..9842d7d89a 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -5,13 +5,15 @@ #include #include #include -#include #include #include #include +#include + #include +#include "slic3r/GUI/GUI.hpp" #include "slic3r/GUI/I18N.hpp" #include "slic3r/GUI/GUI.hpp" #include "Http.hpp" @@ -25,8 +27,13 @@ namespace pt = boost::property_tree; namespace Slic3r { namespace { -std::string substitute_host(const std::string& orig_addr, const std::string sub_addr) +std::string substitute_host(const std::string& orig_addr, std::string sub_addr) { + // put ipv6 into [] brackets + if (sub_addr.find(':') != std::string::npos && sub_addr.at(0) != '[') + sub_addr = "[" + sub_addr + "]"; + +#if 0 //URI = scheme ":"["//"[userinfo "@"] host [":" port]] path["?" query]["#" fragment] std::string final_addr = orig_addr; // http @@ -52,6 +59,35 @@ std::string substitute_host(const std::string& orig_addr, const std::string sub_ } final_addr.replace(host_start, host_end - host_start, sub_addr); return final_addr; +#else + // Using the new CURL API for handling URL. https://everything.curl.dev/libcurl/url + // If anything fails, return the input unchanged. + std::string out = orig_addr; + CURLU *hurl = curl_url(); + if (hurl) { + // Parse the input URL. + CURLUcode rc = curl_url_set(hurl, CURLUPART_URL, orig_addr.c_str(), 0); + if (rc == CURLUE_OK) { + // Replace the address. + rc = curl_url_set(hurl, CURLUPART_HOST, sub_addr.c_str(), 0); + if (rc == CURLUE_OK) { + // Extract a string fromt the CURL URL handle. + char *url; + rc = curl_url_get(hurl, CURLUPART_URL, &url, 0); + if (rc == CURLUE_OK) { + out = url; + curl_free(url); + } else + BOOST_LOG_TRIVIAL(error) << "OctoPrint substitute_host: failed to extract the URL after substitution"; + } else + BOOST_LOG_TRIVIAL(error) << "OctoPrint substitute_host: failed to substitute host " << sub_addr << " in URL " << orig_addr; + } else + BOOST_LOG_TRIVIAL(error) << "OctoPrint substitute_host: failed to parse URL " << orig_addr; + curl_url_cleanup(hurl); + } else + BOOST_LOG_TRIVIAL(error) << "OctoPrint substitute_host: failed to allocate curl_url"; + return out; +#endif } } //namespace @@ -110,7 +146,7 @@ bool OctoPrint::test(wxString &msg) const #ifdef WIN32 .ssl_revoke_best_effort(m_ssl_revoke_best_effort) .on_ip_resolve([&](std::string address) { - msg = boost::nowide::widen(address); + msg = GUI::from_u8(address); }) #endif .perform_sync(); @@ -138,9 +174,11 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro const auto upload_filename = upload_data.upload_path.filename(); const auto upload_parent_path = upload_data.upload_path.parent_path(); - wxString test_msg; - if (! test(test_msg)) { - error_fn(std::move(test_msg)); + // If test fails, test_msg_or_host_ip contains the error message. + // Otherwise on Windows it contains the resolved IP address of the host. + wxString test_msg_or_host_ip; + if (! test(test_msg_or_host_ip)) { + error_fn(std::move(test_msg_or_host_ip)); return false; } @@ -149,23 +187,18 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro bool allow_ip_resolve = GUI::get_app_config()->get("allow_ip_resolve") == "1"; - if (m_host.find("https://") == 0 || test_msg.empty() || !allow_ip_resolve) { + if (m_host.find("https://") == 0 || test_msg_or_host_ip.empty() || !allow_ip_resolve) { // If https is entered we assume signed ceritificate is being used // IP resolving will not happen - it could resolve into address not being specified in cert url = make_url("api/files/local"); } else { // Curl uses easy_getinfo to get ip address of last successful transaction. // If it got the address use it instead of the stored in "host" variable. - // This new address returns in "test_msg" variable. + // This new address returns in "test_msg_or_host_ip" variable. // Solves troubles of uploades failing with name address. - std::string resolved_addr = boost::nowide::narrow(test_msg); - // put ipv6 into [] brackets - if (resolved_addr.find(':') != std::string::npos && resolved_addr.at(0) != '[') - resolved_addr = "[" + resolved_addr + "]"; // in original address (m_host) replace host for resolved ip - std::string final_addr = substitute_host(m_host, resolved_addr); - BOOST_LOG_TRIVIAL(debug) << "Upload address after ip resolve: " << final_addr; - url = make_url("api/files/local", final_addr); + url = substitute_host(make_url("api/files/local", m_host), GUI::into_u8(test_msg_or_host_ip)); + BOOST_LOG_TRIVIAL(info) << "Upload address after ip resolve: " << url; } BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%") diff --git a/src/slic3r/Utils/TCPConsole.hpp b/src/slic3r/Utils/TCPConsole.hpp index 7c0e1d2901..d353634e87 100644 --- a/src/slic3r/Utils/TCPConsole.hpp +++ b/src/slic3r/Utils/TCPConsole.hpp @@ -13,6 +13,8 @@ namespace Utils { using boost::asio::ip::tcp; +// Generic command / response TCP telnet like console class. +// Used by the MKS host to send G-code commands to test connection ("M105") and to start printing ("M23 filename", "M24"). class TCPConsole { public: