Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::Http::priv Struct Reference
+ Collaboration diagram for Slic3r::Http::priv:

Public Types

enum  { DEFAULT_TIMEOUT_CONNECT = 10 , DEFAULT_TIMEOUT_MAX = 0 , DEFAULT_SIZE_LIMIT = 5 * 1024 * 1024 }
 

Public Member Functions

 priv (const std::string &url)
 
 ~priv ()
 
void set_timeout_connect (long timeout)
 
void set_timeout_max (long timeout)
 
void form_add_file (const char *name, const fs::path &path, const char *filename)
 
void set_post_body (const fs::path &path)
 
void set_post_body (const std::string &body)
 
void set_put_body (const fs::path &path)
 
void set_range (const std::string &range)
 
std::string curl_error (CURLcode curlcode)
 
std::string body_size_error ()
 
void http_perform ()
 

Static Public Member Functions

static bool ca_file_supported (::CURL *curl)
 
static size_t writecb (void *data, size_t size, size_t nmemb, void *userp)
 
static int xfercb (void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
 
static int xfercb_legacy (void *userp, double dltotal, double dlnow, double ultotal, double ulnow)
 
static size_t form_file_read_cb (char *buffer, size_t size, size_t nitems, void *userp)
 

Public Attributes

::CURL * curl
 
::curl_httppost * form
 
::curl_httppost * form_end
 
::curl_slist * headerlist
 
std::string buffer
 
std::deque< fs::ifstream > form_files
 
std::string postfields
 
std::string error_buffer
 
size_t limit
 
bool cancel
 
std::unique_ptr< fs::ifstream > putFile
 
std::thread io_thread
 
Http::CompleteFn completefn
 
Http::ErrorFn errorfn
 
Http::ProgressFn progressfn
 
Http::IPResolveFn ipresolvefn
 

Detailed Description

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
DEFAULT_TIMEOUT_CONNECT 
DEFAULT_TIMEOUT_MAX 
DEFAULT_SIZE_LIMIT 
105 {
108 DEFAULT_SIZE_LIMIT = 5 * 1024 * 1024,
109 };
@ DEFAULT_SIZE_LIMIT
Definition Http.cpp:108
@ DEFAULT_TIMEOUT_MAX
Definition Http.cpp:107
@ DEFAULT_TIMEOUT_CONNECT
Definition Http.cpp:106

Constructor & Destructor Documentation

◆ priv()

Slic3r::Http::priv::priv ( const std::string &  url)
155 : curl(::curl_easy_init())
156 , form(nullptr)
157 , form_end(nullptr)
158 , headerlist(nullptr)
159 , error_buffer(CURL_ERROR_SIZE + 1, '\0')
160 , limit(0)
161 , cancel(false)
162{
164
165 if (curl == nullptr) {
166 throw Slic3r::RuntimeError(std::string("Could not construct Curl object"));
167 }
168
171 ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // curl makes a copy internally
172 ::curl_easy_setopt(curl, CURLOPT_USERAGENT, SLIC3R_APP_NAME "/" SLIC3R_VERSION);
173 ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer.front());
174}
static std::string tls_global_init()
Definition Http.cpp:634
bool cancel
Definition Http.cpp:123
size_t limit
Definition Http.cpp:122
void set_timeout_connect(long timeout)
Definition Http.cpp:256
::CURL * curl
Definition Http.cpp:111
::curl_httppost * form
Definition Http.cpp:112
::curl_httppost * form_end
Definition Http.cpp:113
::curl_slist * headerlist
Definition Http.cpp:114
std::string error_buffer
Definition Http.cpp:121
void set_timeout_max(long timeout)
Definition Http.cpp:261

References curl, DEFAULT_TIMEOUT_CONNECT, DEFAULT_TIMEOUT_MAX, error_buffer, set_timeout_connect(), set_timeout_max(), and Slic3r::Http::tls_global_init().

+ Here is the call graph for this function:

◆ ~priv()

Slic3r::Http::priv::~priv ( )
177{
178 ::curl_easy_cleanup(curl);
179 ::curl_formfree(form);
180 ::curl_slist_free_all(headerlist);
181}

Member Function Documentation

◆ body_size_error()

std::string Slic3r::Http::priv::body_size_error ( )
332{
333 return (boost::format("HTTP body data size exceeded limit (%1% bytes)") % limit).str();
334}

◆ ca_file_supported()

bool Slic3r::Http::priv::ca_file_supported ( ::CURL *  curl)
static
184{
185#if defined(_WIN32) || defined(__APPLE__)
186 bool res = false;
187#else
188 bool res = true;
189#endif
190
191 if (curl == nullptr) { return res; }
192
193#if LIBCURL_VERSION_MAJOR >= 7 && LIBCURL_VERSION_MINOR >= 48
194 ::curl_tlssessioninfo *tls;
195 if (::curl_easy_getinfo(curl, CURLINFO_TLS_SSL_PTR, &tls) == CURLE_OK) {
196 if (tls->backend == CURLSSLBACKEND_SCHANNEL || tls->backend == CURLSSLBACKEND_DARWINSSL) {
197 // With Windows and OS X native SSL support, cert files cannot be set
198 // DK: OSX is now not building CURL and links system one, thus we do not know which backend is installed. Still, false will be returned since the ifdef at the begining if this function.
199 res = false;
200 }
201 }
202#endif
203
204 return res;
205}

Referenced by Slic3r::Http::ca_file(), and Slic3r::Http::ca_file_supported().

+ Here is the caller graph for this function:

◆ curl_error()

std::string Slic3r::Http::priv::curl_error ( CURLcode  curlcode)
323{
324 return (boost::format("%1%:\n%2%\n[Error %3%]")
325 % ::curl_easy_strerror(curlcode)
326 % error_buffer.c_str()
327 % curlcode
328 ).str();
329}

◆ form_add_file()

void Slic3r::Http::priv::form_add_file ( const char *  name,
const fs::path &  path,
const char *  filename 
)
267{
268 // We can't use CURLFORM_FILECONTENT, because curl doesn't support Unicode filenames on Windows
269 // and so we use CURLFORM_STREAM with boost ifstream to read the file.
270
271 if (filename == nullptr) {
272 filename = path.string().c_str();
273 }
274
275 form_files.emplace_back(path, std::ios::in | std::ios::binary);
276 auto &stream = form_files.back();
277 stream.seekg(0, std::ios::end);
278 size_t size = stream.tellg();
279 stream.seekg(0);
280
281 if (filename != nullptr) {
282 ::curl_formadd(&form, &form_end,
283 CURLFORM_COPYNAME, name,
284 CURLFORM_FILENAME, filename,
285 CURLFORM_CONTENTTYPE, "application/octet-stream",
286 CURLFORM_STREAM, static_cast<void*>(&stream),
287 CURLFORM_CONTENTSLENGTH, static_cast<long>(size),
288 CURLFORM_END
289 );
290 }
291}
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183
std::deque< fs::ifstream > form_files
Definition Http.cpp:119

◆ form_file_read_cb()

size_t Slic3r::Http::priv::form_file_read_cb ( char *  buffer,
size_t  size,
size_t  nitems,
void userp 
)
static
244{
245 auto stream = reinterpret_cast<fs::ifstream*>(userp);
246
247 try {
248 stream->read(buffer, size * nitems);
249 } catch (const std::exception &) {
250 return CURL_READFUNC_ABORT;
251 }
252
253 return stream->gcount();
254}
std::string buffer
Definition Http.cpp:116

◆ http_perform()

void Slic3r::Http::priv::http_perform ( )
337{
338 ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
339 ::curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
340 ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb);
341 ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast<void*>(this));
342 ::curl_easy_setopt(curl, CURLOPT_READFUNCTION, form_file_read_cb);
343
344 ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
345#if LIBCURL_VERSION_MAJOR >= 7 && LIBCURL_VERSION_MINOR >= 32
346 ::curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xfercb);
347 ::curl_easy_setopt(curl, CURLOPT_XFERINFODATA, static_cast<void*>(this));
348#ifndef _WIN32
349 (void)xfercb_legacy; // prevent unused function warning
350#endif
351#else
352 ::curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, xfercb);
353 ::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, static_cast<void*>(this));
354#endif
355
356 ::curl_easy_setopt(curl, CURLOPT_VERBOSE, get_logging_level() >= 5);
357
358 if (headerlist != nullptr) {
359 ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
360 }
361
362 if (form != nullptr) {
363 ::curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
364 }
365
366 if (!postfields.empty()) {
367 ::curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfields.c_str());
368 ::curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, postfields.size());
369 }
370
371 CURLcode res = ::curl_easy_perform(curl);
372
373 putFile.reset();
374
375 if (res != CURLE_OK) {
376 if (res == CURLE_ABORTED_BY_CALLBACK) {
377 if (cancel) {
378 // The abort comes from the request being cancelled programatically
379 Progress dummyprogress(0, 0, 0, 0, std::string());
380 bool cancel = true;
381 if (progressfn) { progressfn(dummyprogress, cancel); }
382 } else {
383 // The abort comes from the CURLOPT_READFUNCTION callback, which means reading file failed
384 if (errorfn) { errorfn(std::move(buffer), "Error reading file for file upload", 0); }
385 }
386 }
387 else if (res == CURLE_WRITE_ERROR) {
388 if (errorfn) { errorfn(std::move(buffer), body_size_error(), 0); }
389 } else {
390 if (errorfn) { errorfn(std::move(buffer), curl_error(res), 0); }
391 };
392 } else {
393 long http_status = 0;
394 ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
395
396 if (http_status >= 400) {
397 if (errorfn) { errorfn(std::move(buffer), std::string(), http_status); }
398 } else {
399 if (completefn) { completefn(std::move(buffer), http_status); }
400 if (ipresolvefn) {
401 char* ct;
402 res = curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &ct);
403 if ((CURLE_OK == res) && ct) {
404 ipresolvefn(ct);
405 }
406 }
407 }
408 }
409}
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
unsigned get_logging_level()
Definition utils.cpp:107
#define L(s)
Definition I18N.hpp:18
Http::CompleteFn completefn
Definition Http.cpp:127
std::string curl_error(CURLcode curlcode)
Definition Http.cpp:322
Http::ProgressFn progressfn
Definition Http.cpp:129
static size_t form_file_read_cb(char *buffer, size_t size, size_t nitems, void *userp)
Definition Http.cpp:243
std::string postfields
Definition Http.cpp:120
static size_t writecb(void *data, size_t size, size_t nmemb, void *userp)
Definition Http.cpp:207
static int xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
Definition Http.cpp:223
Http::ErrorFn errorfn
Definition Http.cpp:128
static int xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow)
Definition Http.cpp:238
Http::IPResolveFn ipresolvefn
Definition Http.cpp:130
std::unique_ptr< fs::ifstream > putFile
Definition Http.cpp:124
std::string body_size_error()
Definition Http.cpp:331

References Slic3r::Http::cancel(), Slic3r::get_logging_level(), L, and void().

+ Here is the call graph for this function:

◆ set_post_body() [1/2]

void Slic3r::Http::priv::set_post_body ( const fs::path &  path)
295{
296 std::ifstream file(path.string());
297 std::string file_content { std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>() };
298 postfields = std::move(file_content);
299}

◆ set_post_body() [2/2]

void Slic3r::Http::priv::set_post_body ( const std::string &  body)
302{
303 postfields = body;
304}

◆ set_put_body()

void Slic3r::Http::priv::set_put_body ( const fs::path &  path)
307{
308 boost::system::error_code ec;
309 boost::uintmax_t filesize = file_size(path, ec);
310 if (!ec) {
311 putFile = std::make_unique<fs::ifstream>(path);
312 ::curl_easy_setopt(curl, CURLOPT_READDATA, (void *) (putFile.get()));
313 ::curl_easy_setopt(curl, CURLOPT_INFILESIZE, filesize);
314 }
315}

◆ set_range()

void Slic3r::Http::priv::set_range ( const std::string &  range)
318{
319 ::curl_easy_setopt(curl, CURLOPT_RANGE, range.c_str());
320}
auto range(Cont &&cont)
Definition libslic3r.h:356

References Slic3r::range().

+ Here is the call graph for this function:

◆ set_timeout_connect()

void Slic3r::Http::priv::set_timeout_connect ( long  timeout)
257{
258 ::curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
259}

Referenced by priv().

+ Here is the caller graph for this function:

◆ set_timeout_max()

void Slic3r::Http::priv::set_timeout_max ( long  timeout)
262{
263 ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
264}

Referenced by priv().

+ Here is the caller graph for this function:

◆ writecb()

size_t Slic3r::Http::priv::writecb ( void data,
size_t  size,
size_t  nmemb,
void userp 
)
static
208{
209 auto self = static_cast<priv*>(userp);
210 const char *cdata = static_cast<char*>(data);
211 const size_t realsize = size * nmemb;
212 const size_t limit = self->limit > 0 ? self->limit : DEFAULT_SIZE_LIMIT;
213 if (self->buffer.size() + realsize > limit) {
214 // This makes curl_easy_perform return CURLE_WRITE_ERROR
215 return 0;
216 }
217
218 self->buffer.append(cdata, realsize);
219
220 return realsize;
221}
constexpr auto data(C &c) -> decltype(c.data())
Definition span.hpp:195
Definition CutSurface.cpp:39

◆ xfercb()

int Slic3r::Http::priv::xfercb ( void userp,
curl_off_t  dltotal,
curl_off_t  dlnow,
curl_off_t  ultotal,
curl_off_t  ulnow 
)
static
224{
225 auto self = static_cast<priv*>(userp);
226 bool cb_cancel = false;
227
228 if (self->progressfn) {
229 Progress progress(dltotal, dlnow, ultotal, ulnow, self->buffer);
230 self->progressfn(progress, cb_cancel);
231 }
232
233 if (cb_cancel) { self->cancel = true; }
234
235 return self->cancel;
236}

◆ xfercb_legacy()

int Slic3r::Http::priv::xfercb_legacy ( void userp,
double  dltotal,
double  dlnow,
double  ultotal,
double  ulnow 
)
static
239{
240 return xfercb(userp, dltotal, dlnow, ultotal, ulnow);
241}

Member Data Documentation

◆ buffer

std::string Slic3r::Http::priv::buffer

◆ cancel

bool Slic3r::Http::priv::cancel

◆ completefn

Http::CompleteFn Slic3r::Http::priv::completefn

◆ curl

::CURL* Slic3r::Http::priv::curl

Referenced by priv().

◆ error_buffer

std::string Slic3r::Http::priv::error_buffer

Referenced by priv().

◆ errorfn

Http::ErrorFn Slic3r::Http::priv::errorfn

◆ form

::curl_httppost* Slic3r::Http::priv::form

◆ form_end

::curl_httppost* Slic3r::Http::priv::form_end

◆ form_files

std::deque<fs::ifstream> Slic3r::Http::priv::form_files

◆ headerlist

::curl_slist* Slic3r::Http::priv::headerlist

◆ io_thread

std::thread Slic3r::Http::priv::io_thread

◆ ipresolvefn

Http::IPResolveFn Slic3r::Http::priv::ipresolvefn

◆ limit

size_t Slic3r::Http::priv::limit

◆ postfields

std::string Slic3r::Http::priv::postfields

◆ progressfn

Http::ProgressFn Slic3r::Http::priv::progressfn

◆ putFile

std::unique_ptr<fs::ifstream> Slic3r::Http::priv::putFile

The documentation for this struct was generated from the following file: