Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(awc): allow to configure connector per request #3515

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions awc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Update `brotli` dependency to `7`.
- Prevent panics on connection pool drop when Tokio runtime is shutdown early.
- Minimum supported Rust version (MSRV) is now 1.75.
- Allow to set a specific SNI hostname on the request for TLS connections.

## 3.5.1

Expand Down
22 changes: 14 additions & 8 deletions awc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use std::{fmt, net::IpAddr, rc::Rc, time::Duration};
use actix_http::{
error::HttpError,
header::{self, HeaderMap, HeaderName, TryIntoHeaderPair},
Uri,
};
use actix_rt::net::{ActixStream, TcpStream};
use actix_service::{boxed, Service};
use base64::prelude::*;

use crate::{
client::{
ClientConfig, ConnectInfo, Connector, ConnectorService, TcpConnectError, TcpConnection,
ClientConfig, ConnectInfo, Connector, ConnectorService, HostnameWithSni, TcpConnectError,
TcpConnection,
},
connect::DefaultConnector,
error::SendRequestError,
Expand Down Expand Up @@ -46,8 +46,8 @@ impl ClientBuilder {
#[allow(clippy::new_ret_no_self)]
pub fn new() -> ClientBuilder<
impl Service<
ConnectInfo<Uri>,
Response = TcpConnection<Uri, TcpStream>,
ConnectInfo<HostnameWithSni>,
Response = TcpConnection<HostnameWithSni, TcpStream>,
Error = TcpConnectError,
> + Clone,
(),
Expand All @@ -69,16 +69,22 @@ impl ClientBuilder {

impl<S, Io, M> ClientBuilder<S, M>
where
S: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io>, Error = TcpConnectError>
+ Clone
S: Service<
ConnectInfo<HostnameWithSni>,
Response = TcpConnection<HostnameWithSni, Io>,
Error = TcpConnectError,
> + Clone
+ 'static,
Io: ActixStream + fmt::Debug + 'static,
{
/// Use custom connector service.
pub fn connector<S1, Io1>(self, connector: Connector<S1>) -> ClientBuilder<S1, M>
where
S1: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io1>, Error = TcpConnectError>
+ Clone
S1: Service<
ConnectInfo<HostnameWithSni>,
Response = TcpConnection<HostnameWithSni, Io1>,
Error = TcpConnectError,
> + Clone
+ 'static,
Io1: ActixStream + fmt::Debug + 'static,
{
Expand Down
100 changes: 91 additions & 9 deletions awc/src/client/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,122 @@ use std::{net::IpAddr, time::Duration};
const DEFAULT_H2_CONN_WINDOW: u32 = 1024 * 1024 * 2; // 2MB
const DEFAULT_H2_STREAM_WINDOW: u32 = 1024 * 1024; // 1MB

/// Connector configuration
#[derive(Clone)]
pub(crate) struct ConnectorConfig {
/// Connect configuration
#[derive(Clone, Hash, Eq, PartialEq)]
pub struct ConnectConfig {
pub(crate) timeout: Duration,
pub(crate) handshake_timeout: Duration,
pub(crate) conn_lifetime: Duration,
pub(crate) conn_keep_alive: Duration,
pub(crate) disconnect_timeout: Option<Duration>,
pub(crate) limit: usize,
pub(crate) conn_window_size: u32,
pub(crate) stream_window_size: u32,
pub(crate) local_address: Option<IpAddr>,
}

impl Default for ConnectorConfig {
/// Connector configuration
#[derive(Clone)]
pub struct ConnectorConfig {
pub(crate) default_connect_config: ConnectConfig,
pub(crate) disconnect_timeout: Option<Duration>,
pub(crate) limit: usize,
}

impl Default for ConnectConfig {
fn default() -> Self {
Self {
timeout: Duration::from_secs(5),
handshake_timeout: Duration::from_secs(5),
conn_lifetime: Duration::from_secs(75),
conn_keep_alive: Duration::from_secs(15),
disconnect_timeout: Some(Duration::from_millis(3000)),
limit: 100,
conn_window_size: DEFAULT_H2_CONN_WINDOW,
stream_window_size: DEFAULT_H2_STREAM_WINDOW,
local_address: None,
}
}
}

impl Default for ConnectorConfig {
fn default() -> Self {
Self {
default_connect_config: ConnectConfig::default(),
disconnect_timeout: Some(Duration::from_millis(3000)),
limit: 100,
}
}
}

impl ConnectorConfig {
pub(crate) fn no_disconnect_timeout(&self) -> Self {
pub fn no_disconnect_timeout(&self) -> Self {
let mut res = self.clone();
res.disconnect_timeout = None;
res
}
}

impl ConnectConfig {
/// Sets TCP connection timeout.
///
/// This is the max time allowed to connect to remote host, including DNS name resolution.
///
/// By default, the timeout is 5 seconds.
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}

/// Sets TLS handshake timeout.
///
/// This is the max time allowed to perform the TLS handshake with remote host after TCP
/// connection is established.
///
/// By default, the timeout is 5 seconds.
pub fn handshake_timeout(mut self, timeout: Duration) -> Self {
self.handshake_timeout = timeout;
self
}

/// Sets the initial window size (in bytes) for HTTP/2 stream-level flow control for received
/// data.
///
/// The default value is 65,535 and is good for APIs, but not for big objects.
pub fn initial_window_size(mut self, size: u32) -> Self {
self.stream_window_size = size;
self
}

/// Sets the initial window size (in bytes) for HTTP/2 connection-level flow control for
/// received data.
///
/// The default value is 65,535 and is good for APIs, but not for big objects.
pub fn initial_connection_window_size(mut self, size: u32) -> Self {
self.conn_window_size = size;
self
}

/// Set keep-alive period for opened connection.
///
/// Keep-alive period is the period between connection usage. If
/// the delay between repeated usages of the same connection
/// exceeds this period, the connection is closed.
/// Default keep-alive period is 15 seconds.
pub fn conn_keep_alive(mut self, dur: Duration) -> Self {
self.conn_keep_alive = dur;
self
}

/// Set max lifetime period for connection.
///
/// Connection lifetime is max lifetime of any opened connection
/// until it is closed regardless of keep-alive period.
/// Default lifetime period is 75 seconds.
pub fn conn_lifetime(mut self, dur: Duration) -> Self {
self.conn_lifetime = dur;
self
}

/// Set local IP Address the connector would use for establishing connection.
pub fn local_address(mut self, addr: IpAddr) -> Self {
self.local_address = Some(addr);
self
}
}
Loading
Loading