use types::c; use fmt; use os; use memio; use strings; use io; use internal::curl::ccurl; export type curlerror = !(setopterr | performerr | getinfoerr); export type setopterr = !int; export type performerr = !int; export type getinfoerr = !int; // A HTTP response export type response = struct { // Body data: memio::stream, // HTTP status status: i64, // Size of the body sz: i64, }; // Creates a response and returns it. Caller must call [[closeresponse]] to // close the underlying stream. export fn newresponse() response = { return response { data = memio::dynamic(), status = 0, sz = 0, }; }; // Closes the stream associated to the response created by [[newresponse]]. export fn closeresponse(resp: response) (void | io::error) = { io::close(&resp.data)?; }; fn cb(ptr: *c::char, sz: c::ssize, nmemb: c::ssize, userdata: *opaque) c::ssize = { let s = c::tostr(ptr)!; let resp = userdata: *response; let realsize = nmemb * sz; let b = strings::toutf8(s); memio::concat(&resp.data, strings::fromutf8_unsafe(b[..realsize]))!; resp.sz += sz * nmemb; return sz * nmemb; }; // Makes a HTTP request to the given url and fills resp with the body, HTTP // status and body size. export fn get(url: const str, resp: *response) (void | curlerror) = { let c = ccurl::curl_easy_init(); defer ccurl::curl_easy_cleanup(c); let c_url = c::fromstr(url); defer free(c_url); let res = ccurl::curl_easy_setopt(c, ccurl::CURLOPT_URL, c_url); if (res != 0) { return res: setopterr; }; res = ccurl::curl_easy_setopt_writefunction(c, ccurl::CURLOPT_WRITEFUNCTION, &cb); res = ccurl::curl_easy_setopt_writedata(c, ccurl::CURLOPT_WRITEDATA, resp); res = ccurl::curl_easy_perform(c); if (res != 0) { return res: performerr; }; let rc: c::long = 0; res = ccurl::curl_easy_getinfo(c, ccurl::CURLINFO_RESPONSE_CODE, &rc); if (res != 0) { return res: getinfoerr; }; resp.status = rc; };