diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index fc7afbb34..63c26f721 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -127,6 +127,7 @@ struct Http::priv Http::CompleteFn completefn; Http::ErrorFn errorfn; Http::ProgressFn progressfn; + Http::IPResolveFn ipresolvefn; priv(const std::string &url); ~priv(); @@ -390,6 +391,13 @@ void Http::priv::http_perform() if (errorfn) { errorfn(std::move(buffer), std::string(), http_status); } } else { if (completefn) { completefn(std::move(buffer), http_status); } + if (ipresolvefn) { + char* ct; + res = curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &ct); + if ((CURLE_OK == res) && ct) { + ipresolvefn(ct); + } + } } } } @@ -554,6 +562,12 @@ Http& Http::on_progress(ProgressFn fn) return *this; } +Http& Http::on_ip_resolve(IPResolveFn fn) +{ + if (p) { p->ipresolvefn = std::move(fn); } + return *this; +} + Http::Ptr Http::perform() { auto self = std::make_shared(std::move(*this)); diff --git a/src/slic3r/Utils/Http.hpp b/src/slic3r/Utils/Http.hpp index 61d84c51e..2f458582d 100644 --- a/src/slic3r/Utils/Http.hpp +++ b/src/slic3r/Utils/Http.hpp @@ -41,6 +41,8 @@ public: // Writing true to the `cancel` reference cancels the request in progress. typedef std::function ProgressFn; + typedef std::function IPResolveFn; + Http(Http &&other); // Note: strings are expected to be UTF-8-encoded @@ -113,6 +115,9 @@ public: // See the `Progress` structure for description of the data passed. // Writing a true-ish value into the cancel reference parameter cancels the request. Http& on_progress(ProgressFn fn); + // Callback called after succesful HTTP request (after on_complete callback) + // Called if curl_easy_getinfo resolved just used IP address. + Http& on_ip_resolve(IPResolveFn fn); // Starts performing the request in a background thread Ptr perform(); diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index f9ae4af5a..12db505b2 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -76,6 +76,9 @@ 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); + }) #endif .perform_sync(); @@ -108,9 +111,25 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro return false; } + std::string url; bool res = true; - auto url = make_url("api/files/local"); + if (m_host.find("https://") == 0 || test_msg.empty()) + { + // 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. + // Solves troubles of uploades failing with name address. + std::string resolved_addr = boost::nowide::narrow(test_msg); + // put ipv6 into [] brackets (there shouldn't be any http:// if its resolved addr) + if (resolved_addr.find(':') != std::string::npos && resolved_addr.at(0) != '[') + resolved_addr = "[" + resolved_addr + "]"; + url = make_url("api/files/local", resolved_addr); + } BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%") % name @@ -176,6 +195,21 @@ std::string OctoPrint::make_url(const std::string &path) const } } +std::string OctoPrint::make_url(const std::string& path, const std::string& addr) const +{ + std::string hst = addr.empty() ? m_host : addr; + if (hst.find("http://") == 0 || hst.find("https://") == 0) { + if (hst.back() == '/') { + return (boost::format("%1%%2%") % hst % path).str(); + } + else { + return (boost::format("%1%/%2%") % hst % path).str(); + } + } else { + return (boost::format("http://%1%/%2%") % hst % path).str(); + } +} + SL1Host::SL1Host(DynamicPrintConfig *config) : OctoPrint(config), m_authorization_type(dynamic_cast*>(config->option("printhost_authorization_type"))->value), diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index 48035b795..481b79731 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -44,6 +44,7 @@ private: virtual void set_auth(Http &http) const; std::string make_url(const std::string &path) const; + std::string make_url(const std::string& path, const std::string& addr) const; }; class SL1Host: public OctoPrint