-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathnative.rs
64 lines (54 loc) · 1.77 KB
/
native.rs
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
use std::collections::BTreeMap;
use crate::{Request, Response};
/// Only available when compiling for native.
///
/// NOTE: Ok(…) is returned on network error.
/// Err is only for failure to use the fetch api.
pub fn fetch_blocking(request: &Request) -> crate::Result<Response> {
let mut req = ureq::request(&request.method, &request.url);
for header in &request.headers {
req = req.set(header.0, header.1);
}
let resp = if request.body.is_empty() {
req.call()
} else {
req.send_bytes(&request.body)
};
let (ok, resp) = match resp {
Ok(resp) => (true, resp),
Err(ureq::Error::Status(_, resp)) => (false, resp), // Still read the body on e.g. 404
Err(ureq::Error::Transport(error)) => return Err(error.to_string()),
};
let url = resp.get_url().to_owned();
let status = resp.status();
let status_text = resp.status_text().to_owned();
let mut headers = BTreeMap::new();
for key in &resp.headers_names() {
if let Some(value) = resp.header(key) {
// lowercase for easy lookup
headers.insert(key.to_ascii_lowercase(), value.to_owned());
}
}
let mut reader = resp.into_reader();
let mut bytes = vec![];
use std::io::Read;
reader
.read_to_end(&mut bytes)
.map_err(|err| err.to_string())?;
let response = Response {
url,
ok,
status,
status_text,
bytes,
headers,
};
Ok(response)
}
// ----------------------------------------------------------------------------
pub(crate) fn fetch(request: Request, on_done: Box<dyn FnOnce(crate::Result<Response>) + Send>) {
std::thread::spawn(move || {
let result = fetch_blocking(&request);
on_done(result)
});
}