11 #include <sys/errno.h>
14 #include <CoreFoundation/CoreFoundation.h>
16 #include <curl/curl.h>
23 "title" :
"VuoUrlFetch",
39 __attribute__((constructor))
static void VuoUrl_init(
void)
41 curl_global_init(CURL_GLOBAL_DEFAULT);
59 size_t realsize = size * nmemb;
62 mem->memory = (
char *)realloc(mem->memory, mem->size + realsize + 1);
63 if(mem->memory == NULL)
65 VUserLog(
"Error: realloc() returned NULL (out of memory?).");
69 memcpy(&(mem->memory[mem->size]), contents, realsize);
70 mem->size += realsize;
71 mem->memory[mem->size] = 0;
81 CFStringRef cf = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, (
const UInt8 *)buffer->memory, strlen(buffer->memory), sourceEncoding,
true, kCFAllocatorMalloc);
86 VUserLog(
"Error: Couldn't convert response from %s to UTF-8.", sourceEncodingName);
90 CFIndex maxBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cf), kCFStringEncodingUTF8) + 1;
91 char *outBuffer = calloc(1, maxBytes);
92 CFStringGetCString(cf, outBuffer, maxBytes, kCFStringEncodingUTF8);
95 buffer->memory = outBuffer;
96 buffer->size = strlen(outBuffer);
102 VUserLog(
"Converted response from %s to UTF-8.", sourceEncodingName);
117 bool VuoUrl_fetch(
const char *url,
void **data,
unsigned int *dataLength)
122 if (strncmp(url,
"data:", 5) == 0)
127 const char *urlData = url + 5;
130 urlData = strchr(urlData,
',');
138 bool isBase64 = (urlData - url >= 5 + 7 + 1)
139 && (strncmp(urlData - 7 - 1,
";base64", 7) == 0);
146 long long outputLength;
148 *dataLength = outputLength;
152 *data = strdup(decoded);
153 *dataLength = strlen(decoded);
167 FILE *fp = fopen(posixPath,
"rb");
170 VUserLog(
"Error: Could not read file \"%s\"", posixPath);
175 fseek(fp, 0, SEEK_END);
176 *dataLength = ftell(fp);
178 *data = (
char *)malloc(*dataLength + 1);
179 if (fread(*data, 1, *dataLength, fp) != *dataLength)
182 VUserLog(
"Error: Could not read all the data from file \"%s\": %s", posixPath, strerror(errno));
185 ((
char *)*data)[*dataLength] = 0;
194 curl = curl_easy_init();
197 VUserLog(
"Error: cURL initialization failed.");
200 VuoDefer(^{ curl_easy_cleanup(curl); });
202 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
205 curl_easy_setopt(curl, CURLOPT_URL, resolvedUrl);
207 curl_easy_setopt(curl, CURLOPT_USERAGENT,
"Vuo/" VUO_VERSION_STRING
" (https://vuo.org/)");
209 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
210 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
213 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void *)&buffer);
215 res = curl_easy_perform(curl);
218 VUserLog(
"Error: cURL request failed: %s (%d)", curl_easy_strerror(res), res);
222 VDebugLog(
"Received %zu bytes.", buffer.size);
223 if (buffer.size == 0 || !buffer.memory)
227 char *contentType = NULL;
228 res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType);
229 if (res == CURLE_OK && contentType)
232 VDebugLog(
"Content-Type: %s", contentType);
235 if (strcasecmp(contentType,
"text/html; charset=utf-8") == 0
236 || strcasecmp(contentType,
"text/html; charset=us-ascii") == 0)
240 else if (strcasecmp(contentType,
"text/html; charset=iso-8859-1") == 0
241 || strcasecmp(contentType,
"text/html") == 0)
247 *data = buffer.memory;
248 *dataLength = buffer.size;