Skip to content

Commit

Permalink
Merge branch 'master' into bump-env_logger
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmonstar authored Oct 21, 2024
2 parents 8cf6147 + aba01ff commit 10ca3d2
Show file tree
Hide file tree
Showing 20 changed files with 534 additions and 119 deletions.
7 changes: 2 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,12 @@ jobs:

include:
- name: linux / stable
test-features: "--features __internal_proxy_sys_no_cache"
- name: linux / beta
rust: beta
test-features: "--features __internal_proxy_sys_no_cache"
# - name: linux / nightly
# rust: nightly
# test-features: "--features __internal_proxy_sys_no_cache"
- name: macOS / stable
os: macOS-latest
test-features: "--features __internal_proxy_sys_no_cache"

- name: windows / stable-x86_64-msvc
os: windows-latest
Expand Down Expand Up @@ -272,7 +268,7 @@ jobs:
run: |
cargo clean
cargo update -Z minimal-versions
cargo update -p proc-macro2 --precise 1.0.60
cargo update -p proc-macro2 --precise 1.0.87
cargo check
cargo check --all-features
Expand Down Expand Up @@ -300,6 +296,7 @@ jobs:
cargo update
cargo update -p log --precise 0.4.21
cargo update -p tokio --precise 1.29.1
cargo update -p tokio-util --precise 0.7.11
cargo update -p url --precise 2.5.0
- uses: Swatinem/rust-cache@v2
Expand Down
21 changes: 19 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
## Unreleased
## v0.12.8

- Implement `danger_accept_invalid_hostnames` for `rustls`.
- Add support for SOCKS4 proxies.
- Add `multipart::Form::file()` method for adding files easily.
- Add `Body::wrap()` to wrap any `http_body::Body` type.
- Fix the pool configuration to use a timer to remove expired connections.


## v0.12.7

- Revert adding `impl Service<http::Request<_>>` for `Client`.

## v0.12.6

- Add support for `danger_accept_invalid_hostnames` for `rustls`.
- Add `impl Service<http::Request<Body>>` for `Client` and `&'_ Client`.
- Add support for `!Sync` bodies in `Body::wrap_stream()`.
- Enable happy eyeballs when `hickory-dns` is used.
- Fix `Proxy` so that `HTTP(S)_PROXY` values take precendence over `ALL_PROXY`.
- Fix `blocking::RequestBuilder::header()` from unsetting `sensitive` on passed header values.

## v0.12.5

Expand Down
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "reqwest"
version = "0.12.5"
version = "0.12.8"
description = "higher level HTTP client library"
keywords = ["http", "request", "client"]
categories = ["web-programming::http-client", "wasm"]
Expand Down Expand Up @@ -143,7 +143,7 @@ rustls = { version = "0.23.4", optional = true, default-features = false, featur
rustls-pki-types = { version = "1.1.0", features = ["alloc"] ,optional = true }
tokio-rustls = { version = "0.26", optional = true, default-features = false, features = ["tls12"] }
webpki-roots = { version = "0.26.0", optional = true }
rustls-native-certs = { version = "0.7", optional = true }
rustls-native-certs = { version = "0.8.0", optional = true }

## cookies
cookie_crate = { version = "0.18.0", package = "cookie", optional = true }
Expand All @@ -154,7 +154,7 @@ async-compression = { version = "0.4.0", default-features = false, features = ["
tokio-util = { version = "0.7.9", default-features = false, features = ["codec", "io"], optional = true }

## socks
tokio-socks = { version = "0.5.1", optional = true }
tokio-socks = { version = "0.5.2", optional = true }

## hickory-dns
hickory-resolver = { version = "0.24", optional = true, features = ["tokio-runtime"] }
Expand All @@ -172,7 +172,7 @@ env_logger = "0.11"
hyper = { version = "1.1.0", default-features = false, features = ["http1", "http2", "client", "server"] }
hyper-util = { version = "0.1.3", features = ["http1", "http2", "client", "client-legacy", "server-auto", "tokio"] }
serde = { version = "1.0", features = ["derive"] }
libflate = "1.0"
libflate = "2.1"
brotli_crate = { package = "brotli", version = "6.0.0" }
zstd_crate = { package = "zstd", version = "0.13" }
doc-comment = "0.3"
Expand All @@ -184,14 +184,14 @@ rustls = { version = "0.23", default-features = false, features = ["ring"] }
windows-registry = "0.2"

[target.'cfg(target_os = "macos")'.dependencies]
system-configuration = { version = "0.5.1", optional = true }
system-configuration = { version = "0.6.0", optional = true }

# wasm

[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3.45"
serde_json = "1.0"
wasm-bindgen = "0.2.68"
wasm-bindgen = "0.2.89"
wasm-bindgen-futures = "0.4.18"
wasm-streams = { version = "0.4", optional = true }

Expand All @@ -216,7 +216,7 @@ features = [
]

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen = { version = "0.2.68", features = ["serde-serialize"] }
wasm-bindgen = { version = "0.2.89", features = ["serde-serialize"] }
wasm-bindgen-test = "0.3"

[lints.rust]
Expand Down
29 changes: 15 additions & 14 deletions src/async_impl/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,6 @@ impl Body {
}
}

/*
#[cfg(feature = "blocking")]
pub(crate) fn wrap(body: hyper::Body) -> Body {
Body {
inner: Inner::Streaming {
body: Box::pin(WrapHyper(body)),
},
}
}
*/

pub(crate) fn empty() -> Body {
Body::reusable(Bytes::new())
}
Expand All @@ -138,8 +127,20 @@ impl Body {
}
}

// pub?
pub(crate) fn streaming<B>(inner: B) -> Body
/// Wrap a [`HttpBody`] in a box inside `Body`.
///
/// # Example
///
/// ```
/// # use reqwest::Body;
/// # use futures_util;
/// # fn main() {
/// let content = "hello,world!".to_string();
///
/// let body = Body::wrap(content);
/// # }
/// ```
pub fn wrap<B>(inner: B) -> Body
where
B: HttpBody + Send + Sync + 'static,
B::Data: Into<Bytes>,
Expand Down Expand Up @@ -483,7 +484,7 @@ mod tests {
assert!(!bytes_body.is_end_stream());
assert_eq!(bytes_body.size_hint().exact(), Some(3));

let stream_body = Body::streaming(bytes_body);
let stream_body = Body::wrap(bytes_body);
assert!(!stream_body.is_end_stream());
assert_eq!(stream_body.size_hint().exact(), None);
}
Expand Down
119 changes: 86 additions & 33 deletions src/async_impl/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ use crate::dns::{gai::GaiResolver, DnsResolverWithOverrides, DynResolver, Resolv
use crate::error;
use crate::into_url::try_uri;
use crate::redirect::{self, remove_sensitive_headers};
#[cfg(feature = "__rustls")]
use crate::tls::CertificateRevocationList;
#[cfg(feature = "__tls")]
use crate::tls::{self, TlsBackend};
#[cfg(feature = "__tls")]
Expand Down Expand Up @@ -118,6 +120,8 @@ struct Config {
tls_built_in_certs_webpki: bool,
#[cfg(feature = "rustls-tls-native-roots")]
tls_built_in_certs_native: bool,
#[cfg(feature = "__rustls")]
crls: Vec<CertificateRevocationList>,
#[cfg(feature = "__tls")]
min_tls_version: Option<tls::Version>,
#[cfg(feature = "__tls")]
Expand Down Expand Up @@ -217,6 +221,8 @@ impl ClientBuilder {
tls_built_in_certs_native: true,
#[cfg(any(feature = "native-tls", feature = "__rustls"))]
identity: None,
#[cfg(feature = "__rustls")]
crls: vec![],
#[cfg(feature = "__tls")]
min_tls_version: None,
#[cfg(feature = "__tls")]
Expand Down Expand Up @@ -514,9 +520,9 @@ impl ClientBuilder {
if config.tls_built_in_certs_native {
let mut valid_count = 0;
let mut invalid_count = 0;
for cert in rustls_native_certs::load_native_certs()
.map_err(crate::error::builder)?
{

let load_results = rustls_native_certs::load_native_certs();
for cert in load_results.certs {
// Continue on parsing errors, as native stores often include ancient or syntactically
// invalid certificates, like root certificates without any X509 extensions.
// Inspiration: https://github.com/rustls/rustls/blob/633bf4ba9d9521a95f68766d04c22e2b01e68318/rustls/src/anchors.rs#L105-L112
Expand All @@ -529,9 +535,21 @@ impl ClientBuilder {
}
}
if valid_count == 0 && invalid_count > 0 {
return Err(crate::error::builder(
"zero valid certificates found in native root store",
));
let err = if load_results.errors.is_empty() {
crate::error::builder(
"zero valid certificates found in native root store",
)
} else {
use std::fmt::Write as _;
let mut acc = String::new();
for err in load_results.errors {
let _ = writeln!(&mut acc, "{err}");
}

crate::error::builder(acc)
};

return Err(err);
}
}

Expand Down Expand Up @@ -576,9 +594,10 @@ impl ClientBuilder {

// Build TLS config
let signature_algorithms = provider.signature_verification_algorithms;
let config_builder = rustls::ClientConfig::builder_with_provider(provider)
.with_protocol_versions(&versions)
.map_err(|_| crate::error::builder("invalid TLS versions"))?;
let config_builder =
rustls::ClientConfig::builder_with_provider(provider.clone())
.with_protocol_versions(&versions)
.map_err(|_| crate::error::builder("invalid TLS versions"))?;

let config_builder = if !config.certs_verification {
config_builder
Expand All @@ -592,7 +611,26 @@ impl ClientBuilder {
signature_algorithms,
)))
} else {
config_builder.with_root_certificates(root_cert_store)
if config.crls.is_empty() {
config_builder.with_root_certificates(root_cert_store)
} else {
let crls = config
.crls
.iter()
.map(|e| e.as_rustls_crl())
.collect::<Vec<_>>();
let verifier =
rustls::client::WebPkiServerVerifier::builder_with_provider(
Arc::new(root_cert_store),
provider,
)
.with_crls(crls)
.build()
.map_err(|_| {
crate::error::builder("invalid TLS verification settings")
})?;
config_builder.with_webpki_verifier(verifier)
}
};

// Finalize TLS config
Expand Down Expand Up @@ -714,8 +752,8 @@ impl ClientBuilder {
}
}

#[cfg(not(target_arch = "wasm32"))]
builder.timer(hyper_util::rt::TokioTimer::new());
builder.pool_timer(hyper_util::rt::TokioTimer::new());
builder.pool_idle_timeout(config.pool_idle_timeout);
builder.pool_max_idle_per_host(config.pool_max_idle_per_host);
connector.set_keepalive(config.tcp_keepalive);
Expand Down Expand Up @@ -1394,6 +1432,35 @@ impl ClientBuilder {
self
}

/// Add a certificate revocation list.
///
///
/// # Optional
///
/// This requires the `rustls-tls(-...)` Cargo feature enabled.
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))]
pub fn add_crl(mut self, crl: CertificateRevocationList) -> ClientBuilder {
self.config.crls.push(crl);
self
}

/// Add multiple certificate revocation lists.
///
///
/// # Optional
///
/// This requires the `rustls-tls(-...)` Cargo feature enabled.
#[cfg(feature = "__rustls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))]
pub fn add_crls(
mut self,
crls: impl IntoIterator<Item = CertificateRevocationList>,
) -> ClientBuilder {
self.config.crls.extend(crls);
self
}

/// Controls the use of built-in/preloaded certificates during certificate validation.
///
/// Defaults to `true` -- built-in system certs will be used.
Expand Down Expand Up @@ -1720,14 +1787,7 @@ impl ClientBuilder {
self
}

/// Enables the [hickory-dns](hickory_resolver) async resolver instead of a default threadpool
/// using `getaddrinfo`.
///
/// If the `hickory-dns` feature is turned on, the default option is enabled.
///
/// # Optional
///
/// This requires the optional `hickory-dns` feature to be enabled
#[doc(hidden)]
#[cfg(feature = "hickory-dns")]
#[cfg_attr(docsrs, doc(cfg(feature = "hickory-dns")))]
#[deprecated(note = "use `hickory_dns` instead")]
Expand All @@ -1744,29 +1804,22 @@ impl ClientBuilder {
/// # Optional
///
/// This requires the optional `hickory-dns` feature to be enabled
///
/// # Warning
///
/// The hickory resolver does not work exactly the same, or on all the platforms
/// that the default resolver does
#[cfg(feature = "hickory-dns")]
#[cfg_attr(docsrs, doc(cfg(feature = "hickory-dns")))]
pub fn hickory_dns(mut self, enable: bool) -> ClientBuilder {
self.config.hickory_dns = enable;
self
}

/// Disables the hickory-dns async resolver.
///
/// This method exists even if the optional `hickory-dns` feature is not enabled.
/// This can be used to ensure a `Client` doesn't use the hickory-dns async resolver
/// even if another dependency were to enable the optional `hickory-dns` feature.
#[doc(hidden)]
#[deprecated(note = "use `no_hickory_dns` instead")]
pub fn no_trust_dns(self) -> ClientBuilder {
#[cfg(feature = "hickory-dns")]
{
self.hickory_dns(false)
}

#[cfg(not(feature = "hickory-dns"))]
{
self
}
self.no_hickory_dns()
}

/// Disables the hickory-dns async resolver.
Expand Down
Loading

0 comments on commit 10ca3d2

Please sign in to comment.