mirror of
https://github.com/actix/actix-web.git
synced 2024-12-30 03:50:42 +00:00
Re-implement Host predicate (#989)
* update HostGuard implementation * update/add tests for new HostGuard implementation
This commit is contained in:
parent
6b7df6b242
commit
3650f6d7b8
1 changed files with 116 additions and 50 deletions
166
src/guard.rs
166
src/guard.rs
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue