Skip to content

Commit 63dc4f8

Browse files
committed
Fix https_only/enforce_https enforcement
1 parent 1b7d8cf commit 63dc4f8

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ hyper-util = { version = "0.1", default-features = false, features = ["server-au
4343
rustls = { version = "0.23", default-features = false, features = ["tls12"] }
4444
rustls-pemfile = "2"
4545
tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] }
46+
tower = { version = "0.5.2", default-features = false, features = ["util"] }
4647

4748
[[example]]
4849
name = "client"

src/connector.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ where
6969
// dst.scheme() would need to derive Eq to be matchable;
7070
// use an if cascade instead
7171
match dst.scheme() {
72-
Some(scheme) if scheme == &http::uri::Scheme::HTTP => {
72+
Some(scheme) if scheme == &http::uri::Scheme::HTTP && !self.force_https => {
7373
let future = self.http.call(dst);
7474
return Box::pin(async move {
7575
Ok(MaybeHttpsStream::Http(future.await.map_err(Into::into)?))
@@ -199,3 +199,74 @@ pub trait ResolveServerName {
199199
uri: &Uri,
200200
) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>>;
201201
}
202+
203+
#[cfg(test)]
204+
mod tests {
205+
use http::Uri;
206+
use hyper_util::client::legacy::connect::HttpConnector;
207+
use tower::ServiceExt;
208+
209+
use super::HttpsConnector;
210+
use crate::HttpsConnectorBuilder;
211+
212+
fn https_or_http_connector() -> HttpsConnector<HttpConnector> {
213+
HttpsConnectorBuilder::new()
214+
.with_native_roots()
215+
.unwrap()
216+
.https_or_http()
217+
.enable_http1()
218+
.build()
219+
}
220+
221+
fn https_only_connector() -> HttpsConnector<HttpConnector> {
222+
HttpsConnectorBuilder::new()
223+
.with_native_roots()
224+
.unwrap()
225+
.https_only()
226+
.enable_http1()
227+
.build()
228+
}
229+
230+
fn https_uri() -> Uri {
231+
Uri::from_static("https://google.com")
232+
}
233+
234+
fn http_uri() -> Uri {
235+
Uri::from_static("http://google.com")
236+
}
237+
238+
#[tokio::test]
239+
async fn connects_https() {
240+
https_or_http_connector()
241+
.oneshot(https_uri())
242+
.await
243+
.unwrap();
244+
}
245+
246+
#[tokio::test]
247+
async fn connects_http() {
248+
https_or_http_connector()
249+
.oneshot(http_uri())
250+
.await
251+
.unwrap();
252+
}
253+
254+
#[tokio::test]
255+
async fn connects_https_only() {
256+
https_only_connector()
257+
.oneshot(https_uri())
258+
.await
259+
.unwrap();
260+
}
261+
262+
#[tokio::test]
263+
async fn enforces_https_only() {
264+
let message = https_only_connector()
265+
.oneshot(http_uri())
266+
.await
267+
.unwrap_err()
268+
.to_string();
269+
270+
assert_eq!(message, "unsupported scheme http");
271+
}
272+
}

0 commit comments

Comments
 (0)