27 #include <curl/curl.h>
29 #include <wx/filename.h>
32 #include "model/downloader.h"
35 static size_t throw_cb(
void* ptr,
size_t size,
size_t nmemb,
void* data) {
38 return (
size_t)(size * nmemb);
41 static unsigned write_cb(
char* in,
unsigned size,
unsigned nmemb,
void* data);
44 Downloader::Downloader(std::string url_)
45 : url(url_), stream(), error_msg(
""), errorcode(0){};
52 stream->write(buff, bytes);
57 char curl_errbuf[CURL_ERROR_SIZE];
59 this->stream = stream;
60 curl = curl_easy_init();
61 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
62 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
63 curl_easy_setopt(curl, CURLOPT_USERAGENT,
"Mozilla/5.0");
64 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
65 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
67 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
68 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
69 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
70 curl_easy_setopt(curl, CURLOPT_WRITEDATA,
this);
71 curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
72 int code = curl_easy_perform(curl);
73 curl_easy_cleanup(curl);
74 if (code != CURLE_OK) {
75 wxLogWarning(
"Failed to get '%s' [%s]\n", url, curl_errbuf);
77 error_msg = std::string(curl_errbuf);
85 path = wxFileName::CreateTempFileName(
"ocpn_dl").ToStdString();
88 stream.open(path.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
89 if (!stream.is_open()) {
90 errorcode = CURLE_WRITE_ERROR;
91 error_msg = std::string(
"Cannot open temporary file ") + path;
101 char curl_errbuf[CURL_ERROR_SIZE] = {0};
102 double filesize = 0.0;
104 curl = curl_easy_init();
105 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
106 curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
107 curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
108 curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, throw_cb);
109 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
110 curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
112 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
114 int r = curl_easy_perform(curl);
116 r = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
118 curl_easy_cleanup(curl);
119 wxLogMessage(
"filesize %s: %d bytes\n", url.c_str(), (
int)filesize);
122 error_msg = std::string(curl_errbuf);
125 return (
long)filesize;
129 static unsigned write_cb(
char* in,
unsigned size,
unsigned nmemb,
void* data) {
130 auto downloader =
static_cast<Downloader*
>(data);
134 downloader->
on_chunk(in, size * nmemb);
135 return in == NULL ? 0 : size * nmemb;
Handle downloading of files from remote urls.
bool download(std::ostream *stream)
Download url into stream, return false on errors.
long get_filesize()
Try to get remote filesize, return 0 on failure.
std::string last_error()
Last Curl error message.
virtual void on_chunk(const char *buff, unsigned bytes)
Called when given bytes has been transferred from remote.
int last_errorcode()
Last error code, a CURLE return code.