custom_auth_handler/
main.rs1use std::env;
2use std::error::Error;
3use std::sync::Arc;
4
5use nano_get::{
6 AuthDecision, AuthHandler, AuthTarget, Challenge, Client, Header, Request, Response, Url,
7};
8
9struct DemoTokenAuth;
10
11impl AuthHandler for DemoTokenAuth {
12 fn respond(
13 &self,
14 _target: AuthTarget,
15 _url: &Url,
16 challenges: &[Challenge],
17 _request: &Request,
18 _response: &Response,
19 ) -> Result<AuthDecision, nano_get::NanoGetError> {
20 let supports_token = challenges
21 .iter()
22 .any(|challenge| challenge.scheme.eq_ignore_ascii_case("token"));
23
24 if supports_token {
25 return Ok(AuthDecision::UseHeaders(vec![Header::new(
26 "Authorization",
27 "Token example-secret",
28 )?]));
29 }
30
31 Ok(AuthDecision::NoMatch)
32 }
33}
34
35fn print_setup() {
36 println!("The custom-auth-handler example needs a real protected endpoint.");
37 println!("Set NANO_GET_CUSTOM_AUTH_URL to a URL that challenges with a custom scheme.");
38 println!("The example handler looks for a scheme named `Token`.");
39}
40
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}