Skip to content

Commit

Permalink
Add a number of conditional compilation features
Browse files Browse the repository at this point in the history
  • Loading branch information
alexrudy committed Apr 5, 2024
1 parent 14400fd commit bcdc466
Show file tree
Hide file tree
Showing 19 changed files with 351 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ repos:
- id: fmt
- id: cargo-check
- id: clippy
args: ["--", "-D", "warnings", "-A", "unknown-lints"]
args: ["--all-features", "--", "-D", "warnings", "-A", "unknown-lints"]
- repo: local
hooks:
- id: cargo-machete
Expand Down
59 changes: 46 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,28 @@ repository = "https://github.com/alexrudy/hyperdriver"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
axum = "0.7"
camino = { version = "1", default-features = false }
axum = { version = "0.7", optional = true }
bytes = "1"
camino = { version = "1", default-features = false, features = ["serde1"] }
dashmap = "5"
dashmap = { version = "5", optional = true }
futures-core = "0.3"
futures-util = "0.3"
http = { version = "1" }
http-body = { version = "1" }
http-body-util = { version = "0.1" }
humantime-serde = "1.1.1"
humantime-serde = { version = "1.1.1", optional = true }
hyper = { version = "1", features = ["full"] }
libc = { version = "0.2" }
ouroboros = "0.18"
pem-rfc7468 = { version = "0.7", features = ["alloc"] }
libc = { version = "0.2", optional = true }
ouroboros = { version = "0.18", optional = true }
pem-rfc7468 = { version = "0.7", features = ["alloc"], optional = true }
pin-project = { version = "1" }
rustls = "^0.23"
rustls-native-certs = "0.7.0"
serde = { version = "1" }
socket2 = "0.5"
rustls = { version = "0.23", optional = true }
rustls-native-certs = { version = "0.7.0", optional = true }
serde = { version = "1", optional = true }
socket2 = { version = "0.5", optional = true }
thiserror = { version = "1" }
tokio = { version = "1", features = ["full"] }
tokio-rustls = "0.26"
tokio-rustls = { version = "0.26", optional = true }
tower = { version = "0.4", features = [
"make",
"util",
Expand All @@ -43,9 +43,42 @@ tracing-subscriber = "0.2"
tempfile = "3"

[features]
default = []
axum = ["dep:axum"]
default = ["client", "server", "discovery", "stream"]
docs = []
incoming = []
client = ["dep:socket2"]
server = ["dep:ouroboros"]
discovery = [
"server",
"client",
"pidfile",
"stream",
"dep:humantime-serde",
"dep:dashmap",
"dep:serde",
"camino/serde1",
]
pidfile = ["dep:libc"]
sni = []
stream = []
tls = [
"dep:rustls-native-certs",
"dep:rustls",
"dep:tokio-rustls",
"dep:pem-rfc7468",
]

[package.metadata.cargo-machete]
ignored = ["humantime-serde"]


[[test]]
name = "server"
path = "tests/server.rs"
required-features = ["server"]

[[test]]
name = "client"
path = "tests/client.rs"
required-features = ["client"]
23 changes: 19 additions & 4 deletions src/client/clients/builder.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#[cfg(feature = "tls")]
use rustls::ClientConfig;

use crate::client::{conn::http::HttpConnectionBuilder, default_tls_config, Client};
use crate::client::{conn::http::HttpConnectionBuilder, Client};

#[cfg(feature = "tls")]
use crate::client::default_tls_config;

#[derive(Debug)]
pub struct Builder {
tcp: crate::client::conn::TcpConnectionConfig,
#[cfg(feature = "tls")]
tls: Option<ClientConfig>,
pool: Option<crate::client::pool::Config>,
conn: crate::client::conn::http::HttpConnectionBuilder,
Expand All @@ -13,7 +18,9 @@ pub struct Builder {
impl Default for Builder {
fn default() -> Self {
Self {
#[cfg(feature = "stream")]
tcp: Default::default(),
#[cfg(feature = "tls")]
tls: Some(default_tls_config()),
pool: Some(Default::default()),
conn: Default::default(),
Expand All @@ -22,10 +29,12 @@ impl Default for Builder {
}

impl Builder {
#[cfg(feature = "stream")]
pub fn tcp(&mut self) -> &mut crate::client::conn::TcpConnectionConfig {
&mut self.tcp
}

#[cfg(feature = "tls")]
pub fn with_tls(&mut self, config: ClientConfig) -> &mut Self {
self.tls = Some(config);
self
Expand All @@ -42,10 +51,16 @@ impl Builder {

impl Builder {
pub fn build(self) -> Client<HttpConnectionBuilder> {
let tls = self.tls.unwrap_or_else(super::default_tls_config);

Client {
transport: crate::client::conn::TcpConnector::new(self.tcp, tls),
#[cfg(feature = "tls")]
transport: crate::client::conn::TcpConnector::new(
self.tcp,
self.tls.unwrap_or_else(super::default_tls_config),
),

#[cfg(not(feature = "tls"))]
transport: crate::client::conn::TcpConnector::new(self.tcp),

protocol: HttpConnectionBuilder::default(),
pool: self.pool.map(crate::client::pool::Pool::new),
}
Expand Down
30 changes: 29 additions & 1 deletion src/client/clients/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,29 @@ use hyper::body::Incoming;
use tracing::warn;

use crate::client::conn;

#[cfg(feature = "stream")]
use crate::client::conn::tcp::TcpConnector;
use crate::client::conn::Connection;
use crate::client::conn::ConnectionError;
use crate::client::conn::HttpProtocol;
use crate::client::conn::Protocol;
use crate::client::conn::Transport;
use crate::client::conn::TransportStream;
use crate::client::default_tls_config;
use crate::client::pool::Checkout;
use crate::client::pool::Connector;
use crate::client::pool::{self, PoolableConnection, Pooled};
use crate::client::Error;
use crate::client::HttpConnectionBuilder;
use crate::stream::info::HasConnectionInfo;

#[cfg(feature = "tls")]
use crate::client::default_tls_config;

#[cfg(feature = "stream")]
mod builder;

#[cfg(feature = "stream")]
/// An HTTP client
#[derive(Debug)]
pub struct Client<P = HttpConnectionBuilder, T = TcpConnector>
Expand All @@ -44,6 +50,20 @@ where
pool: Option<pool::Pool<P::Connection>>,
}

#[cfg(not(feature = "stream"))]
/// An HTTP client
#[derive(Debug)]
pub struct Client<P, T>
where
T: Transport,
P: Protocol<T::IO>,
P::Connection: PoolableConnection,
{
protocol: P,
transport: T,
pool: Option<pool::Pool<P::Connection>>,
}

impl<P, T> Client<P, T>
where
T: Transport,
Expand Down Expand Up @@ -75,6 +95,7 @@ where
}
}

#[cfg(feature = "stream")]
impl Client<HttpConnectionBuilder, TcpConnector> {
/// A client builder for configuring the client.
pub fn builder() -> builder::Builder {
Expand All @@ -88,15 +109,22 @@ impl Client<HttpConnectionBuilder, TcpConnector> {
idle_timeout: Some(std::time::Duration::from_secs(90)),
max_idle_per_host: 32,
})),

#[cfg(feature = "tls")]
transport: TcpConnector::new(
crate::client::conn::TcpConnectionConfig::default(),
default_tls_config(),
),

#[cfg(not(feature = "tls"))]
transport: TcpConnector::new(crate::client::conn::TcpConnectionConfig::default()),

protocol: conn::http::HttpConnectionBuilder::default(),
}
}
}

#[cfg(feature = "stream")]
impl Default for Client<HttpConnectionBuilder> {
fn default() -> Self {
Self::new_tcp_http()
Expand Down
1 change: 1 addition & 0 deletions src/client/conn/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ impl HttpConnectionBuilder {
match self.protocol {
HttpProtocol::Http2 => self.handshake_h2(transport.into_inner()).await,
HttpProtocol::Http1 => {
#[cfg(feature = "tls")]
if transport
.info()
.tls
Expand Down
22 changes: 20 additions & 2 deletions src/client/conn/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use crate::stream::client::Stream;
use crate::stream::info::ConnectionInfo;
use ::http::Uri;
use futures_util::future::BoxFuture;
use futures_util::FutureExt;
Expand All @@ -13,15 +11,25 @@ use hyper::body::Incoming;
use tower::Service;

pub mod dns;

#[cfg(feature = "stream")]
pub mod duplex;
pub mod http;

#[cfg(feature = "stream")]
pub mod tcp;

use crate::client::pool::PoolableTransport;
#[cfg(feature = "stream")]
use crate::stream::client::Stream;
use crate::stream::info::ConnectionInfo;
use crate::stream::info::HasConnectionInfo;

pub use self::http::ConnectionError;

#[cfg(feature = "stream")]
pub(crate) use self::tcp::TcpConnectionConfig;
#[cfg(feature = "stream")]
pub(crate) use self::tcp::TcpConnector;

/// A transport provides data transmission between two endpoints.
Expand Down Expand Up @@ -89,6 +97,7 @@ impl<IO> TransportStream<IO>
where
IO: HasConnectionInfo,
{
#[cfg_attr(not(feature = "tls"), allow(dead_code))]
pub(crate) fn info(&self) -> &ConnectionInfo<IO::Addr> {
&self.info
}
Expand All @@ -102,9 +111,12 @@ where
}
}

#[cfg(feature = "stream")]
impl TransportStream<Stream> {
/// Create a new transport from a `crate::stream::client::Stream`.
#[cfg_attr(not(feature = "tls"), allow(unused_mut))]
pub async fn new(mut stream: Stream) -> io::Result<Self> {
#[cfg(feature = "tls")]
stream.finish_handshake().await?;

let info = stream.info();
Expand All @@ -118,12 +130,18 @@ where
IO: HasConnectionInfo + Unpin + Send + 'static,
IO::Addr: Send,
{
#[cfg(feature = "tls")]
fn can_share(&self) -> bool {
self.info.tls.as_ref().and_then(|tls| tls.alpn.as_ref())
== Some(&crate::stream::info::Protocol::Http(
::http::Version::HTTP_2,
))
}

#[cfg(not(feature = "tls"))]
fn can_share(&self) -> bool {
false
}
}

impl<IO> AsyncRead for TransportStream<IO>
Expand Down
Loading

0 comments on commit bcdc466

Please sign in to comment.