Skip to content

Commit b584036

Browse files
authored
Added an example for the "multi" api (#431)
1 parent 8de2e05 commit b584036

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,8 @@ required-features = ["ssl"]
7171
name = "aws_sigv4"
7272
path = "examples/aws_sigv4.rs"
7373
required-features = ["static-curl", "ssl"]
74+
75+
[[example]]
76+
name = "multi-dl"
77+
path = "examples/multi-dl.rs"
78+
required-features = ["ssl"]

examples/multi-dl.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use std::collections::HashMap;
2+
use std::time::Duration;
3+
4+
use anyhow::Result;
5+
6+
use curl::easy::{Easy2, Handler, WriteError};
7+
use curl::multi::{Easy2Handle, Multi};
8+
9+
const URLS: &[&str] = &[
10+
"https://www.microsoft.com",
11+
"https://www.google.com",
12+
"https://www.amazon.com",
13+
"https://www.apple.com",
14+
];
15+
16+
struct Collector(Vec<u8>);
17+
impl Handler for Collector {
18+
fn write(&mut self, data: &[u8]) -> Result<usize, WriteError> {
19+
self.0.extend_from_slice(data);
20+
Ok(data.len())
21+
}
22+
}
23+
24+
fn download(multi: &mut Multi, token: usize, url: &str) -> Result<Easy2Handle<Collector>> {
25+
let version = curl::Version::get();
26+
let mut request = Easy2::new(Collector(Vec::new()));
27+
request.url(&url)?;
28+
request.useragent(&format!("curl/{}", version.version()))?;
29+
30+
let mut handle = multi.add2(request)?;
31+
handle.set_token(token)?;
32+
Ok(handle)
33+
}
34+
35+
fn main() -> Result<()> {
36+
let mut multi = Multi::new();
37+
let mut handles = URLS
38+
.iter()
39+
.enumerate()
40+
.map(|(token, url)| Ok((token, download(&mut multi, token, url)?)))
41+
.collect::<Result<HashMap<_, _>>>()?;
42+
43+
let mut still_alive = true;
44+
while still_alive {
45+
// We still need to process the last messages when
46+
// `Multi::perform` returns "0".
47+
if multi.perform()? == 0 {
48+
still_alive = false;
49+
}
50+
51+
multi.messages(|message| {
52+
let token = message.token().expect("failed to get the token");
53+
let handle = handles
54+
.get_mut(&token)
55+
.expect("the download value should exist in the HashMap");
56+
57+
match message
58+
.result_for2(&handle)
59+
.expect("token mismatch with the `EasyHandle`")
60+
{
61+
Ok(()) => {
62+
let http_status = handle
63+
.response_code()
64+
.expect("HTTP request finished without status code");
65+
66+
println!(
67+
"R: Transfer succeeded (Status: {}) {} (Download length: {})",
68+
http_status,
69+
URLS[token],
70+
handle.get_ref().0.len()
71+
);
72+
}
73+
Err(error) => {
74+
println!("E: {} - <{}>", error, URLS[token]);
75+
}
76+
}
77+
});
78+
79+
if still_alive {
80+
// The sleeping time could be reduced to allow other processing.
81+
// For instance, a thread could check a condition signalling the
82+
// thread shutdown.
83+
multi.wait(&mut [], Duration::from_secs(60))?;
84+
}
85+
}
86+
87+
Ok(())
88+
}

0 commit comments

Comments
 (0)