From ebef0fad26e4792cdc6ea618611f9aaec39dfacf Mon Sep 17 00:00:00 2001 From: Maksym Vorobiov Date: Wed, 4 Mar 2020 17:28:07 +0200 Subject: [PATCH] add H2 window size configuration and max_http_version to awc::ClientBuilder --- awc/CHANGES.md | 6 +++++ awc/src/builder.rs | 59 +++++++++++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/awc/CHANGES.md b/awc/CHANGES.md index d410ae514..1d6e03708 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -1,5 +1,11 @@ # Changes +## [NEXT] + +* ClientBuilder accepts initial_window_size and initial_connection_window_size HTTP2 configuration + +* ClientBuilder allowing to set max_http_version to limit HTTP version to be used + ## [1.0.1] - 2019-12-15 * Fix compilation with default features off diff --git a/awc/src/builder.rs b/awc/src/builder.rs index 7bd0171ec..2b1679312 100644 --- a/awc/src/builder.rs +++ b/awc/src/builder.rs @@ -4,11 +4,11 @@ use std::fmt; use std::rc::Rc; use std::time::Duration; -use actix_http::client::{Connect, ConnectError, Connection, Connector}; +use actix_http::client::{Connect as HttpConnect, ConnectError, Connection, Connector}; use actix_http::http::{header, Error as HttpError, HeaderMap, HeaderName}; use actix_service::Service; -use crate::connect::ConnectorWrapper; +use crate::connect::{ConnectorWrapper, Connect}; use crate::{Client, ClientConfig}; /// An HTTP Client builder @@ -16,10 +16,15 @@ use crate::{Client, ClientConfig}; /// This type can be used to construct an instance of `Client` through a /// builder-like pattern. pub struct ClientBuilder { - config: ClientConfig, default_headers: bool, allow_redirects: bool, max_redirects: usize, + max_http_version: Option, + stream_window_size: Option, + conn_window_size: Option, + headers: HeaderMap, + timeout: Option, + connector: Option>>, } impl Default for ClientBuilder { @@ -34,25 +39,24 @@ impl ClientBuilder { default_headers: true, allow_redirects: true, max_redirects: 10, - config: ClientConfig { - headers: HeaderMap::new(), - timeout: Some(Duration::from_secs(5)), - connector: RefCell::new(Box::new(ConnectorWrapper( - Connector::new().finish(), - ))), - }, + headers: HeaderMap::new(), + timeout: Some(Duration::from_secs(5)), + connector: None, + max_http_version: None, + stream_window_size: None, + conn_window_size: None, } } /// Use custom connector service. pub fn connector(mut self, connector: T) -> Self where - T: Service + 'static, + T: Service + 'static, T::Response: Connection, ::Future: 'static, T::Future: 'static, { - self.config.connector = RefCell::new(Box::new(ConnectorWrapper(connector))); + self.connector = Some(RefCell::new(Box::new(ConnectorWrapper(connector)))); self } @@ -61,13 +65,13 @@ impl ClientBuilder { /// Request timeout is the total time before a response must be received. /// Default value is 5 seconds. pub fn timeout(mut self, timeout: Duration) -> Self { - self.config.timeout = Some(timeout); + self.timeout = Some(timeout); self } /// Disable request timeout. pub fn disable_timeout(mut self) -> Self { - self.config.timeout = None; + self.timeout = None; self } @@ -106,7 +110,7 @@ impl ClientBuilder { match HeaderName::try_from(key) { Ok(key) => match value.try_into() { Ok(value) => { - self.config.headers.append(key, value); + self.headers.append(key, value); } Err(e) => log::error!("Header value error: {:?}", e), }, @@ -140,7 +144,27 @@ impl ClientBuilder { /// Finish build process and create `Client` instance. pub fn finish(self) -> Client { - Client(Rc::new(self.config)) + let connector = if self.connector.is_some() { + self.connector.unwrap() + } else { + let mut connector = Connector::new(); + if let Some(val) = self.max_http_version { + connector = connector.max_http_version(val) + }; + if let Some(val) = self.conn_window_size { + connector = connector.initial_connection_window_size(val) + }; + if let Some(val) = self.stream_window_size { + connector = connector.initial_window_size(val) + }; + RefCell::new(Box::new(ConnectorWrapper(connector.finish())) as Box) + }; + let config = ClientConfig { + headers: self.headers, + timeout: self.timeout, + connector, + }; + Client(Rc::new(config)) } } @@ -153,7 +177,6 @@ mod tests { let client = ClientBuilder::new().basic_auth("username", Some("password")); assert_eq!( client - .config .headers .get(header::AUTHORIZATION) .unwrap() @@ -165,7 +188,6 @@ mod tests { let client = ClientBuilder::new().basic_auth("username", None); assert_eq!( client - .config .headers .get(header::AUTHORIZATION) .unwrap() @@ -180,7 +202,6 @@ mod tests { let client = ClientBuilder::new().bearer_auth("someS3cr3tAutht0k3n"); assert_eq!( client - .config .headers .get(header::AUTHORIZATION) .unwrap()