adam@0: #include adam@0: #include adam@0: #include adam@0: adam@0: #include adam@0: adam@0: #include adam@0: adam@0: #define BUF_INIT 1024 adam@0: #define BUF_MAX 1073741824 adam@0: adam@0: uw_unit uw_FeedFfi_init(uw_context ctx) { adam@0: curl_global_init(CURL_GLOBAL_ALL); adam@0: adam@0: return uw_unit_v; adam@0: } adam@0: adam@0: static CURL *curl(uw_context ctx) { adam@0: CURL *r; adam@0: adam@0: if (!(r = uw_get_global(ctx, "curl"))) { adam@0: r = curl_easy_init(); adam@0: if (r) adam@0: uw_set_global(ctx, "curl", r, curl_easy_cleanup); adam@0: } adam@0: adam@0: return r; adam@0: } adam@0: adam@0: static void free_buffer(void *data) { adam@0: uw_buffer *buf = data; adam@0: adam@0: uw_buffer_free(buf); adam@0: free(buf); adam@0: } adam@0: adam@0: static uw_buffer *curl_buffer(uw_context ctx) { adam@0: uw_buffer *r; adam@0: adam@0: if (!(r = uw_get_global(ctx, "curl_buffer"))) { adam@0: r = malloc(sizeof(uw_buffer)); adam@0: if (r) { adam@0: uw_buffer_init(BUF_MAX, r, BUF_INIT); adam@0: uw_set_global(ctx, "curl_buffer", r, free_buffer); adam@0: } adam@0: } adam@0: adam@0: return r; adam@0: } adam@0: adam@0: static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { adam@0: uw_buffer *out = userp; adam@0: adam@0: uw_buffer_append(out, buffer, size * nmemb); adam@0: adam@0: return size * nmemb; adam@0: } adam@0: adam@0: uw_Basis_string uw_FeedFfi_fetch(uw_context ctx, uw_Basis_string url) { adam@0: CURL *c = curl(ctx); adam@0: uw_buffer *b = curl_buffer(ctx); adam@0: CURLcode code; adam@0: adam@0: uw_buffer_reset(b); adam@0: adam@0: curl_easy_setopt(c, CURLOPT_URL, url); adam@0: curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_data); adam@0: curl_easy_setopt(c, CURLOPT_WRITEDATA, b); adam@0: adam@0: code = curl_easy_perform(c); adam@0: adam@0: if (code) adam@0: uw_error(ctx, FATAL, "Error fetching URL %s", url); adam@0: else { adam@0: uw_buffer_append(b, "", 1); adam@0: return uw_strdup(ctx, b->start); adam@0: } adam@0: }