src/client/http_client.rs: new prefix options
This commit is contained in:
		@ -166,6 +166,7 @@ fn complete_repository(_arg: &str, _param: &HashMap<String, String>) -> Vec<Stri
 | 
				
			|||||||
fn connect(server: &str, userid: &str) -> Result<HttpClient, Error> {
 | 
					fn connect(server: &str, userid: &str) -> Result<HttpClient, Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let options = HttpClientOptions::new()
 | 
					    let options = HttpClientOptions::new()
 | 
				
			||||||
 | 
					        .prefix(Some("proxmox-backup".to_string()))
 | 
				
			||||||
        .interactive(true)
 | 
					        .interactive(true)
 | 
				
			||||||
        .fingerprint_cache(true)
 | 
					        .fingerprint_cache(true)
 | 
				
			||||||
        .ticket_cache(true);
 | 
					        .ticket_cache(true);
 | 
				
			||||||
@ -536,7 +537,7 @@ fn api_logout(param: Value) -> Result<Value, Error> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let repo = extract_repository_from_value(¶m)?;
 | 
					    let repo = extract_repository_from_value(¶m)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    delete_ticket_info(repo.host(), repo.user())?;
 | 
					    delete_ticket_info("proxmox-backup", repo.host(), repo.user())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(Value::Null)
 | 
					    Ok(Value::Null)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1474,6 +1475,7 @@ async fn status(param: Value) -> Result<Value, Error> {
 | 
				
			|||||||
async fn try_get(repo: &BackupRepository, url: &str) -> Value {
 | 
					async fn try_get(repo: &BackupRepository, url: &str) -> Value {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let options = HttpClientOptions::new()
 | 
					    let options = HttpClientOptions::new()
 | 
				
			||||||
 | 
					        .prefix(Some("proxmox-backup".to_string()))
 | 
				
			||||||
        .interactive(false)
 | 
					        .interactive(false)
 | 
				
			||||||
        .fingerprint_cache(true)
 | 
					        .fingerprint_cache(true)
 | 
				
			||||||
        .ticket_cache(true);
 | 
					        .ticket_cache(true);
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,7 @@ fn connect() -> Result<HttpClient, Error> {
 | 
				
			|||||||
    let uid = nix::unistd::Uid::current();
 | 
					    let uid = nix::unistd::Uid::current();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut options = HttpClientOptions::new()
 | 
					    let mut options = HttpClientOptions::new()
 | 
				
			||||||
 | 
					        .prefix(Some("proxmox-backup".to_string()))
 | 
				
			||||||
        .verify_cert(false); // not required for connection to localhost
 | 
					        .verify_cert(false); // not required for connection to localhost
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let client = if uid.is_root()  {
 | 
					    let client = if uid.is_root()  {
 | 
				
			||||||
 | 
				
			|||||||
@ -31,6 +31,7 @@ pub struct AuthInfo {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct HttpClientOptions {
 | 
					pub struct HttpClientOptions {
 | 
				
			||||||
 | 
					    prefix: Option<String>,
 | 
				
			||||||
    password: Option<String>,
 | 
					    password: Option<String>,
 | 
				
			||||||
    fingerprint: Option<String>,
 | 
					    fingerprint: Option<String>,
 | 
				
			||||||
    interactive: bool,
 | 
					    interactive: bool,
 | 
				
			||||||
@ -43,6 +44,7 @@ impl HttpClientOptions {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub fn new() -> Self {
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
 | 
					            prefix: None,
 | 
				
			||||||
            password: None,
 | 
					            password: None,
 | 
				
			||||||
            fingerprint: None,
 | 
					            fingerprint: None,
 | 
				
			||||||
            interactive: false,
 | 
					            interactive: false,
 | 
				
			||||||
@ -52,6 +54,11 @@ impl HttpClientOptions {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn prefix(mut self, prefix: Option<String>) -> Self {
 | 
				
			||||||
 | 
					        self.prefix = prefix;
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn password(mut self, password: Option<String>) -> Self {
 | 
					    pub fn password(mut self, password: Option<String>) -> Self {
 | 
				
			||||||
        self.password = password;
 | 
					        self.password = password;
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
@ -93,9 +100,9 @@ pub struct HttpClient {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Delete stored ticket data (logout)
 | 
					/// Delete stored ticket data (logout)
 | 
				
			||||||
pub fn delete_ticket_info(server: &str, username: &str) -> Result<(), Error> {
 | 
					pub fn delete_ticket_info(prefix: &str, server: &str, username: &str) -> Result<(), Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let base = BaseDirectories::with_prefix("proxmox-backup")?;
 | 
					    let base = BaseDirectories::with_prefix(prefix)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // usually /run/user/<uid>/...
 | 
					    // usually /run/user/<uid>/...
 | 
				
			||||||
    let path = base.place_runtime_file("tickets")?;
 | 
					    let path = base.place_runtime_file("tickets")?;
 | 
				
			||||||
@ -113,11 +120,11 @@ pub fn delete_ticket_info(server: &str, username: &str) -> Result<(), Error> {
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn store_fingerprint(server: &str, fingerprint: &str) -> Result<(), Error> {
 | 
					fn store_fingerprint(prefix: &str, server: &str, fingerprint: &str) -> Result<(), Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let base = BaseDirectories::with_prefix("proxmox-backup")?;
 | 
					    let base = BaseDirectories::with_prefix(prefix)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // usually ~/.config/proxmox-backup/fingerprints
 | 
					    // usually ~/.config/<prefix>/fingerprints
 | 
				
			||||||
    let path = base.place_config_file("fingerprints")?;
 | 
					    let path = base.place_config_file("fingerprints")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let raw = match std::fs::read_to_string(&path) {
 | 
					    let raw = match std::fs::read_to_string(&path) {
 | 
				
			||||||
@ -155,11 +162,11 @@ fn store_fingerprint(server: &str, fingerprint: &str) -> Result<(), Error> {
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn load_fingerprint(server: &str) -> Option<String> {
 | 
					fn load_fingerprint(prefix: &str, server: &str) -> Option<String> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let base = BaseDirectories::with_prefix("proxmox-backup").ok()?;
 | 
					    let base = BaseDirectories::with_prefix(prefix).ok()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // usually ~/.config/proxmox-backup/fingerprints
 | 
					    // usually ~/.config/<prefix>/fingerprints
 | 
				
			||||||
    let path = base.place_config_file("fingerprints").ok()?;
 | 
					    let path = base.place_config_file("fingerprints").ok()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let raw = std::fs::read_to_string(&path).ok()?;
 | 
					    let raw = std::fs::read_to_string(&path).ok()?;
 | 
				
			||||||
@ -176,9 +183,9 @@ fn load_fingerprint(server: &str) -> Option<String> {
 | 
				
			|||||||
    None
 | 
					    None
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn store_ticket_info(server: &str, username: &str, ticket: &str, token: &str) -> Result<(), Error> {
 | 
					fn store_ticket_info(prefix: &str, server: &str, username: &str, ticket: &str, token: &str) -> Result<(), Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let base = BaseDirectories::with_prefix("proxmox-backup")?;
 | 
					    let base = BaseDirectories::with_prefix(prefix)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // usually /run/user/<uid>/...
 | 
					    // usually /run/user/<uid>/...
 | 
				
			||||||
    let path = base.place_runtime_file("tickets")?;
 | 
					    let path = base.place_runtime_file("tickets")?;
 | 
				
			||||||
@ -212,8 +219,8 @@ fn store_ticket_info(server: &str, username: &str, ticket: &str, token: &str) ->
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn load_ticket_info(server: &str, username: &str) -> Option<(String, String)> {
 | 
					fn load_ticket_info(prefix: &str, server: &str, username: &str) -> Option<(String, String)> {
 | 
				
			||||||
    let base = BaseDirectories::with_prefix("proxmox-backup").ok()?;
 | 
					    let base = BaseDirectories::with_prefix(prefix).ok()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // usually /run/user/<uid>/...
 | 
					    // usually /run/user/<uid>/...
 | 
				
			||||||
    let path = base.place_runtime_file("tickets").ok()?;
 | 
					    let path = base.place_runtime_file("tickets").ok()?;
 | 
				
			||||||
@ -240,27 +247,58 @@ impl HttpClient {
 | 
				
			|||||||
        let verified_fingerprint = Arc::new(Mutex::new(None));
 | 
					        let verified_fingerprint = Arc::new(Mutex::new(None));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut fingerprint = options.fingerprint.take();
 | 
					        let mut fingerprint = options.fingerprint.take();
 | 
				
			||||||
        if options.fingerprint_cache && fingerprint.is_none() {
 | 
					        if options.fingerprint_cache && fingerprint.is_none() && options.prefix.is_some() {
 | 
				
			||||||
            fingerprint = load_fingerprint(server);
 | 
					            fingerprint = load_fingerprint(options.prefix.as_ref().unwrap(), server);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let client = Self::build_client(
 | 
					        let mut ssl_connector_builder = SslConnector::builder(SslMethod::tls()).unwrap();
 | 
				
			||||||
            server.to_string(),
 | 
					
 | 
				
			||||||
            fingerprint,
 | 
					        if options.verify_cert {
 | 
				
			||||||
            options.interactive,
 | 
					            let server = server.to_string();
 | 
				
			||||||
            verified_fingerprint.clone(),
 | 
					            let verified_fingerprint = verified_fingerprint.clone();
 | 
				
			||||||
            options.verify_cert,
 | 
					            let interactive = options.interactive;
 | 
				
			||||||
            options.fingerprint_cache,
 | 
					            let fingerprint_cache = options.fingerprint_cache;
 | 
				
			||||||
        );
 | 
					            let prefix = options.prefix.clone();
 | 
				
			||||||
 | 
					            ssl_connector_builder.set_verify_callback(openssl::ssl::SslVerifyMode::PEER, move |valid, ctx| {
 | 
				
			||||||
 | 
					                let (valid, fingerprint) = Self::verify_callback(valid, ctx, fingerprint.clone(), interactive);
 | 
				
			||||||
 | 
					                if valid {
 | 
				
			||||||
 | 
					                    if let Some(fingerprint) = fingerprint {
 | 
				
			||||||
 | 
					                        if fingerprint_cache && prefix.is_some() {
 | 
				
			||||||
 | 
					                            if let Err(err) = store_fingerprint(
 | 
				
			||||||
 | 
					                                prefix.as_ref().unwrap(), &server, &fingerprint) {
 | 
				
			||||||
 | 
					                                eprintln!("{}", err);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        *verified_fingerprint.lock().unwrap() = Some(fingerprint);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                valid
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            ssl_connector_builder.set_verify(openssl::ssl::SslVerifyMode::NONE);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut httpc = hyper::client::HttpConnector::new();
 | 
				
			||||||
 | 
					        httpc.set_nodelay(true); // important for h2 download performance!
 | 
				
			||||||
 | 
					        httpc.set_recv_buffer_size(Some(1024*1024)); //important for h2 download performance!
 | 
				
			||||||
 | 
					        httpc.enforce_http(false); // we want https...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let https = HttpsConnector::with_connector(httpc, ssl_connector_builder.build());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let client = Client::builder()
 | 
				
			||||||
 | 
					        //.http2_initial_stream_window_size( (1 << 31) - 2)
 | 
				
			||||||
 | 
					        //.http2_initial_connection_window_size( (1 << 31) - 2)
 | 
				
			||||||
 | 
					            .build::<_, Body>(https);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let password = options.password.take();
 | 
					        let password = options.password.take();
 | 
				
			||||||
 | 
					        let use_ticket_cache = options.ticket_cache && options.prefix.is_some();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let password = if let Some(password) = password {
 | 
					        let password = if let Some(password) = password {
 | 
				
			||||||
            password
 | 
					            password
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            let mut ticket_info = None;
 | 
					            let mut ticket_info = None;
 | 
				
			||||||
            if options.ticket_cache {
 | 
					            if use_ticket_cache {
 | 
				
			||||||
                ticket_info = load_ticket_info(server, username);
 | 
					                ticket_info = load_ticket_info(options.prefix.as_ref().unwrap(), server, username);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if let Some((ticket, _token)) = ticket_info {
 | 
					            if let Some((ticket, _token)) = ticket_info {
 | 
				
			||||||
                ticket
 | 
					                ticket
 | 
				
			||||||
@ -274,8 +312,18 @@ impl HttpClient {
 | 
				
			|||||||
            server.to_owned(),
 | 
					            server.to_owned(),
 | 
				
			||||||
            username.to_owned(),
 | 
					            username.to_owned(),
 | 
				
			||||||
            password,
 | 
					            password,
 | 
				
			||||||
            options.ticket_cache,
 | 
					        ).map_ok({
 | 
				
			||||||
        );
 | 
					            let server = server.to_string();
 | 
				
			||||||
 | 
					            let prefix = options.prefix.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            move |auth| {
 | 
				
			||||||
 | 
					                if use_ticket_cache & &prefix.is_some() {
 | 
				
			||||||
 | 
					                    let _ = store_ticket_info(prefix.as_ref().unwrap(), &server, &auth.username, &auth.ticket, &auth.token);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                auth
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            client,
 | 
					            client,
 | 
				
			||||||
@ -320,25 +368,22 @@ impl HttpClient {
 | 
				
			|||||||
    fn verify_callback(
 | 
					    fn verify_callback(
 | 
				
			||||||
        valid: bool, ctx:
 | 
					        valid: bool, ctx:
 | 
				
			||||||
        &mut X509StoreContextRef,
 | 
					        &mut X509StoreContextRef,
 | 
				
			||||||
        server: String,
 | 
					 | 
				
			||||||
        expected_fingerprint: Option<String>,
 | 
					        expected_fingerprint: Option<String>,
 | 
				
			||||||
        interactive: bool,
 | 
					        interactive: bool,
 | 
				
			||||||
        verified_fingerprint: Arc<Mutex<Option<String>>>,
 | 
					    ) -> (bool, Option<String>) {
 | 
				
			||||||
        fingerprint_cache: bool,
 | 
					        if valid { return (true, None); }
 | 
				
			||||||
    ) -> bool {
 | 
					 | 
				
			||||||
        if valid { return true; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let cert = match ctx.current_cert() {
 | 
					        let cert = match ctx.current_cert() {
 | 
				
			||||||
            Some(cert) => cert,
 | 
					            Some(cert) => cert,
 | 
				
			||||||
            None => return false,
 | 
					            None => return (false, None),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let depth = ctx.error_depth();
 | 
					        let depth = ctx.error_depth();
 | 
				
			||||||
        if depth != 0 { return false; }
 | 
					        if depth != 0 { return (false, None); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let fp = match cert.digest(openssl::hash::MessageDigest::sha256()) {
 | 
					        let fp = match cert.digest(openssl::hash::MessageDigest::sha256()) {
 | 
				
			||||||
            Ok(fp) => fp,
 | 
					            Ok(fp) => fp,
 | 
				
			||||||
            Err(_) => return false, // should not happen
 | 
					            Err(_) => return (false, None), // should not happen
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let fp_string = proxmox::tools::digest_to_hex(&fp);
 | 
					        let fp_string = proxmox::tools::digest_to_hex(&fp);
 | 
				
			||||||
        let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
 | 
					        let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
 | 
				
			||||||
@ -346,10 +391,9 @@ impl HttpClient {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if let Some(expected_fingerprint) = expected_fingerprint {
 | 
					        if let Some(expected_fingerprint) = expected_fingerprint {
 | 
				
			||||||
            if expected_fingerprint == fp_string {
 | 
					            if expected_fingerprint == fp_string {
 | 
				
			||||||
                *verified_fingerprint.lock().unwrap() = Some(fp_string);
 | 
					                return (true, Some(fp_string));
 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                return false;
 | 
					                return (false, None);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -364,58 +408,18 @@ impl HttpClient {
 | 
				
			|||||||
                match std::io::stdin().read_exact(&mut buf) {
 | 
					                match std::io::stdin().read_exact(&mut buf) {
 | 
				
			||||||
                    Ok(()) => {
 | 
					                    Ok(()) => {
 | 
				
			||||||
                        if buf[0] == b'y' || buf[0] == b'Y' {
 | 
					                        if buf[0] == b'y' || buf[0] == b'Y' {
 | 
				
			||||||
                            if fingerprint_cache {
 | 
					                            return (true, Some(fp_string));
 | 
				
			||||||
                                if let Err(err) = store_fingerprint(&server, &fp_string) {
 | 
					 | 
				
			||||||
                                    eprintln!("{}", err);
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            *verified_fingerprint.lock().unwrap() = Some(fp_string);
 | 
					 | 
				
			||||||
                           return true;
 | 
					 | 
				
			||||||
                        } else if buf[0] == b'n' || buf[0] == b'N' {
 | 
					                        } else if buf[0] == b'n' || buf[0] == b'N' {
 | 
				
			||||||
                            return false;
 | 
					                            return (false, None);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Err(_) => {
 | 
					                    Err(_) => {
 | 
				
			||||||
                        return false;
 | 
					                        return (false, None);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        false
 | 
					        (false, None)
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn build_client(
 | 
					 | 
				
			||||||
        server: String,
 | 
					 | 
				
			||||||
        fingerprint: Option<String>,
 | 
					 | 
				
			||||||
        interactive: bool,
 | 
					 | 
				
			||||||
        verified_fingerprint: Arc<Mutex<Option<String>>>,
 | 
					 | 
				
			||||||
        verify_cert: bool,
 | 
					 | 
				
			||||||
        fingerprint_cache: bool,
 | 
					 | 
				
			||||||
    ) -> Client<HttpsConnector> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut ssl_connector_builder = SslConnector::builder(SslMethod::tls()).unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if verify_cert {
 | 
					 | 
				
			||||||
            ssl_connector_builder.set_verify_callback(openssl::ssl::SslVerifyMode::PEER, move |valid, ctx| {
 | 
					 | 
				
			||||||
                Self::verify_callback(
 | 
					 | 
				
			||||||
                    valid, ctx, server.clone(), fingerprint.clone(), interactive,
 | 
					 | 
				
			||||||
                    verified_fingerprint.clone(), fingerprint_cache)
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            ssl_connector_builder.set_verify(openssl::ssl::SslVerifyMode::NONE);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut httpc = hyper::client::HttpConnector::new();
 | 
					 | 
				
			||||||
        httpc.set_nodelay(true); // important for h2 download performance!
 | 
					 | 
				
			||||||
        httpc.set_recv_buffer_size(Some(1024*1024)); //important for h2 download performance!
 | 
					 | 
				
			||||||
        httpc.enforce_http(false); // we want https...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let https = HttpsConnector::with_connector(httpc, ssl_connector_builder.build());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Client::builder()
 | 
					 | 
				
			||||||
        //.http2_initial_stream_window_size( (1 << 31) - 2)
 | 
					 | 
				
			||||||
        //.http2_initial_connection_window_size( (1 << 31) - 2)
 | 
					 | 
				
			||||||
            .build::<_, Body>(https)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn request(&self, mut req: Request<Body>) -> Result<Value, Error> {
 | 
					    pub async fn request(&self, mut req: Request<Body>) -> Result<Value, Error> {
 | 
				
			||||||
@ -576,7 +580,6 @@ impl HttpClient {
 | 
				
			|||||||
        server: String,
 | 
					        server: String,
 | 
				
			||||||
        username: String,
 | 
					        username: String,
 | 
				
			||||||
        password: String,
 | 
					        password: String,
 | 
				
			||||||
        use_ticket_cache: bool,
 | 
					 | 
				
			||||||
    ) -> Result<AuthInfo, Error> {
 | 
					    ) -> Result<AuthInfo, Error> {
 | 
				
			||||||
        let data = json!({ "username": username, "password": password });
 | 
					        let data = json!({ "username": username, "password": password });
 | 
				
			||||||
        let req = Self::request_builder(&server, "POST", "/api2/json/access/ticket", Some(data)).unwrap();
 | 
					        let req = Self::request_builder(&server, "POST", "/api2/json/access/ticket", Some(data)).unwrap();
 | 
				
			||||||
@ -587,10 +590,6 @@ impl HttpClient {
 | 
				
			|||||||
            token: cred["data"]["CSRFPreventionToken"].as_str().unwrap().to_owned(),
 | 
					            token: cred["data"]["CSRFPreventionToken"].as_str().unwrap().to_owned(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if use_ticket_cache {
 | 
					 | 
				
			||||||
            let _ = store_ticket_info(&server, &auth.username, &auth.ticket, &auth.token);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(auth)
 | 
					        Ok(auth)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user