/* Copyright © 2015-2016 Gluzskiy Alexandr (sss) This file is part of Unknown Download Manager (UDM). UDM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. UDM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with UDM. If not, see . */ #include "curl_download.h" #include #include size_t curl_w_callback(char *ptr, size_t size, size_t nmemb, void *userdata) { curl_download *d = (curl_download*)userdata; if(d->get_cancel_state()) return -1; //cancel transfer //TODO: implement pause std::ofstream &of(d->get_ofile()); if(!of.is_open()) { //TODO: sanity check and path validation try{ of.open(d->get_download_path(), std::ios::out | std::ios::binary); } catch(...) //TODO: handle exception { } } size_t size_ = size * nmemb; if(size_) { if(of.is_open()) { try{ of.write(ptr, size_); } catch(...) //TODO: handle exception { } } else { return -1; //TODO: handle error } } return size_; } curl_download::curl_download(std::map params, core_api *a, module_base *m) { //for now we use single transfer connection for url //TODO: support multiple connections in parallel for multithreaded download easy_handle = curl_easy_init(); if(!easy_handle) ; //TODO: handle error api = a; module = m; curl_easy_setopt(easy_handle, CURLOPT_URL, params[0].c_str()); //Url as set in module_info curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, curl_w_callback); curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, this); if(!params[1].empty()) download_path = params[1]; else { download_path = api->get_core_settings()["default_download_directory"]; //extract name from url auto p1 = params[0].rfind("/"); if(p1 != std::string::npos) { download_path += "/"; download_path += params[0].substr(p1+1); } } //curl_easy_setopt(h, CURLOPT_DEFAULT_PROTOCOL, "http"); //require curl >= 7.45 } bool curl_download::start() { boost::thread(boost::bind(&curl_download::perform_internal, this)); state = core_events::download_running; return true; //TODO: } bool curl_download::stop() { cancel_transfer = true; state = core_events::download_stopped; return true; //TODO: } bool curl_download::delete_download() { cancel_transfer = true; curl_easy_cleanup(easy_handle); return true; //TODO: } void curl_download::perform_internal() { auto status = curl_easy_perform(easy_handle); if(status != CURLE_OK) state = core_events::download_error; else state = core_events::download_completed; ofile.close(); {//curl debug char *url; curl_easy_getinfo(easy_handle, CURLINFO_EFFECTIVE_URL, &url); BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__<<"\nCURLINFO_EFFECTIVE_URL:\t"< l; core_events::download_state_info i; i.download_id = id; i.state = state; l.push_back(i); api->download_state_changed(module, l); //TODO: save state } curl_download::~curl_download() { //curl_easy_cleanup(easy_handle); //this crashes for some reason }