From 8321b63982178916b88d7d5619e652e923bcf587 Mon Sep 17 00:00:00 2001 From: Dominic Date: Wed, 20 May 2020 09:01:11 +0200 Subject: [PATCH] tests for the access control request method matcher --- src/matcher/access_control_request_method.rs | 51 +++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/matcher/access_control_request_method.rs b/src/matcher/access_control_request_method.rs index e356c0a..a5e03f2 100644 --- a/src/matcher/access_control_request_method.rs +++ b/src/matcher/access_control_request_method.rs @@ -36,6 +36,10 @@ pub struct AccessControlRequestMethodMatcher impl AccessControlRequestMethodMatcher { + /// Construct a new matcher that matches if the `Access-Control-Request-Method` header matches `method`. + /// Note that during matching the method is normalized according to the fetch specification, that is, + /// byte-uppercased. This means that when using a custom `method` instead of a predefined one, make sure + /// it is uppercased or this matcher will never succeed. pub fn new(method : Method) -> Self { Self { method } @@ -46,12 +50,57 @@ impl RouteMatcher for AccessControlRequestMethodMatcher { fn is_match(&self, state : &State) -> Result<(), RouteNonMatch> { + // according to the fetch specification, methods should be normalized by byte-uppercase + // https://fetch.spec.whatwg.org/#concept-method match HeaderMap::borrow_from(state).get(ACCESS_CONTROL_REQUEST_METHOD) .and_then(|value| value.to_str().ok()) - .and_then(|str| str.parse::().ok()) + .and_then(|str| str.to_ascii_uppercase().parse::().ok()) { Some(m) if m == self.method => Ok(()), _ => Err(RouteNonMatch::new(StatusCode::NOT_FOUND)) } } } + + +#[cfg(test)] +mod test +{ + use super::*; + + fn with_state(accept : Option<&str>, block : F) + where F : FnOnce(&mut State) -> () + { + State::with_new(|state| { + let mut headers = HeaderMap::new(); + if let Some(acc) = accept + { + headers.insert(ACCESS_CONTROL_REQUEST_METHOD, acc.parse().unwrap()); + } + state.put(headers); + block(state); + }); + } + + #[test] + fn no_acrm_header() + { + let matcher = AccessControlRequestMethodMatcher::new(Method::PUT); + with_state(None, |state| assert!(matcher.is_match(&state).is_err())); + } + + #[test] + fn correct_acrm_header() + { + let matcher = AccessControlRequestMethodMatcher::new(Method::PUT); + with_state(Some("PUT"), |state| assert!(matcher.is_match(&state).is_ok())); + with_state(Some("put"), |state| assert!(matcher.is_match(&state).is_ok())); + } + + #[test] + fn incorrect_acrm_header() + { + let matcher = AccessControlRequestMethodMatcher::new(Method::PUT); + with_state(Some("DELETE"), |state| assert!(matcher.is_match(&state).is_err())); + } +}