-
Notifications
You must be signed in to change notification settings - Fork 2
/
fetch_curl.c
95 lines (76 loc) · 2.5 KB
/
fetch_curl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include "log.h"
#include "util.h"
#include "curl/curl.h"
typedef struct script_s {
char *buffer;
size_t size;
} script_s;
static size_t fetch_write_script(void *contents, size_t size, size_t nscriptb, void *userp) {
script_s *script = (script_s *)userp;
size_t new_size = size * nscriptb;
size_t total_size = script->size + new_size;
if (total_size > SCRIPT_MAX) {
LOG_ERROR("Script size exceeds maximum (%" PRId64 ")\n", (int64_t)total_size);
return 0;
}
char *ptr = realloc(script->buffer, total_size + 1);
if (!ptr) {
LOG_ERROR("Unable to allocate memory for %s (%" PRId32 ")\n", "script", errno);
return 0;
}
script->buffer = ptr;
memcpy(script->buffer + script->size, contents, new_size);
script->size += new_size;
script->buffer[script->size] = 0;
return new_size;
}
// Fetch proxy auto configuration using CURL
char *fetch_get(const char *url, int32_t *error) {
script_s script = {(char *)calloc(1, sizeof(char)), 0};
CURL *curl_handle = curl_easy_init();
if (!curl_handle) {
LOG_ERROR("Unable to initialize curl handle\n");
return NULL;
}
// Disable proxy when fetching PAC file
curl_easy_setopt(curl_handle, CURLOPT_PROXY, "");
// Add Accept header with PAC mime-type
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/x-ns-proxy-autoconfig");
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
// Setup url to fetch
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
// Write to memory buffer callback
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, fetch_write_script);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&script);
CURLcode res = curl_easy_perform(curl_handle);
if (res != CURLE_OK) {
free(script.buffer);
script.buffer = NULL;
}
if (error)
*error = res;
curl_slist_free_all(headers);
curl_easy_cleanup(curl_handle);
return script.buffer;
}
bool fetch_global_init(void) {
CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
if (res != CURLE_OK) {
LOG_ERROR("Unable to initialize curl\n");
return false;
}
return true;
}
bool fetch_global_cleanup(void) {
curl_global_cleanup();
return true;
}