mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-20 15:08:40 +00:00
171 lines
5.2 KiB
C++
Executable File
171 lines
5.2 KiB
C++
Executable File
/**
|
|
* Karaka
|
|
*
|
|
* @package Utils
|
|
* @copyright Dennis Eichhorn
|
|
* @license OMS License 1.0
|
|
* @version 1.0.0
|
|
* @link https://jingga.app
|
|
*/
|
|
#ifndef UTILS_WEB_UTILS_H
|
|
#define UTILS_WEB_UTILS_H
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <curl/curl.h>
|
|
|
|
#include "FileUtils.h"
|
|
|
|
namespace Utils
|
|
{
|
|
namespace WebUtils
|
|
{
|
|
static bool CURL_SETUP = false;
|
|
|
|
inline
|
|
void setup()
|
|
{
|
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
Utils::WebUtils::CURL_SETUP = true;
|
|
}
|
|
|
|
inline
|
|
void clean()
|
|
{
|
|
curl_global_cleanup();
|
|
Utils::WebUtils::CURL_SETUP = false;
|
|
}
|
|
|
|
int write_download_data (void *ptr, size_t size, size_t nmeb, void *stream)
|
|
{
|
|
Utils::FileUtils::file_body *out = (Utils::FileUtils::file_body *) stream;
|
|
size_t outSize = size * nmeb;
|
|
|
|
if (out->size == 0) {
|
|
// first time this function is called for a specific resource
|
|
out->content = (char *) malloc((outSize + 1) * sizeof(char));
|
|
if (!out->content) {
|
|
fprintf(stderr, "CRITICAL: malloc failed");
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (out->content) {
|
|
memcpy(out->content, ptr, outSize * sizeof(char));
|
|
|
|
out->size = (int) outSize;
|
|
out->content[out->size] = 0;
|
|
}
|
|
} else {
|
|
// the max buffer (16384 = 16k) is exceeded, then this is called again and needs to get extended
|
|
char *temp = (char *) malloc((outSize + out->size + 1) * sizeof(char));
|
|
|
|
memcpy(temp, out->content, out->size * sizeof(char));
|
|
memcpy(temp + out->size * sizeof(char), ptr, outSize * sizeof(char));
|
|
|
|
free(out->content);
|
|
|
|
out->content = temp;
|
|
out->size += outSize;
|
|
out->content[out->size] = 0;
|
|
}
|
|
|
|
return out->size;
|
|
}
|
|
|
|
inline
|
|
Utils::FileUtils::file_body download (char *url)
|
|
{
|
|
Utils::FileUtils::file_body page = {0};
|
|
|
|
if (!Utils::WebUtils::CURL_SETUP) {
|
|
Utils::WebUtils::setup();
|
|
}
|
|
|
|
CURL *h = curl_easy_init();
|
|
curl_easy_setopt(h, CURLOPT_URL, url);
|
|
curl_easy_setopt(h, CURLOPT_PRIVATE, url);
|
|
curl_easy_setopt(h, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
curl_easy_setopt(h, CURLOPT_SSL_VERIFYHOST, 0L);
|
|
curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, write_download_data);
|
|
curl_easy_setopt(h, CURLOPT_WRITEDATA, &page);
|
|
curl_easy_perform(h);
|
|
curl_easy_cleanup(h);
|
|
|
|
return page;
|
|
}
|
|
|
|
inline
|
|
void add_transfer(CURLM *cm, char *url, Utils::FileUtils::file_body *page, int *left)
|
|
{
|
|
CURL *h = curl_easy_init();
|
|
curl_easy_setopt(h, CURLOPT_URL, url);
|
|
curl_easy_setopt(h, CURLOPT_PRIVATE, url);
|
|
curl_easy_setopt(h, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
curl_easy_setopt(h, CURLOPT_SSL_VERIFYHOST, 0L);
|
|
curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, write_download_data);
|
|
curl_easy_setopt(h, CURLOPT_WRITEDATA, page);
|
|
|
|
curl_multi_add_handle(cm, h);
|
|
|
|
++(*left);
|
|
}
|
|
|
|
Utils::FileUtils::file_body *multi_download (char **urls, int count, int max_parrallel)
|
|
{
|
|
Utils::FileUtils::file_body *pages = (Utils::FileUtils::file_body *) malloc(count * sizeof(Utils::FileUtils::file_body));
|
|
|
|
if (!Utils::WebUtils::CURL_SETUP) {
|
|
Utils::WebUtils::setup();
|
|
}
|
|
|
|
CURLM *cm = curl_multi_init();
|
|
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, max_parrallel);
|
|
|
|
int downloads;
|
|
int left = 0;
|
|
|
|
for(downloads = 0; downloads < max_parrallel && downloads < count; ++downloads) {
|
|
Utils::WebUtils::add_transfer(cm, urls[downloads], &pages[downloads], &left);
|
|
}
|
|
|
|
CURLMsg *msg;
|
|
int msgs_left = -1;
|
|
|
|
do {
|
|
int alive = 1;
|
|
curl_multi_perform(cm, &alive);
|
|
|
|
while((msg = curl_multi_info_read(cm, &msgs_left))) {
|
|
if(msg->msg == CURLMSG_DONE) {
|
|
char *url;
|
|
CURL *e = msg->easy_handle;
|
|
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
|
|
curl_multi_remove_handle(cm, e);
|
|
curl_easy_cleanup(e);
|
|
--left;
|
|
} else {
|
|
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
|
|
}
|
|
|
|
if(downloads < count) {
|
|
++downloads;
|
|
add_transfer(cm, urls[downloads], &pages[downloads], &left);
|
|
}
|
|
}
|
|
|
|
if(left > 0) {
|
|
curl_multi_wait(cm, NULL, 0, 1000, NULL);
|
|
}
|
|
|
|
} while(left > 0);
|
|
|
|
curl_multi_cleanup(cm);
|
|
|
|
return pages;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |