Last active
August 21, 2016 10:48
-
-
Save zno5/0f86fa2b4725b78e8d39987be2946e22 to your computer and use it in GitHub Desktop.
Download a file with curl 7.43.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <string> | |
#include <vector> | |
#include <iostream> | |
#include <fstream> | |
#include <cassert> | |
#include <curl/curl.h> | |
/* | |
first of all, initialize curl lib. | |
in main function, call it. | |
curl_global_init(CURL_GLOBAL_ALL); | |
call clean up function on program termination | |
curl_global_cleanup(); | |
*/ | |
//////////////////////////////////////////////////////////////////////////////// | |
class CHttpDownload | |
{ | |
public: | |
CHttpDownload() : m_curl(nullptr) | |
{ | |
} | |
~CHttpDownload(); | |
bool Initialize(const std::string & url, const std::string fileName = ""); | |
bool Run(); | |
auto & GetData() const | |
{ | |
return m_buffer; | |
} | |
private: | |
static size_t WriteBufferCallback( | |
char * ptr, | |
size_t size, | |
size_t nmemb, | |
void * userdata | |
); | |
private: | |
CURL * m_curl; | |
std::vector<uint8_t> m_buffer; | |
std::string m_fileName; | |
std::ofstream m_file; | |
}; | |
//////////////////////////////////////////////////////////////////////////////// | |
CHttpDownload::~CHttpDownload() | |
{ | |
curl_easy_cleanup(m_curl); | |
if (m_file.is_open()) | |
{ | |
m_file.close(); | |
} | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
bool CHttpDownload::Initialize( | |
const std::string & url, | |
const std::string fileName | |
) | |
{ | |
m_fileName = fileName; | |
m_curl = curl_easy_init(); | |
if (!m_curl) | |
{ | |
return false; | |
} | |
if (curl_easy_setopt(m_curl, CURLOPT_URL, url.c_str()) != CURLE_OK) | |
{ | |
return false; | |
} | |
if (curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 0L) != CURLE_OK) | |
{ | |
return false; | |
} | |
if (curl_easy_setopt(m_curl, CURLOPT_TIMEOUT, 30) != CURLE_OK) | |
{ | |
return false; | |
} | |
if (curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, 30) != CURLE_OK) | |
{ | |
return false; | |
} | |
auto callback = &CHttpDownload::WriteBufferCallback; | |
if (curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, callback) != CURLE_OK) | |
{ | |
return false; | |
} | |
auto data = static_cast<void *>(this); | |
if (curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, data) != CURLE_OK) | |
{ | |
return false; | |
} | |
return true; | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
bool CHttpDownload::Run() | |
{ | |
assert(m_curl); | |
if (!m_curl) | |
{ | |
return false; | |
} | |
if (!m_fileName.empty()) | |
{ | |
m_file.open( | |
m_fileName, | |
std::ios::out | std::ios::trunc | std::ios::binary | |
); | |
} | |
auto code = curl_easy_perform(m_curl); | |
if (m_file.is_open()) | |
{ | |
m_file.close(); | |
} | |
if (CURLE_OK != code) | |
{ | |
std::cout << curl_easy_strerror(code) << std::endl; | |
return false; | |
} | |
return true; | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
size_t CHttpDownload::WriteBufferCallback( | |
char * ptr, | |
size_t size, | |
size_t nmemb, | |
void * userdata | |
) | |
{ | |
assert(1 == size); | |
auto bytes = size * nmemb; | |
auto http = static_cast<CHttpDownload *>(userdata); | |
if (http->m_file.is_open()) | |
{ | |
http->m_file.write(ptr, bytes); | |
return bytes; | |
} | |
auto & buffer = http->m_buffer; | |
auto bufferSize = buffer.size(); | |
buffer.resize(bufferSize + bytes); | |
std::copy(ptr, ptr + bytes, buffer.begin() + bufferSize); | |
return bytes; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment