mirror of
https://github.com/despawnerer/freearc
synced 2026-08-23 02:23:04 -04:00
134 lines
3.8 KiB
C++
134 lines
3.8 KiB
C++
#include "URL.h"
|
|
#include "Compression/Compression.h"
|
|
|
|
#define FREEARC_USER_AGENT "FreeArc/0.67"
|
|
|
|
// ****************************************************************************
|
|
// ** URL reading library
|
|
// ****************************************************************************
|
|
|
|
#ifdef FREEARC_NOURL
|
|
|
|
void url_setup_proxy(char *_proxy) {}
|
|
void url_setup_bypass_list(char *_bypass_list) {}
|
|
URL *url_open(char *_url) { return NULL; }
|
|
int url_readp(URL *url, int64 offset, char *buf, int size) { return -1; }
|
|
void url_close(URL *url) {}
|
|
|
|
#else
|
|
|
|
char *proxy = NULL;
|
|
void url_setup_proxy (char *_proxy)
|
|
{
|
|
proxy = strequ(_proxy,"--") ? NULL : strdup_msg (_proxy);
|
|
}
|
|
|
|
void url_setup_bypass_list (char *_bypass_list)
|
|
{
|
|
}
|
|
|
|
static size_t NoWriteCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
|
{
|
|
char **buf = (char **) data;
|
|
memcpy (*buf, ptr, size*nmemb);
|
|
*buf += size*nmemb;
|
|
return size*nmemb;
|
|
}
|
|
|
|
URL* url_open (char *_url)
|
|
{
|
|
static bool curl_inited = FALSE;
|
|
if (!curl_inited) curl_global_init(CURL_GLOBAL_ALL), curl_inited=TRUE;
|
|
|
|
URL *url = (URL*) malloc(sizeof(URL));
|
|
if (!url) return NULL;
|
|
url->url = strdup_msg (_url);
|
|
url->curpos = 0;
|
|
|
|
/* init the curl session */
|
|
url->curl_handle = curl_easy_init();
|
|
|
|
/* set proxy if it was specified by user */
|
|
if (proxy) curl_easy_setopt (url->curl_handle, CURLOPT_PROXY, proxy);
|
|
|
|
/* some servers don't like requests that are made without a user-agent
|
|
field, so we provide one */
|
|
curl_easy_setopt (url->curl_handle, CURLOPT_USERAGENT, FREEARC_USER_AGENT);
|
|
|
|
/* specify URL to get */
|
|
curl_easy_setopt (url->curl_handle, CURLOPT_URL, url->url);
|
|
|
|
// Get file size
|
|
curl_easy_setopt (url->curl_handle, CURLOPT_WRITEFUNCTION, NoWriteCallback);
|
|
CURLcode res = curl_easy_perform (url->curl_handle);
|
|
if (CURLE_OK!=res && CURLE_WRITE_ERROR!=res) {url_close(url); return NULL;}
|
|
|
|
long response;
|
|
curl_easy_getinfo (url->curl_handle, CURLINFO_RESPONSE_CODE, &response);
|
|
if (response!=200 && response!=301 && response!=302) {url_close(url); return NULL;}
|
|
|
|
double size;
|
|
res = curl_easy_getinfo (url->curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size);
|
|
if (CURLE_OK != res) {url_close(url); return NULL;}
|
|
url->size = (int64)size;
|
|
|
|
/* send all data read to this function */
|
|
curl_easy_setopt (url->curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
|
|
|
return url;
|
|
}
|
|
|
|
// Check existence of given url
|
|
int url_exists (char *_url)
|
|
{
|
|
URL *url = url_open(_url);
|
|
url_close(url);
|
|
return url!=NULL;
|
|
}
|
|
|
|
int url_readp (URL *url, int64 offset, char *buf, int size)
|
|
{
|
|
if (size==0) return 0;
|
|
if (!url) return -1;
|
|
|
|
/* specify byte range to get */
|
|
char Range[100];
|
|
sprintf (Range, "%.0lf-%.0lf", double(offset), double(offset+size-1));
|
|
curl_easy_setopt (url->curl_handle, CURLOPT_RANGE, Range);
|
|
|
|
/* we pass address of 'current write pointer' variable to the callback function */
|
|
char *ptr = buf;
|
|
curl_easy_setopt (url->curl_handle, CURLOPT_WRITEDATA, (void *)&ptr);
|
|
|
|
/* get it! */
|
|
curl_easy_perform (url->curl_handle);
|
|
|
|
return ptr-buf;
|
|
}
|
|
|
|
void url_reset (URL *url)
|
|
{
|
|
}
|
|
|
|
void url_close (URL *url)
|
|
{
|
|
if (!url) return;
|
|
/* cleanup curl stuff */
|
|
curl_easy_cleanup (url->curl_handle);
|
|
|
|
free (url->url);
|
|
free (url);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
int64 url_size (URL *url) {return url? url->size : 0;}
|
|
int64 url_pos (URL *url) {return url? url->curpos : 0;}
|
|
void url_seek (URL *url, int64 newpos) {if (url) url->curpos = newpos, url_reset(url);}
|
|
int url_read (URL *url, char *buf, int size) {return url? url_readp (url, url->curpos, buf, size) : -1;}
|