Resolve IP address from last curl connection and use it as address for next Octoprint upload

IP resolve only for non secure connection and on windows.
This commit is contained in:
David Kocik 2021-11-25 15:17:41 +01:00
parent 9868206eee
commit e276b70851
4 changed files with 55 additions and 1 deletions

View File

@ -127,6 +127,7 @@ struct Http::priv
Http::CompleteFn completefn; Http::CompleteFn completefn;
Http::ErrorFn errorfn; Http::ErrorFn errorfn;
Http::ProgressFn progressfn; Http::ProgressFn progressfn;
Http::IPResolveFn ipresolvefn;
priv(const std::string &url); priv(const std::string &url);
~priv(); ~priv();
@ -390,6 +391,13 @@ void Http::priv::http_perform()
if (errorfn) { errorfn(std::move(buffer), std::string(), http_status); } if (errorfn) { errorfn(std::move(buffer), std::string(), http_status); }
} else { } else {
if (completefn) { completefn(std::move(buffer), http_status); } 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; return *this;
} }
Http& Http::on_ip_resolve(IPResolveFn fn)
{
if (p) { p->ipresolvefn = std::move(fn); }
return *this;
}
Http::Ptr Http::perform() Http::Ptr Http::perform()
{ {
auto self = std::make_shared<Http>(std::move(*this)); auto self = std::make_shared<Http>(std::move(*this));

View File

@ -41,6 +41,8 @@ public:
// Writing true to the `cancel` reference cancels the request in progress. // Writing true to the `cancel` reference cancels the request in progress.
typedef std::function<void(Progress, bool& /* cancel */)> ProgressFn; typedef std::function<void(Progress, bool& /* cancel */)> ProgressFn;
typedef std::function<void(std::string/* address */)> IPResolveFn;
Http(Http &&other); Http(Http &&other);
// Note: strings are expected to be UTF-8-encoded // Note: strings are expected to be UTF-8-encoded
@ -113,6 +115,9 @@ public:
// See the `Progress` structure for description of the data passed. // See the `Progress` structure for description of the data passed.
// Writing a true-ish value into the cancel reference parameter cancels the request. // Writing a true-ish value into the cancel reference parameter cancels the request.
Http& on_progress(ProgressFn fn); 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 // Starts performing the request in a background thread
Ptr perform(); Ptr perform();

View File

@ -76,6 +76,9 @@ bool OctoPrint::test(wxString &msg) const
}) })
#ifdef WIN32 #ifdef WIN32
.ssl_revoke_best_effort(m_ssl_revoke_best_effort) .ssl_revoke_best_effort(m_ssl_revoke_best_effort)
.on_ip_resolve([&](std::string address) {
msg = boost::nowide::widen(address);
})
#endif #endif
.perform_sync(); .perform_sync();
@ -108,9 +111,25 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro
return false; return false;
} }
std::string url;
bool res = true; 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%") BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%")
% name % 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) : SL1Host::SL1Host(DynamicPrintConfig *config) :
OctoPrint(config), OctoPrint(config),
m_authorization_type(dynamic_cast<const ConfigOptionEnum<AuthorizationType>*>(config->option("printhost_authorization_type"))->value), m_authorization_type(dynamic_cast<const ConfigOptionEnum<AuthorizationType>*>(config->option("printhost_authorization_type"))->value),

View File

@ -44,6 +44,7 @@ private:
virtual void set_auth(Http &http) const; 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 make_url(const std::string& path, const std::string& addr) const;
}; };
class SL1Host: public OctoPrint class SL1Host: public OctoPrint