pub struct ClientBuilder { /* private fields */ }Expand description
Builder for configuring a Client.
Implementations§
Source§impl ClientBuilder
impl ClientBuilder
Sourcepub fn redirect_policy(self, policy: RedirectPolicy) -> Self
pub fn redirect_policy(self, policy: RedirectPolicy) -> Self
Sets the default redirect policy used by Client::get, Client::head, and requests
that do not override redirect handling explicitly.
Sourcepub fn connection_policy(self, policy: ConnectionPolicy) -> Self
pub fn connection_policy(self, policy: ConnectionPolicy) -> Self
Configures whether sessions should close each connection after one request or reuse compatible connections for sequential and pipelined traffic.
Examples found in repository?
42fn bench_get(iterations: usize) -> Duration {
43 let response = b"HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nhello".to_vec();
44 let (base_url, handle) = spawn_persistent_server(iterations, response);
45
46 let client = Client::builder()
47 .connection_policy(ConnectionPolicy::Reuse)
48 .build();
49 let mut session = client.session();
50
51 let start = Instant::now();
52 for i in 0..iterations {
53 let req = Request::get(format!("{}/g{}", base_url, i)).expect("request");
54 let resp = session.execute(req).expect("execute");
55 assert_eq!(resp.body, b"hello");
56 }
57 let elapsed = start.elapsed();
58 handle.join().expect("join server");
59 elapsed
60}
61
62fn bench_head(iterations: usize) -> Duration {
63 let response = b"HTTP/1.1 200 OK\r\nContent-Length: 5\r\nX-Bench: 1\r\n\r\n".to_vec();
64 let (base_url, handle) = spawn_persistent_server(iterations, response);
65
66 let client = Client::builder()
67 .connection_policy(ConnectionPolicy::Reuse)
68 .build();
69 let mut session = client.session();
70
71 let start = Instant::now();
72 for i in 0..iterations {
73 let req = Request::head(format!("{}/h{}", base_url, i)).expect("request");
74 let resp = session.execute(req).expect("execute");
75 assert!(resp.body.is_empty());
76 }
77 let elapsed = start.elapsed();
78 handle.join().expect("join server");
79 elapsed
80}
81
82fn bench_pipeline(total_requests: usize, pipeline_depth: usize) -> Duration {
83 let response = b"HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nhello".to_vec();
84 let (base_url, handle) = spawn_persistent_server(total_requests, response);
85
86 let client = Client::builder()
87 .connection_policy(ConnectionPolicy::Reuse)
88 .build();
89 let mut session = client.session();
90
91 let start = Instant::now();
92 let mut sent = 0usize;
93 while sent < total_requests {
94 let batch_size = (total_requests - sent).min(pipeline_depth);
95 let mut batch = Vec::with_capacity(batch_size);
96 for index in 0..batch_size {
97 batch.push(Request::get(format!("{}/p{}", base_url, sent + index)).expect("request"));
98 }
99 let responses = session.execute_pipelined(&batch).expect("execute");
100 assert_eq!(responses.len(), batch_size);
101 for response in responses {
102 assert_eq!(response.body, b"hello");
103 }
104 sent += batch_size;
105 }
106 let elapsed = start.elapsed();
107 handle.join().expect("join server");
108 elapsed
109}More examples
14fn main() -> Result<(), Box<dyn Error>> {
15 let client = Client::builder()
16 .connection_policy(ConnectionPolicy::Reuse)
17 .build();
18 let mut session = client.session();
19
20 let first = session.execute(Request::get("http://example.com/")?)?;
21 let second = session.execute(Request::get("http://example.com/index.html")?)?;
22 let pipelined = session.execute_pipelined(&[
23 Request::get("http://example.com/")?,
24 Request::get("http://example.com/index.html")?,
25 ])?;
26
27 println!("This example demonstrates the Session API shape for reuse and pipelining.");
28 summarize("sequential #1", &first);
29 summarize("sequential #2", &second);
30 summarize("pipeline #1", &pipelined[0]);
31 summarize("pipeline #2", &pipelined[1]);
32
33 Ok(())
34}Sourcepub fn cache_mode(self, mode: CacheMode) -> Self
pub fn cache_mode(self, mode: CacheMode) -> Self
Enables or disables the built-in in-memory cache.
Examples found in repository?
5fn main() -> Result<(), Box<dyn Error>> {
6 let client = Client::builder().cache_mode(CacheMode::Memory).build();
7
8 let first = Request::get("http://example.com")?;
9 let mut second = Request::get("http://example.com")?;
10 second.add_header("Cache-Control", "max-age=0, min-fresh=1")?;
11
12 let first_response = client.execute(first)?;
13 let second_response = client.execute(second)?;
14
15 println!("memory cache example");
16 println!(
17 "first response: {} {}",
18 first_response.status_code, first_response.reason_phrase
19 );
20 println!(
21 "second response with request directives: {} {}",
22 second_response.status_code, second_response.reason_phrase
23 );
24 println!("This example demonstrates cache configuration and cache-control request headers.");
25
26 Ok(())
27}Sourcepub fn parser_strictness(self, strictness: ParserStrictness) -> Self
pub fn parser_strictness(self, strictness: ParserStrictness) -> Self
Configures how strictly response framing and line syntax are validated.
The default is ParserStrictness::Strict.
Sourcepub fn proxy(self, proxy: ProxyConfig) -> Self
pub fn proxy(self, proxy: ProxyConfig) -> Self
Routes requests through an explicit HTTP proxy.
Examples found in repository?
19fn main() -> Result<(), Box<dyn Error>> {
20 let Some(proxy_url) = env::var("NANO_GET_PROXY_URL").ok() else {
21 print_setup();
22 return Ok(());
23 };
24
25 let target_url = env_or_default("NANO_GET_PROXY_TARGET_URL", "http://example.com");
26 let proxy_user = env_or_default("NANO_GET_PROXY_AUTH_USER", "proxy-user");
27 let proxy_pass = env_or_default("NANO_GET_PROXY_AUTH_PASS", "proxy-pass");
28
29 let mut proxy = ProxyConfig::new(proxy_url)?;
30 proxy.add_header("X-Example-Proxy", "nano-get-demo")?;
31
32 let challenge_driven = Client::builder()
33 .proxy(proxy.clone())
34 .basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
35 .build()
36 .execute(Request::get(&target_url)?)?;
37
38 let preemptive = Client::builder()
39 .proxy(proxy.clone())
40 .preemptive_basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
41 .build()
42 .execute(Request::get(&target_url)?)?;
43
44 let mut manual = Request::get(&target_url)?;
45 manual.proxy_basic_auth(proxy_user, proxy_pass)?;
46 let manual_response = Client::builder().proxy(proxy).build().execute(manual)?;
47
48 println!("proxy-and-proxy-auth example");
49 println!("challenge-driven status: {}", challenge_driven.status_code);
50 println!("preemptive status: {}", preemptive.status_code);
51 println!(
52 "request-level override status: {}",
53 manual_response.status_code
54 );
55
56 Ok(())
57}Sourcepub fn auth_handler(self, handler: Arc<dyn AuthHandler + Send + Sync>) -> Self
pub fn auth_handler(self, handler: Arc<dyn AuthHandler + Send + Sync>) -> Self
Installs a generic origin-authentication handler for 401 challenges.
Examples found in repository?
41fn main() -> Result<(), Box<dyn Error>> {
42 let Some(url) = env::var("NANO_GET_CUSTOM_AUTH_URL").ok() else {
43 print_setup();
44 return Ok(());
45 };
46
47 let client = Client::builder()
48 .auth_handler(Arc::new(DemoTokenAuth))
49 .build();
50 let response = client.execute(Request::get(&url)?)?;
51
52 println!("custom-auth-handler example");
53 println!(
54 "status: {} {}",
55 response.status_code, response.reason_phrase
56 );
57 println!(
58 "parsed WWW-Authenticate challenges: {}",
59 response.www_authenticate_challenges()?.len()
60 );
61
62 Ok(())
63}Sourcepub fn proxy_auth_handler(
self,
handler: Arc<dyn AuthHandler + Send + Sync>,
) -> Self
pub fn proxy_auth_handler( self, handler: Arc<dyn AuthHandler + Send + Sync>, ) -> Self
Installs a generic proxy-authentication handler for 407 challenges.
Sourcepub fn basic_auth(
self,
username: impl Into<String>,
password: impl Into<String>,
) -> Self
pub fn basic_auth( self, username: impl Into<String>, password: impl Into<String>, ) -> Self
Enables challenge-driven HTTP Basic authentication for origin servers.
Examples found in repository?
18fn main() -> Result<(), Box<dyn Error>> {
19 let Some(url) = env::var("NANO_GET_BASIC_AUTH_URL").ok() else {
20 print_setup();
21 return Ok(());
22 };
23
24 let user = env_or_default("NANO_GET_BASIC_AUTH_USER", "demo-user");
25 let pass = env_or_default("NANO_GET_BASIC_AUTH_PASS", "demo-pass");
26
27 let challenge_driven = Client::builder()
28 .basic_auth(user.clone(), pass.clone())
29 .build()
30 .execute(Request::get(&url)?)?;
31
32 let preemptive = Client::builder()
33 .preemptive_basic_auth(user.clone(), pass.clone())
34 .build()
35 .execute(Request::get(&url)?)?;
36
37 let mut request = Request::get(&url)?;
38 request.basic_auth(user, pass)?;
39 let manual = request.execute()?;
40
41 println!("basic-auth example");
42 println!("challenge-driven status: {}", challenge_driven.status_code);
43 println!("preemptive status: {}", preemptive.status_code);
44 println!("request-level override status: {}", manual.status_code);
45
46 Ok(())
47}Sourcepub fn basic_proxy_auth(
self,
username: impl Into<String>,
password: impl Into<String>,
) -> Self
pub fn basic_proxy_auth( self, username: impl Into<String>, password: impl Into<String>, ) -> Self
Enables challenge-driven HTTP Basic authentication for the configured proxy.
Examples found in repository?
19fn main() -> Result<(), Box<dyn Error>> {
20 let Some(proxy_url) = env::var("NANO_GET_PROXY_URL").ok() else {
21 print_setup();
22 return Ok(());
23 };
24
25 let target_url = env_or_default("NANO_GET_PROXY_TARGET_URL", "http://example.com");
26 let proxy_user = env_or_default("NANO_GET_PROXY_AUTH_USER", "proxy-user");
27 let proxy_pass = env_or_default("NANO_GET_PROXY_AUTH_PASS", "proxy-pass");
28
29 let mut proxy = ProxyConfig::new(proxy_url)?;
30 proxy.add_header("X-Example-Proxy", "nano-get-demo")?;
31
32 let challenge_driven = Client::builder()
33 .proxy(proxy.clone())
34 .basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
35 .build()
36 .execute(Request::get(&target_url)?)?;
37
38 let preemptive = Client::builder()
39 .proxy(proxy.clone())
40 .preemptive_basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
41 .build()
42 .execute(Request::get(&target_url)?)?;
43
44 let mut manual = Request::get(&target_url)?;
45 manual.proxy_basic_auth(proxy_user, proxy_pass)?;
46 let manual_response = Client::builder().proxy(proxy).build().execute(manual)?;
47
48 println!("proxy-and-proxy-auth example");
49 println!("challenge-driven status: {}", challenge_driven.status_code);
50 println!("preemptive status: {}", preemptive.status_code);
51 println!(
52 "request-level override status: {}",
53 manual_response.status_code
54 );
55
56 Ok(())
57}Sourcepub fn preemptive_basic_auth(
self,
username: impl Into<String>,
password: impl Into<String>,
) -> Self
pub fn preemptive_basic_auth( self, username: impl Into<String>, password: impl Into<String>, ) -> Self
Sends HTTP Basic origin credentials on the first request and still handles later 401
challenges with the same credentials.
Examples found in repository?
18fn main() -> Result<(), Box<dyn Error>> {
19 let Some(url) = env::var("NANO_GET_BASIC_AUTH_URL").ok() else {
20 print_setup();
21 return Ok(());
22 };
23
24 let user = env_or_default("NANO_GET_BASIC_AUTH_USER", "demo-user");
25 let pass = env_or_default("NANO_GET_BASIC_AUTH_PASS", "demo-pass");
26
27 let challenge_driven = Client::builder()
28 .basic_auth(user.clone(), pass.clone())
29 .build()
30 .execute(Request::get(&url)?)?;
31
32 let preemptive = Client::builder()
33 .preemptive_basic_auth(user.clone(), pass.clone())
34 .build()
35 .execute(Request::get(&url)?)?;
36
37 let mut request = Request::get(&url)?;
38 request.basic_auth(user, pass)?;
39 let manual = request.execute()?;
40
41 println!("basic-auth example");
42 println!("challenge-driven status: {}", challenge_driven.status_code);
43 println!("preemptive status: {}", preemptive.status_code);
44 println!("request-level override status: {}", manual.status_code);
45
46 Ok(())
47}Sourcepub fn preemptive_basic_proxy_auth(
self,
username: impl Into<String>,
password: impl Into<String>,
) -> Self
pub fn preemptive_basic_proxy_auth( self, username: impl Into<String>, password: impl Into<String>, ) -> Self
Sends HTTP Basic proxy credentials on the first proxy request or CONNECT attempt and
still handles later 407 challenges with the same credentials.
Examples found in repository?
19fn main() -> Result<(), Box<dyn Error>> {
20 let Some(proxy_url) = env::var("NANO_GET_PROXY_URL").ok() else {
21 print_setup();
22 return Ok(());
23 };
24
25 let target_url = env_or_default("NANO_GET_PROXY_TARGET_URL", "http://example.com");
26 let proxy_user = env_or_default("NANO_GET_PROXY_AUTH_USER", "proxy-user");
27 let proxy_pass = env_or_default("NANO_GET_PROXY_AUTH_PASS", "proxy-pass");
28
29 let mut proxy = ProxyConfig::new(proxy_url)?;
30 proxy.add_header("X-Example-Proxy", "nano-get-demo")?;
31
32 let challenge_driven = Client::builder()
33 .proxy(proxy.clone())
34 .basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
35 .build()
36 .execute(Request::get(&target_url)?)?;
37
38 let preemptive = Client::builder()
39 .proxy(proxy.clone())
40 .preemptive_basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
41 .build()
42 .execute(Request::get(&target_url)?)?;
43
44 let mut manual = Request::get(&target_url)?;
45 manual.proxy_basic_auth(proxy_user, proxy_pass)?;
46 let manual_response = Client::builder().proxy(proxy).build().execute(manual)?;
47
48 println!("proxy-and-proxy-auth example");
49 println!("challenge-driven status: {}", challenge_driven.status_code);
50 println!("preemptive status: {}", preemptive.status_code);
51 println!(
52 "request-level override status: {}",
53 manual_response.status_code
54 );
55
56 Ok(())
57}Sourcepub fn build(self) -> Client
pub fn build(self) -> Client
Builds a Client from the current builder configuration.
Examples found in repository?
41fn main() -> Result<(), Box<dyn Error>> {
42 let Some(url) = env::var("NANO_GET_CUSTOM_AUTH_URL").ok() else {
43 print_setup();
44 return Ok(());
45 };
46
47 let client = Client::builder()
48 .auth_handler(Arc::new(DemoTokenAuth))
49 .build();
50 let response = client.execute(Request::get(&url)?)?;
51
52 println!("custom-auth-handler example");
53 println!(
54 "status: {} {}",
55 response.status_code, response.reason_phrase
56 );
57 println!(
58 "parsed WWW-Authenticate challenges: {}",
59 response.www_authenticate_challenges()?.len()
60 );
61
62 Ok(())
63}More examples
42fn bench_get(iterations: usize) -> Duration {
43 let response = b"HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nhello".to_vec();
44 let (base_url, handle) = spawn_persistent_server(iterations, response);
45
46 let client = Client::builder()
47 .connection_policy(ConnectionPolicy::Reuse)
48 .build();
49 let mut session = client.session();
50
51 let start = Instant::now();
52 for i in 0..iterations {
53 let req = Request::get(format!("{}/g{}", base_url, i)).expect("request");
54 let resp = session.execute(req).expect("execute");
55 assert_eq!(resp.body, b"hello");
56 }
57 let elapsed = start.elapsed();
58 handle.join().expect("join server");
59 elapsed
60}
61
62fn bench_head(iterations: usize) -> Duration {
63 let response = b"HTTP/1.1 200 OK\r\nContent-Length: 5\r\nX-Bench: 1\r\n\r\n".to_vec();
64 let (base_url, handle) = spawn_persistent_server(iterations, response);
65
66 let client = Client::builder()
67 .connection_policy(ConnectionPolicy::Reuse)
68 .build();
69 let mut session = client.session();
70
71 let start = Instant::now();
72 for i in 0..iterations {
73 let req = Request::head(format!("{}/h{}", base_url, i)).expect("request");
74 let resp = session.execute(req).expect("execute");
75 assert!(resp.body.is_empty());
76 }
77 let elapsed = start.elapsed();
78 handle.join().expect("join server");
79 elapsed
80}
81
82fn bench_pipeline(total_requests: usize, pipeline_depth: usize) -> Duration {
83 let response = b"HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nhello".to_vec();
84 let (base_url, handle) = spawn_persistent_server(total_requests, response);
85
86 let client = Client::builder()
87 .connection_policy(ConnectionPolicy::Reuse)
88 .build();
89 let mut session = client.session();
90
91 let start = Instant::now();
92 let mut sent = 0usize;
93 while sent < total_requests {
94 let batch_size = (total_requests - sent).min(pipeline_depth);
95 let mut batch = Vec::with_capacity(batch_size);
96 for index in 0..batch_size {
97 batch.push(Request::get(format!("{}/p{}", base_url, sent + index)).expect("request"));
98 }
99 let responses = session.execute_pipelined(&batch).expect("execute");
100 assert_eq!(responses.len(), batch_size);
101 for response in responses {
102 assert_eq!(response.body, b"hello");
103 }
104 sent += batch_size;
105 }
106 let elapsed = start.elapsed();
107 handle.join().expect("join server");
108 elapsed
109}14fn main() -> Result<(), Box<dyn Error>> {
15 let client = Client::builder()
16 .connection_policy(ConnectionPolicy::Reuse)
17 .build();
18 let mut session = client.session();
19
20 let first = session.execute(Request::get("http://example.com/")?)?;
21 let second = session.execute(Request::get("http://example.com/index.html")?)?;
22 let pipelined = session.execute_pipelined(&[
23 Request::get("http://example.com/")?,
24 Request::get("http://example.com/index.html")?,
25 ])?;
26
27 println!("This example demonstrates the Session API shape for reuse and pipelining.");
28 summarize("sequential #1", &first);
29 summarize("sequential #2", &second);
30 summarize("pipeline #1", &pipelined[0]);
31 summarize("pipeline #2", &pipelined[1]);
32
33 Ok(())
34}5fn main() -> Result<(), Box<dyn Error>> {
6 let client = Client::builder().cache_mode(CacheMode::Memory).build();
7
8 let first = Request::get("http://example.com")?;
9 let mut second = Request::get("http://example.com")?;
10 second.add_header("Cache-Control", "max-age=0, min-fresh=1")?;
11
12 let first_response = client.execute(first)?;
13 let second_response = client.execute(second)?;
14
15 println!("memory cache example");
16 println!(
17 "first response: {} {}",
18 first_response.status_code, first_response.reason_phrase
19 );
20 println!(
21 "second response with request directives: {} {}",
22 second_response.status_code, second_response.reason_phrase
23 );
24 println!("This example demonstrates cache configuration and cache-control request headers.");
25
26 Ok(())
27}18fn main() -> Result<(), Box<dyn Error>> {
19 let Some(url) = env::var("NANO_GET_BASIC_AUTH_URL").ok() else {
20 print_setup();
21 return Ok(());
22 };
23
24 let user = env_or_default("NANO_GET_BASIC_AUTH_USER", "demo-user");
25 let pass = env_or_default("NANO_GET_BASIC_AUTH_PASS", "demo-pass");
26
27 let challenge_driven = Client::builder()
28 .basic_auth(user.clone(), pass.clone())
29 .build()
30 .execute(Request::get(&url)?)?;
31
32 let preemptive = Client::builder()
33 .preemptive_basic_auth(user.clone(), pass.clone())
34 .build()
35 .execute(Request::get(&url)?)?;
36
37 let mut request = Request::get(&url)?;
38 request.basic_auth(user, pass)?;
39 let manual = request.execute()?;
40
41 println!("basic-auth example");
42 println!("challenge-driven status: {}", challenge_driven.status_code);
43 println!("preemptive status: {}", preemptive.status_code);
44 println!("request-level override status: {}", manual.status_code);
45
46 Ok(())
47}19fn main() -> Result<(), Box<dyn Error>> {
20 let Some(proxy_url) = env::var("NANO_GET_PROXY_URL").ok() else {
21 print_setup();
22 return Ok(());
23 };
24
25 let target_url = env_or_default("NANO_GET_PROXY_TARGET_URL", "http://example.com");
26 let proxy_user = env_or_default("NANO_GET_PROXY_AUTH_USER", "proxy-user");
27 let proxy_pass = env_or_default("NANO_GET_PROXY_AUTH_PASS", "proxy-pass");
28
29 let mut proxy = ProxyConfig::new(proxy_url)?;
30 proxy.add_header("X-Example-Proxy", "nano-get-demo")?;
31
32 let challenge_driven = Client::builder()
33 .proxy(proxy.clone())
34 .basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
35 .build()
36 .execute(Request::get(&target_url)?)?;
37
38 let preemptive = Client::builder()
39 .proxy(proxy.clone())
40 .preemptive_basic_proxy_auth(proxy_user.clone(), proxy_pass.clone())
41 .build()
42 .execute(Request::get(&target_url)?)?;
43
44 let mut manual = Request::get(&target_url)?;
45 manual.proxy_basic_auth(proxy_user, proxy_pass)?;
46 let manual_response = Client::builder().proxy(proxy).build().execute(manual)?;
47
48 println!("proxy-and-proxy-auth example");
49 println!("challenge-driven status: {}", challenge_driven.status_code);
50 println!("preemptive status: {}", preemptive.status_code);
51 println!(
52 "request-level override status: {}",
53 manual_response.status_code
54 );
55
56 Ok(())
57}Trait Implementations§
Source§impl Clone for ClientBuilder
impl Clone for ClientBuilder
Source§fn clone(&self) -> ClientBuilder
fn clone(&self) -> ClientBuilder
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more