1 /* *
2 * Blocking easy interfaces to libcurl for R.
3 * Example: https://curl.se/libcurl/c/getinmemory.html
4 */
5
6 #include "curl-common.h"
7
R_curl_fetch_memory(SEXP url,SEXP ptr,SEXP nonblocking)8 SEXP R_curl_fetch_memory(SEXP url, SEXP ptr, SEXP nonblocking){
9 if (!isString(url) || length(url) != 1)
10 error("Argument 'url' must be string.");
11
12 /* get the handle */
13 CURL *handle = get_handle(ptr);
14
15 /* update the url */
16 curl_easy_setopt(handle, CURLOPT_URL, CHAR(STRING_ELT(url, 0)));
17
18 /* reset the response header buffer */
19 reset_resheaders(get_ref(ptr));
20 reset_errbuf(get_ref(ptr));
21
22 /* buffer body */
23 memory body = {NULL, 0};
24 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, append_buffer);
25 curl_easy_setopt(handle, CURLOPT_WRITEDATA, &body);
26
27 /* perform blocking request */
28 CURLcode status = asLogical(nonblocking) ?
29 curl_perform_with_interrupt(handle) : curl_easy_perform(handle);
30
31 /* Reset for reuse */
32 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL);
33 curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL);
34
35 /* check for errors */
36 if (status != CURLE_OK) {
37 free(body.buf);
38 assert_status(status, get_ref(ptr));
39 }
40
41 /* create output */
42 SEXP out = PROTECT(allocVector(RAWSXP, body.size));
43
44 /* copy only if there is actual content */
45 if(body.size)
46 memcpy(RAW(out), body.buf, body.size);
47
48 /* cleanup and return */
49 UNPROTECT(1);
50 free(body.buf);
51 return out;
52 }
53
R_curl_fetch_disk(SEXP url,SEXP ptr,SEXP path,SEXP mode,SEXP nonblocking)54 SEXP R_curl_fetch_disk(SEXP url, SEXP ptr, SEXP path, SEXP mode, SEXP nonblocking){
55 if (!isString(url) || length(url) != 1)
56 error("Argument 'url' must be string.");
57 if (!isString(path) || length(path) != 1)
58 error("`path` must be string.");
59
60 /* get the handle */
61 CURL *handle = get_handle(ptr);
62
63 /* update the url */
64 curl_easy_setopt(handle, CURLOPT_URL, CHAR(STRING_ELT(url, 0)));
65
66 /* reset the response header buffer */
67 reset_resheaders(get_ref(ptr));
68 reset_errbuf(get_ref(ptr));
69
70 /* open file */
71 FILE *dest = fopen(CHAR(asChar(path)), CHAR(asChar(mode)));
72 if(!dest)
73 error("Failed to open file %s.", CHAR(asChar(path)));
74 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, push_disk);
75 curl_easy_setopt(handle, CURLOPT_WRITEDATA, dest);
76
77 /* perform blocking request */
78 CURLcode status = asLogical(nonblocking) ?
79 curl_perform_with_interrupt(handle): curl_easy_perform(handle);
80
81 /* cleanup */
82 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL);
83 curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL);
84 fclose(dest);
85
86 /* check for errors */
87 assert_status(status, get_ref(ptr));
88
89 /* return the file path */
90 return path;
91 }
92