1#include "DownloadQueue.hpp"
9#define MAX_PARALLEL_DOWNLOADS 4
12#define SOCU_ALIGN 0x1000
13#define SOCU_BUFFERSIZE 0x100000
16#define SO_TCPSACK 0x00200
20#define SO_WINSCALE 0x00400
24#define SO_RCVBUF 0x01002
30int sockopt_callback_chesto(
void *clientp, curl_socket_t curlfd, curlsocktype purpose)
32 int winscale = 1, rcvbuf = 0x20000, tcpsack = 1;
34 setsockopt(curlfd, SOL_SOCKET, SO_WINSCALE, &winscale,
sizeof(
int));
35 setsockopt(curlfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
sizeof(
int));
36 setsockopt(curlfd, SOL_SOCKET, SO_TCPSACK, &tcpsack,
sizeof(
int));
44void DownloadQueue::init()
49void DownloadQueue::quit()
54static size_t WriteCallback(
char *data,
size_t n,
size_t l,
void *userp)
57 download->buffer.append(data, n * l);
61DownloadQueue::DownloadQueue()
64 cm = curl_multi_init();
65 curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, MAX_PARALLEL_DOWNLOADS);
69DownloadQueue::~DownloadQueue()
72 curl_multi_cleanup(cm);
80 download->status = DownloadStatus::QUEUED;
81 queue.push_back(download);
87 if (download->status == DownloadStatus::DOWNLOADING)
88 transferFinish(download);
89 else if (download->status == DownloadStatus::QUEUED && queue.size() > 0)
90 queue.remove(download);
94void DownloadQueue::setPlatformCurlFlags(CURL* c)
97 curl_easy_setopt(c, CURLOPT_CAINFO, RAMFS
"res/cacert.pem");
99 curl_easy_setopt(c, CURLOPT_SOCKOPTFUNCTION, sockopt_callback_chesto);
107 download->eh = curl_easy_init();
109 setPlatformCurlFlags(download->eh);
111 curl_easy_setopt(download->eh, CURLOPT_URL, download->url.c_str());
112 curl_easy_setopt(download->eh, CURLOPT_WRITEFUNCTION, WriteCallback);
113 curl_easy_setopt(download->eh, CURLOPT_WRITEDATA, download);
114 curl_easy_setopt(download->eh, CURLOPT_PRIVATE, download);
116 curl_easy_setopt(download->eh, CURLOPT_FOLLOWLOCATION, 1L);
118 curl_multi_add_handle(cm, download->eh);
128 curl_multi_remove_handle(cm, download->eh);
130 curl_easy_cleanup(download->eh);
136void DownloadQueue::startTransfersFromQueue()
139 while ((transfers < MAX_PARALLEL_DOWNLOADS) && (queue.size() > 0))
146 download->status = DownloadStatus::DOWNLOADING;
147 transferStart(download);
162 curl_multi_perform(cm, &still_alive);
165 while(msg = curl_multi_info_read(cm, &msgs_left))
167 long response_code = 404;
169 if (msg->msg != CURLMSG_DONE)
172 curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &download);
173 curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code);
175 transferFinish(download);
176 startTransfersFromQueue();
178 if (response_code == 200)
179 download->status = DownloadStatus::COMPLETE;
181 download->status = DownloadStatus::FAILED;
183 download->cb(download);
186 startTransfersFromQueue();
188 return ((still_alive) || (msgs_left > 0) || (queue.size() > 0));
int process()
process finished and queued downloads
void downloadAdd(DownloadOperation *download)
add a new download operation
void downloadCancel(DownloadOperation *download)
cancel a download operation