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
|
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;
};
|