Replaced the code to substitute host address part in URL
with libcurl library calls. This solution should be more robust than a homebrew URL parser solution.
This commit is contained in:
parent
f88d678a4a
commit
f4dfbb69e2
3 changed files with 51 additions and 15 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
#include <exception>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <wx/progdlg.h>
|
||||
|
||||
#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%")
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue