Skip to content

Commit 4e55583

Browse files
authored
feat(client): Make client an optional feature
cc #2223 BREAKING CHANGE: The HTTP client of hyper is now an optional feature. To enable the client, add `features = ["client"]` to the dependency in your `Cargo.toml`.
1 parent eb092a7 commit 4e55583

File tree

19 files changed

+238
-164
lines changed

19 files changed

+238
-164
lines changed

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ pnet = "0.25.0"
7474
default = [
7575
"runtime",
7676
"stream",
77-
77+
"client",
7878
"http1",
7979
"http2",
8080
]
8181
full = [
82+
"client",
8283
"http1",
8384
"http2",
8485
"stream",
@@ -99,6 +100,8 @@ tcp = [
99100
http1 = []
100101
http2 = ["h2"]
101102

103+
client = []
104+
102105
# `impl Stream` for things
103106
stream = []
104107

src/body/body.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::fmt;
66
use bytes::Bytes;
77
use futures_channel::mpsc;
88
#[cfg(any(feature = "http1", feature = "http2"))]
9+
#[cfg(feature = "client")]
910
use futures_channel::oneshot;
1011
use futures_core::Stream; // for mpsc::Receiver
1112
#[cfg(feature = "stream")]
@@ -18,6 +19,7 @@ use super::DecodedLength;
1819
use crate::common::sync_wrapper::SyncWrapper;
1920
use crate::common::{task, watch, Pin, Poll};
2021
#[cfg(any(feature = "http1", feature = "http2"))]
22+
#[cfg(feature = "client")]
2123
use crate::common::{Future, Never};
2224
#[cfg(feature = "http2")]
2325
use crate::proto::h2::ping;
@@ -72,16 +74,19 @@ struct Extra {
7274
}
7375

7476
#[cfg(any(feature = "http1", feature = "http2"))]
77+
#[cfg(feature = "client")]
7578
type DelayEofUntil = oneshot::Receiver<Never>;
7679

7780
enum DelayEof {
7881
/// Initial state, stream hasn't seen EOF yet.
7982
#[cfg(any(feature = "http1", feature = "http2"))]
83+
#[cfg(feature = "client")]
8084
NotEof(DelayEofUntil),
8185
/// Transitions to this state once we've seen `poll` try to
8286
/// return EOF (`None`). This future is then polled, and
8387
/// when it completes, the Body finally returns EOF (`None`).
8488
#[cfg(any(feature = "http1", feature = "http2"))]
89+
#[cfg(feature = "client")]
8590
Eof(DelayEofUntil),
8691
}
8792

@@ -219,6 +224,7 @@ impl Body {
219224
}
220225

221226
#[cfg(any(feature = "http1", feature = "http2"))]
227+
#[cfg(feature = "client")]
222228
pub(crate) fn delayed_eof(&mut self, fut: DelayEofUntil) {
223229
self.extra_mut().delayed_eof = Some(DelayEof::NotEof(fut));
224230
}
@@ -242,6 +248,7 @@ impl Body {
242248
fn poll_eof(&mut self, cx: &mut task::Context<'_>) -> Poll<Option<crate::Result<Bytes>>> {
243249
match self.take_delayed_eof() {
244250
#[cfg(any(feature = "http1", feature = "http2"))]
251+
#[cfg(feature = "client")]
245252
Some(DelayEof::NotEof(mut delay)) => match self.poll_inner(cx) {
246253
ok @ Poll::Ready(Some(Ok(..))) | ok @ Poll::Pending => {
247254
self.extra_mut().delayed_eof = Some(DelayEof::NotEof(delay));
@@ -258,6 +265,7 @@ impl Body {
258265
Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
259266
},
260267
#[cfg(any(feature = "http1", feature = "http2"))]
268+
#[cfg(feature = "client")]
261269
Some(DelayEof::Eof(mut delay)) => match Pin::new(&mut delay).poll(cx) {
262270
Poll::Ready(Ok(never)) => match never {},
263271
Poll::Pending => {
@@ -266,7 +274,10 @@ impl Body {
266274
}
267275
Poll::Ready(Err(_done)) => Poll::Ready(None),
268276
},
269-
#[cfg(not(any(feature = "http1", feature = "http2")))]
277+
#[cfg(any(
278+
not(any(feature = "http1", feature = "http2")),
279+
not(feature = "client")
280+
))]
270281
Some(delay_eof) => match delay_eof {},
271282
None => self.poll_inner(cx),
272283
}

src/cfg.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,50 @@
1-
macro_rules! cfg_any_http {
2-
($($item:item)*) => {
1+
macro_rules! cfg_feature {
2+
(
3+
#![$meta:meta]
4+
$($item:item)*
5+
) => {
36
$(
4-
#[cfg(any(
5-
feature = "http1",
6-
feature = "http2",
7-
))]
8-
#[cfg_attr(docsrs, doc(cfg(any(
9-
feature = "http1",
10-
feature = "http2",
11-
))))]
7+
#[cfg($meta)]
8+
#[cfg_attr(docsrs, doc(cfg($meta)))]
129
$item
1310
)*
1411
}
1512
}
1613

14+
macro_rules! cfg_any_http {
15+
($($item:item)*) => {
16+
cfg_feature! {
17+
#![any(feature = "http1", feature = "http2")]
18+
$($item)*
19+
}
20+
}
21+
}
22+
1723
cfg_any_http! {
1824
macro_rules! cfg_http1 {
1925
($($item:item)*) => {
20-
$(
21-
#[cfg(feature = "http1")]
22-
#[cfg_attr(docsrs, doc(cfg(feature = "http1")))]
23-
$item
24-
)*
26+
cfg_feature! {
27+
#![feature = "http1"]
28+
$($item)*
29+
}
2530
}
2631
}
2732

2833
macro_rules! cfg_http2 {
2934
($($item:item)*) => {
30-
$(
31-
#[cfg(feature = "http2")]
32-
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
33-
$item
34-
)*
35+
cfg_feature! {
36+
#![feature = "http2"]
37+
$($item)*
38+
}
39+
}
40+
}
41+
42+
macro_rules! cfg_client {
43+
($($item:item)*) => {
44+
cfg_feature! {
45+
#![feature = "client"]
46+
$($item)*
47+
}
3548
}
3649
}
3750
}

src/client/conn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use tower_service::Service;
2525

2626
use super::dispatch;
2727
use crate::body::HttpBody;
28-
use crate::common::{task, BoxSendFuture, Exec, Future, Pin, Poll};
28+
use crate::common::{task, exec::{BoxSendFuture, Exec}, Future, Pin, Poll};
2929
use crate::proto;
3030
use crate::rt::Executor;
3131
#[cfg(feature = "http1")]

src/client/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use http::{Method, Request, Response, Uri, Version};
6262
use self::connect::{sealed::Connect, Alpn, Connected, Connection};
6363
use self::pool::{Key as PoolKey, Pool, Poolable, Pooled, Reservation};
6464
use crate::body::{Body, HttpBody};
65-
use crate::common::{lazy as hyper_lazy, task, BoxSendFuture, Future, Lazy, Pin, Poll};
65+
use crate::common::{lazy as hyper_lazy, task, exec::BoxSendFuture, Future, Lazy, Pin, Poll};
6666
use crate::rt::Executor;
6767

6868
#[cfg(feature = "tcp")]

src/client/pool.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use futures_channel::oneshot;
1111
use tokio::time::{Duration, Instant, Interval};
1212

1313
use super::Ver;
14-
use crate::common::{task, Exec, Future, Pin, Poll, Unpin};
14+
use crate::common::{task, exec::Exec, Future, Pin, Poll, Unpin};
1515

1616
// FIXME: allow() required due to `impl Trait` leaking types to this lint
1717
#[allow(missing_debug_implementations)]
@@ -777,7 +777,7 @@ mod tests {
777777
use std::time::Duration;
778778

779779
use super::{Connecting, Key, Pool, Poolable, Reservation, WeakOpt};
780-
use crate::common::{task, Exec, Future, Pin};
780+
use crate::common::{task, exec::Exec, Future, Pin};
781781

782782
/// Test unique reservations.
783783
#[derive(Debug, PartialEq, Eq)]

src/common/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@ pub(crate) mod drain;
1616
pub(crate) mod exec;
1717
pub(crate) mod io;
1818
#[cfg(any(feature = "http1", feature = "http2"))]
19+
#[cfg(feature = "client")]
1920
mod lazy;
2021
mod never;
2122
#[cfg(feature = "stream")]
2223
pub(crate) mod sync_wrapper;
2324
pub(crate) mod task;
2425
pub(crate) mod watch;
2526

27+
//#[cfg(any(feature = "http1", feature = "http2"))]
28+
//pub(crate) use self::exec::{BoxSendFuture, Exec};
2629
#[cfg(any(feature = "http1", feature = "http2"))]
27-
pub(crate) use self::exec::{BoxSendFuture, Exec};
28-
#[cfg(any(feature = "http1", feature = "http2"))]
30+
#[cfg(feature = "client")]
2931
pub(crate) use self::lazy::{lazy, Started as Lazy};
3032
pub use self::never::Never;
3133
pub(crate) use self::task::Poll;

src/error.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,18 @@ pub(crate) enum User {
8888
UnexpectedHeader,
8989
/// User tried to create a Request with bad version.
9090
#[cfg(any(feature = "http1", feature = "http2"))]
91+
#[cfg(feature = "client")]
9192
UnsupportedVersion,
9293
/// User tried to create a CONNECT Request with the Client.
9394
#[cfg(any(feature = "http1", feature = "http2"))]
95+
#[cfg(feature = "client")]
9496
UnsupportedRequestMethod,
9597
/// User tried to respond with a 1xx (not 101) response code.
9698
#[cfg(feature = "http1")]
9799
UnsupportedStatusCode,
98100
/// User tried to send a Request with Client with non-absolute URI.
99101
#[cfg(any(feature = "http1", feature = "http2"))]
102+
#[cfg(feature = "client")]
100103
AbsoluteUriRequired,
101104

102105
/// User tried polling for an upgrade that doesn't exist.
@@ -241,6 +244,7 @@ impl Error {
241244
}
242245

243246
#[cfg(any(feature = "http1", feature = "http2"))]
247+
#[cfg(feature = "client")]
244248
pub(crate) fn new_connect<E: Into<Cause>>(cause: E) -> Error {
245249
Error::new(Kind::Connect).with(cause)
246250
}
@@ -273,11 +277,13 @@ impl Error {
273277
}
274278

275279
#[cfg(any(feature = "http1", feature = "http2"))]
280+
#[cfg(feature = "client")]
276281
pub(crate) fn new_user_unsupported_version() -> Error {
277282
Error::new_user(User::UnsupportedVersion)
278283
}
279284

280285
#[cfg(any(feature = "http1", feature = "http2"))]
286+
#[cfg(feature = "client")]
281287
pub(crate) fn new_user_unsupported_request_method() -> Error {
282288
Error::new_user(User::UnsupportedRequestMethod)
283289
}
@@ -288,6 +294,7 @@ impl Error {
288294
}
289295

290296
#[cfg(any(feature = "http1", feature = "http2"))]
297+
#[cfg(feature = "client")]
291298
pub(crate) fn new_user_absolute_uri_required() -> Error {
292299
Error::new_user(User::AbsoluteUriRequired)
293300
}
@@ -371,14 +378,17 @@ impl Error {
371378
#[cfg(feature = "http1")]
372379
Kind::User(User::UnexpectedHeader) => "user sent unexpected header",
373380
#[cfg(any(feature = "http1", feature = "http2"))]
381+
#[cfg(feature = "client")]
374382
Kind::User(User::UnsupportedVersion) => "request has unsupported HTTP version",
375383
#[cfg(any(feature = "http1", feature = "http2"))]
384+
#[cfg(feature = "client")]
376385
Kind::User(User::UnsupportedRequestMethod) => "request has unsupported HTTP method",
377386
#[cfg(feature = "http1")]
378387
Kind::User(User::UnsupportedStatusCode) => {
379388
"response has 1xx status code, not supported by server"
380389
}
381390
#[cfg(any(feature = "http1", feature = "http2"))]
391+
#[cfg(feature = "client")]
382392
Kind::User(User::AbsoluteUriRequired) => "client requires absolute-form URIs",
383393
Kind::User(User::NoUpgrade) => "no upgrade available",
384394
#[cfg(feature = "http1")]

src/headers.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use bytes::BytesMut;
33
use http::header::CONTENT_LENGTH;
44
use http::header::{HeaderValue, ValueIter};
55
#[cfg(feature = "http2")]
6-
use http::method::Method;
6+
#[cfg(feature = "client")]
7+
use http::Method;
78
use http::HeaderMap;
89

910
#[cfg(feature = "http1")]
@@ -65,6 +66,7 @@ pub fn content_length_parse_all_values(values: ValueIter<'_, HeaderValue>) -> Op
6566
}
6667

6768
#[cfg(feature = "http2")]
69+
#[cfg(feature = "client")]
6870
pub fn method_has_defined_payload_semantics(method: &Method) -> bool {
6971
match *method {
7072
Method::GET | Method::HEAD | Method::DELETE | Method::CONNECT => false,

src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,14 @@ pub mod upgrade;
7171
cfg_any_http! {
7272
mod headers;
7373
mod proto;
74-
pub mod client;
7574
pub mod server;
7675

77-
pub use crate::client::Client;
7876
pub use crate::server::Server;
7977
}
78+
79+
cfg_feature! {
80+
#![all(feature = "client", any(feature = "http1", feature = "http2"))]
81+
82+
pub mod client;
83+
pub use crate::client::Client;
84+
}

0 commit comments

Comments
 (0)