1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +01:00

Re-implement Host predicate (#989)

* update HostGuard implementation

* update/add tests for new HostGuard implementation
This commit is contained in:
Anton Lazarev 2019-07-18 21:28:43 -07:00 committed by Nikolay Kim
parent 6b7df6b242
commit 3650f6d7b8

View File

@ -26,7 +26,7 @@
//! ``` //! ```
#![allow(non_snake_case)] #![allow(non_snake_case)]
use actix_http::http::{self, header, HttpTryFrom}; use actix_http::http::{self, header, HttpTryFrom, uri::Uri};
use actix_http::RequestHead; use actix_http::RequestHead;
/// Trait defines resource guards. Guards are used for routes selection. /// Trait defines resource guards. Guards are used for routes selection.
@ -256,45 +256,68 @@ impl Guard for HeaderGuard {
} }
} }
// /// Return predicate that matches if request contains specified Host name. /// Return predicate that matches if request contains specified Host name.
// /// ///
// /// ```rust,ignore /// ```rust,ignore
// /// # extern crate actix_web; /// # extern crate actix_web;
// /// use actix_web::{pred, App, HttpResponse}; /// use actix_web::{guard::Host, App, HttpResponse};
// /// ///
// /// fn main() { /// fn main() {
// /// App::new().resource("/index.html", |r| { /// App::new().resource("/index.html", |r| {
// /// r.route() /// r.route()
// /// .guard(pred::Host("www.rust-lang.org")) /// .guard(Host("www.rust-lang.org"))
// /// .f(|_| HttpResponse::MethodNotAllowed()) /// .f(|_| HttpResponse::MethodNotAllowed())
// /// }); /// });
// /// } /// }
// /// ``` /// ```
// pub fn Host<H: AsRef<str>>(host: H) -> HostGuard { pub fn Host<H: AsRef<str>>(host: H) -> HostGuard {
// HostGuard(host.as_ref().to_string(), None) HostGuard(host.as_ref().to_string(), None)
// } }
// #[doc(hidden)] fn get_host_uri(req: &RequestHead) -> Option<Uri> {
// pub struct HostGuard(String, Option<String>); 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)
}
// impl HostGuard { #[doc(hidden)]
// /// Set reuest scheme to match pub struct HostGuard(String, Option<String>);
// pub fn scheme<H: AsRef<str>>(&mut self, scheme: H) {
// self.1 = Some(scheme.as_ref().to_string())
// }
// }
// impl Guard for HostGuard { impl HostGuard {
// fn check(&self, _req: &RequestHead) -> bool { /// Set request scheme to match
// // let info = req.connection_info(); pub fn scheme<H: AsRef<str>>(mut self, scheme: H) -> HostGuard {
// // if let Some(ref scheme) = self.1 { self.1 = Some(scheme.as_ref().to_string());
// // self.0 == info.host() && scheme == info.scheme() self
// // } else { }
// // self.0 == info.host() }
// // }
// false impl Guard for HostGuard {
// } fn check(&self, req: &RequestHead) -> bool {
// } let req_host_uri = if let Some(uri) = get_host_uri(req) {
uri
} else {
return false;
};
if let Some(uri_host) = req_host_uri.host() {
if self.0 != uri_host {
return false;
}
} else {
return false;
}
if let Some(ref scheme) = self.1 {
if let Some(ref req_host_uri_scheme) = req_host_uri.scheme_str() {
return scheme == req_host_uri_scheme;
}
}
true
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@ -318,21 +341,64 @@ mod tests {
assert!(!pred.check(req.head())); assert!(!pred.check(req.head()));
} }
// #[test] #[test]
// fn test_host() { fn test_host() {
// let req = TestServiceRequest::default() let req = TestRequest::default()
// .header( .header(
// header::HOST, header::HOST,
// header::HeaderValue::from_static("www.rust-lang.org"), header::HeaderValue::from_static("www.rust-lang.org"),
// ) )
// .request(); .to_http_request();
// let pred = Host("www.rust-lang.org"); let pred = Host("www.rust-lang.org");
// assert!(pred.check(&req)); assert!(pred.check(req.head()));
// let pred = Host("localhost"); let pred = Host("www.rust-lang.org").scheme("https");
// assert!(!pred.check(&req)); 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_host_scheme() {
let req = TestRequest::default()
.header(
header::HOST,
header::HeaderValue::from_static("https://www.rust-lang.org"),
)
.to_http_request();
let pred = Host("www.rust-lang.org").scheme("https");
assert!(pred.check(req.head()));
let pred = Host("www.rust-lang.org");
assert!(pred.check(req.head()));
let pred = Host("www.rust-lang.org").scheme("http");
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").scheme("https");
assert!(!pred.check(req.head()));
let pred = Host("localhost");
assert!(!pred.check(req.head()));
}
#[test] #[test]
fn test_methods() { fn test_methods() {