From ace98e3a1e62cdfac4c21e22955c05157e373d35 Mon Sep 17 00:00:00 2001 From: Anton Lazarev Date: Mon, 14 Oct 2019 16:05:54 -0700 Subject: [PATCH] support Host guards when Host header is unset (#1129) --- CHANGES.md | 4 ++++ src/guard.rs | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4ff7d1e6..689ab13d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,10 @@ * Add `Payload::into_inner` method and make stored `def::Payload` public. (#1110) +### Changed + +* Support `Host` guards when the `Host` header is unset (e.g. HTTP/2 requests) (#1129) + ## [1.0.8] - 2019-09-25 ### Added diff --git a/src/guard.rs b/src/guard.rs index c6019258..aad19c8f 100644 --- a/src/guard.rs +++ b/src/guard.rs @@ -276,10 +276,11 @@ pub fn Host>(host: H) -> HostGuard { fn get_host_uri(req: &RequestHead) -> Option { use core::str::FromStr; - let host_value = req.headers.get(header::HOST)?; - let host = host_value.to_str().ok()?; - let uri = Uri::from_str(host).ok()?; - Some(uri) + req.headers.get(header::HOST) + .and_then(|host_value| host_value.to_str().ok()) + .or_else(|| req.uri.host()) + .map(|host: &str| Uri::from_str(host).ok()) + .and_then(|host_success| host_success) } #[doc(hidden)] @@ -400,6 +401,31 @@ mod tests { assert!(!pred.check(req.head())); } + #[test] + fn test_host_without_header() { + let req = TestRequest::default() + .uri("www.rust-lang.org") + .to_http_request(); + + let pred = Host("www.rust-lang.org"); + assert!(pred.check(req.head())); + + let pred = Host("www.rust-lang.org").scheme("https"); + assert!(pred.check(req.head())); + + let pred = Host("blog.rust-lang.org"); + assert!(!pred.check(req.head())); + + let pred = Host("blog.rust-lang.org").scheme("https"); + assert!(!pred.check(req.head())); + + let pred = Host("crates.io"); + assert!(!pred.check(req.head())); + + let pred = Host("localhost"); + assert!(!pred.check(req.head())); + } + #[test] fn test_methods() { let req = TestRequest::default().to_http_request();