From e0762b1e473f4b5a921df627561cdf5f6608b790 Mon Sep 17 00:00:00 2001 From: Peng Guanwen Date: Wed, 30 Dec 2020 11:53:01 +0800 Subject: [PATCH 1/4] Squashed commit of the following: commit 565151b90499cf6c54961d8d6d62ffe787d0b097 Merge: 020af513 549c9241 Author: Lorran Rosa Date: Fri Aug 7 07:31:20 2020 -0300 Merge branch 'master' of https://github.com/SergioBenitez/Rocket commit 020af513efb2ab70f1b0d4544c98008ea972c982 Author: Lorran Rosa Date: Fri Aug 7 07:13:11 2020 -0300 Removed extra comments commit a6ad90f1d5a73123924b8e05bd4413ee71e8c273 Author: Lorran Rosa Date: Fri Jul 3 10:17:55 2020 -0300 Added description to `restrict` param at Router.route commit f288f8d2982c15f0644f557c008265039c8b5563 Author: Lorran Rosa Date: Fri Jul 3 10:17:03 2020 -0300 Fix formatting in Rocket.route commit 197f8ee6609870821906b8cf11c38e604816633f Author: Lorran Rosa Date: Fri Jul 3 09:36:33 2020 -0300 Simplified the logic at Rocket.route commit 13b6386b90d11411c439c63678223ecfb9f7a99b Author: Lorran Rosa Date: Tue Jun 23 18:06:47 2020 -0300 [WIP] Passing the logic to the router and performance corrections commit 4c3e516977a1821ae49d5b314c3a7b053e090605 Merge: d3ba36ee 63a4ae04 Author: Lorran Rosa Date: Thu Jun 11 10:41:58 2020 -0300 Merge branch 'master' into master commit d3ba36eec1b594ecfb761d70ecaefa989c5875bf Author: Lorran Rosa Date: Thu Jun 11 10:39:36 2020 -0300 Now code formatting is as it was commit ad0e9efad5185c368633f4155879ec7b241ef09f Author: Lorran Rosa Date: Thu Jun 11 10:34:46 2020 -0300 More code changes removals commit e75ab5e02ae795013864bf468def11ce5e85df20 Author: Lorran Rosa Date: Thu Jun 11 10:14:10 2020 -0300 Remove format changes commit 12ee5d8421721203d25b562de8e38f7afaeb2481 Merge: 71abd120 1010f6a2 Author: Lorran Rosa Date: Wed Apr 22 20:26:38 2020 -0300 Merge branch 'master' of https://github.com/SergioBenitez/Rocket commit 71abd1204eec126ff5f0890ea63237d6b1d76b55 Author: Lorran Rosa Date: Fri Apr 17 23:08:29 2020 -0300 Code formatting commit 5d526c865228cebe70bae59d78a1a267f10a6583 Author: Lorran Rosa Date: Fri Apr 17 23:03:43 2020 -0300 After 2 freaking days I think finally finished fixing these tests lol commit ef171cc862c52f22c75d41b8f5192ca8250bf88f Author: Lorran Rosa Date: Wed Apr 15 23:09:09 2020 -0300 To find a matching 405 template to test_root commit 42b4a14151452d337d7c22e08534a0eeb01f502c Author: Lorran Rosa Date: Wed Apr 15 23:05:33 2020 -0300 Update tests commit cd57e4749a77a50ff7d9394abc99283ead136364 Author: Lorran Rosa Date: Wed Apr 15 23:04:49 2020 -0300 Fix route not interating in all matches. commit 684d4d4cb3163c60136f0726f79ac8e6188fde1c Author: Lorran Rosa Date: Wed Apr 15 08:54:27 2020 -0300 Code formatting, no additions.. commit 36544ba2cd5c225273c6d4656b5c1be543a511cb Author: Lorran Rosa Date: Wed Apr 15 08:50:41 2020 -0300 Code formatting using rustfmt commit 1d4243363d4058f7f8d0cf73d7d35d619c2b0099 Author: Lorran Rosa Date: Wed Apr 15 08:38:00 2020 -0300 Tests commit d93b4b199093f00aef36e79ffef9443023e643c1 Author: Lorran Rosa Date: Wed Apr 15 08:22:59 2020 -0300 Fixing form tests commit 10d143ef28f460790aa646859d8b770efa375184 Author: Lorran Rosa Date: Wed Apr 15 08:22:39 2020 -0300 Checking if requests method matches with route method. commit ddc59f563eeb39f1f0ffc047480093a064a03bcc Author: Lorran Rosa Date: Wed Apr 15 08:21:14 2020 -0300 Removed matching with request_status commit 1cc49ff46c6aa01c63a468d1d7625b26a2880721 Author: Lorran Rosa Date: Tue Apr 14 08:34:54 2020 -0300 Returning 405 if http method doesn't match --- core/codegen/tests/route-format.rs | 2 +- core/lib/src/router/collider.rs | 17 ++- core/lib/src/router/mod.rs | 49 +++++---- core/lib/src/server.rs | 25 ++++- core/lib/tests/form_method-issue-45.rs | 2 +- .../return_method_not_allowed_issue_1224.rs | 103 ++++++++++++++++++ examples/errors/src/tests.rs | 2 +- examples/handlebars_templates/src/tests.rs | 7 +- .../templates/error/405.hbs | 17 +++ examples/tera_templates/src/tests.rs | 8 +- .../templates/error/405.html.tera | 17 +++ 11 files changed, 213 insertions(+), 36 deletions(-) create mode 100644 core/lib/tests/return_method_not_allowed_issue_1224.rs create mode 100644 examples/handlebars_templates/templates/error/405.hbs create mode 100644 examples/tera_templates/templates/error/405.html.tera diff --git a/core/codegen/tests/route-format.rs b/core/codegen/tests/route-format.rs index 1c991b84fc..d43e8a15d7 100644 --- a/core/codegen/tests/route-format.rs +++ b/core/codegen/tests/route-format.rs @@ -61,7 +61,7 @@ fn test_formats() { assert_eq!(response.into_string().unwrap(), "plain"); let response = client.put("/").header(ContentType::HTML).dispatch(); - assert_eq!(response.status(), Status::NotFound); + assert_eq!(response.status(), Status::MethodNotAllowed); } // Test custom formats. diff --git a/core/lib/src/router/collider.rs b/core/lib/src/router/collider.rs index df343a85b6..9767db5cf4 100644 --- a/core/lib/src/router/collider.rs +++ b/core/lib/src/router/collider.rs @@ -25,7 +25,7 @@ impl Route { && formats_collide(self, other) } - /// Determines if this route matches against the given request. This means + /// Determines if this route matches against the given request if . This means /// that: /// /// * The route's method matches that of the incoming request. @@ -38,12 +38,19 @@ impl Route { /// request query string, though in any position. /// - If no query in route, requests with/without queries match. #[doc(hidden)] - pub fn matches(&self, req: &Request<'_>) -> bool { + pub fn matches_by_method(&self, req: &Request<'_>) -> bool { self.method == req.method() && paths_match(self, req) - && queries_match(self, req) + && queries_match(self, req) && formats_match(self, req) } + + /// Match agoinst any method. + #[doc(hidden)] + pub fn match_any(&self, req: &Request<'_>) -> bool { + paths_match(self, req) && queries_match(self, req) && formats_match(self, req) + } + } fn paths_collide(route: &Route, other: &Route) -> bool { @@ -416,7 +423,7 @@ mod tests { route.format = Some(mt_str.parse::().unwrap()); } - route.matches(&req) + route.matches_by_method(&req) } #[test] @@ -471,7 +478,7 @@ mod tests { let rocket = Rocket::custom(Config::default()); let req = Request::new(&rocket, Get, Origin::parse(a).expect("valid URI")); let route = Route::ranked(0, Get, b.to_string(), dummy); - route.matches(&req) + route.matches_by_method(&req) } #[test] diff --git a/core/lib/src/router/mod.rs b/core/lib/src/router/mod.rs index 8538394395..9dfbd50418 100644 --- a/core/lib/src/router/mod.rs +++ b/core/lib/src/router/mod.rs @@ -17,6 +17,7 @@ pub struct Router { routes: HashMap>, } + impl Router { pub fn new() -> Router { Router { routes: HashMap::new() } @@ -31,15 +32,26 @@ impl Router { entries.insert(i, route); } - pub fn route<'b>(&'b self, req: &Request<'_>) -> Vec<&'b Route> { - // Note that routes are presorted by rank on each `add`. - let matches = self.routes.get(&req.method()).map_or(vec![], |routes| { - routes.iter() - .filter(|r| r.matches(req)) - .collect() - }); + // Param `restrict` will restrict the route matching by the http method of `req` + // With `restrict` == false and `req` method == GET both will be matched: + // - GET hello/world <- + // - POST hello/world <- + // With `restrict` == true and `req` method == GET only the first one will be matched: + // - GET foo/bar <- + // - POST foo/bar + pub fn route<'b>(&'b self, req: &Request<'_>, restrict: bool) -> Vec<&'b Route> { + let mut matches = Vec::new(); + for (_method, routes_vec) in self.routes.iter() { + for _route in routes_vec { + if _route.matches_by_method(req) { + matches.push(_route); + } else if !restrict && _route.match_any(req){ + matches.push(_route); + } + } + } - trace_!("Routing the request: {}", req); + trace_!("Routing(restrict: {}): {}", &restrict, req); trace_!("All matches: {:?}", matches); matches } @@ -245,7 +257,7 @@ mod test { fn route<'a>(router: &'a Router, method: Method, uri: &str) -> Option<&'a Route> { let rocket = Rocket::custom(Config::default()); let request = Request::new(&rocket, method, Origin::parse(uri).unwrap()); - let matches = router.route(&request); + let matches = router.route(&request, false); if matches.len() > 0 { Some(matches[0]) } else { @@ -256,7 +268,7 @@ mod test { fn matches<'a>(router: &'a Router, method: Method, uri: &str) -> Vec<&'a Route> { let rocket = Rocket::custom(Config::default()); let request = Request::new(&rocket, method, Origin::parse(uri).unwrap()); - router.route(&request) + router.route(&request, false) } #[test] @@ -294,9 +306,9 @@ mod test { #[test] fn test_err_routing() { let router = router_with_routes(&["/hello"]); - assert!(route(&router, Put, "/hello").is_none()); - assert!(route(&router, Post, "/hello").is_none()); - assert!(route(&router, Options, "/hello").is_none()); + assert!(route(&router, Put, "/hello").is_some()); + assert!(route(&router, Post, "/hello").is_some()); + assert!(route(&router, Options, "/hello").is_some()); assert!(route(&router, Get, "/hell").is_none()); assert!(route(&router, Get, "/hi").is_none()); assert!(route(&router, Get, "/hello/there").is_none()); @@ -304,20 +316,19 @@ mod test { assert!(route(&router, Get, "/hillo").is_none()); let router = router_with_routes(&["/"]); - assert!(route(&router, Put, "/hello").is_none()); - assert!(route(&router, Post, "/hello").is_none()); - assert!(route(&router, Options, "/hello").is_none()); + assert!(route(&router, Put, "/hello").is_some()); + assert!(route(&router, Post, "/hello").is_some()); + assert!(route(&router, Options, "/hello").is_some()); assert!(route(&router, Get, "/hello/there").is_none()); assert!(route(&router, Get, "/hello/i").is_none()); let router = router_with_routes(&["//"]); + assert!(route(&router, Put, "/a/b").is_some()); + assert!(route(&router, Put, "/hello/hi").is_some()); assert!(route(&router, Get, "/a/b/c").is_none()); assert!(route(&router, Get, "/a").is_none()); assert!(route(&router, Get, "/a/").is_none()); assert!(route(&router, Get, "/a/b/c/d").is_none()); - assert!(route(&router, Put, "/hello/hi").is_none()); - assert!(route(&router, Put, "/a/b").is_none()); - assert!(route(&router, Put, "/a/b").is_none()); } macro_rules! assert_ranked_routes { diff --git a/core/lib/src/server.rs b/core/lib/src/server.rs index b4ed0687e1..712498242e 100644 --- a/core/lib/src/server.rs +++ b/core/lib/src/server.rs @@ -263,10 +263,11 @@ impl Rocket { ) -> impl Future> + 's { async move { // Go through the list of matching routes until we fail or succeed. - let matches = self.router.route(request); - for route in matches { + let method_matches = self.router.route(request, true); + for route in method_matches { // Retrieve and set the requests parameters. info_!("Matched: {}", route); + request.set_route(route); // Dispatch the request to the handler. @@ -283,7 +284,25 @@ impl Rocket { } error_!("No matching routes for {}.", request); - Outcome::Forward(data) + + // Find if a similar route exists + let match_any = self.router.route(request, false); + + if match_any.len() > 0 { + info_!("{}", Paint::yellow("A similar route exists: ").bold()); + for route in match_any { + info_!(" - {}", Paint::yellow(&route).bold()); + // Must pass HEAD requests foward + if &request.method() == &Method::Head { + continue; + } + if &request.method() != &route.method { + return Outcome::Failure(Status::MethodNotAllowed); + } + } + } + + Outcome::forward(data) } } diff --git a/core/lib/tests/form_method-issue-45.rs b/core/lib/tests/form_method-issue-45.rs index c60b5224e1..adbbb525cf 100644 --- a/core/lib/tests/form_method-issue-45.rs +++ b/core/lib/tests/form_method-issue-45.rs @@ -37,6 +37,6 @@ mod tests { .body("_method=patch&form_data=Form+data") .dispatch(); - assert_eq!(response.status(), Status::NotFound); + assert_eq!(response.status(), Status::MethodNotAllowed); } } diff --git a/core/lib/tests/return_method_not_allowed_issue_1224.rs b/core/lib/tests/return_method_not_allowed_issue_1224.rs new file mode 100644 index 0000000000..abb1691ccc --- /dev/null +++ b/core/lib/tests/return_method_not_allowed_issue_1224.rs @@ -0,0 +1,103 @@ +#![feature(proc_macro_hygiene)] + +#[macro_use] +extern crate rocket; + +#[get("/index")] +fn get_index() -> &'static str { + "GET index :)" +} + +#[post("/index")] +fn post_index() -> &'static str { + "POST index :)" +} + +#[post("/hello")] +fn post_hello() -> &'static str { + "POST Hello, world!" +} + +mod tests { + use super::*; + use rocket::http::Status; + use rocket::local::Client; + + #[test] + fn test_http_200_when_same_route_with_diff_meth() { + let rocket = rocket::ignite() + .mount("/", routes![get_index, post_index]); + + let client = Client::new(rocket).unwrap(); + + let response = client.post("/index").dispatch(); + + assert_eq!(response.status(), Status::Ok); + } + + #[test] + fn test_http_200_when_head_request() { + let rocket = rocket::ignite().mount("/", routes![get_index]); + + let client = Client::new(rocket).unwrap(); + + let response = client.head("/index").dispatch(); + + assert_eq!(response.status(), Status::Ok); + } + + #[test] + fn test_http_200_when_route_is_ok() { + let rocket = rocket::ignite().mount("/", routes![get_index]); + + let client = Client::new(rocket).unwrap(); + + let response = client.get("/index").dispatch(); + + assert_eq!(response.status(), Status::Ok); + } + + #[test] + fn test_http_200_with_params() { + let rocket = rocket::ignite().mount("/", routes![get_index]); + + let client = Client::new(rocket).unwrap(); + + let response = client.get("/index?say=hi").dispatch(); + + assert_eq!(response.status(), Status::Ok); + } + + #[test] + fn test_http_404_when_route_not_match() { + let rocket = rocket::ignite().mount("/", routes![get_index]); + + let client = Client::new(rocket).unwrap(); + + let response = client.get("/abc").dispatch(); + + assert_eq!(response.status(), Status::NotFound); + } + + #[test] + fn test_http_405_when_method_not_match() { + let rocket = rocket::ignite().mount("/", routes![get_index]); + + let client = Client::new(rocket).unwrap(); + + let response = client.post("/index").dispatch(); + + assert_eq!(response.status(), Status::MethodNotAllowed); + } + + #[test] + fn test_http_405_with_params() { + let rocket = rocket::ignite().mount("/", routes![post_hello]); + + let client = Client::new(rocket).unwrap(); + + let response = client.get("/hello?say=hi").dispatch(); + + assert_eq!(response.status(), Status::MethodNotAllowed); + } +} diff --git a/examples/errors/src/tests.rs b/examples/errors/src/tests.rs index 7d5e6c244a..18dda016f2 100644 --- a/examples/errors/src/tests.rs +++ b/examples/errors/src/tests.rs @@ -46,7 +46,7 @@ fn forced_error_and_default_catcher() { fn test_hello_invalid_age() { let client = Client::tracked(super::rocket()).unwrap(); - for &(name, age) in &[("Ford", -129), ("Trillian", 128)] { + for &(name, age) in &[("Ford", "s"), ("Trillian", "f")] { let request = client.get(format!("/hello/{}/{}", name, age)); let expected = super::not_found(request.inner()); let response = request.dispatch(); diff --git a/examples/handlebars_templates/src/tests.rs b/examples/handlebars_templates/src/tests.rs index 998a364a5d..f3801c238e 100644 --- a/examples/handlebars_templates/src/tests.rs +++ b/examples/handlebars_templates/src/tests.rs @@ -31,10 +31,11 @@ fn test_root() { dispatch!(*method, "/", |client, response| { let mut map = std::collections::HashMap::new(); map.insert("path", "/"); - let expected = Template::show(client.rocket(), "error/404", &map).unwrap(); + //let expected = Template::show(client.cargo(), "error/404", &map).unwrap(); - assert_eq!(response.status(), Status::NotFound); - assert_eq!(response.into_string(), Some(expected)); + assert_eq!(response.status(), Status::MethodNotAllowed); + // FIND A MATCHING TEMPLATE TO HTTP 405 HERE + //assert_eq!(response.body_string(), Some(expected)); }); } } diff --git a/examples/handlebars_templates/templates/error/405.hbs b/examples/handlebars_templates/templates/error/405.hbs new file mode 100644 index 0000000000..a4df7ca0d4 --- /dev/null +++ b/examples/handlebars_templates/templates/error/405.hbs @@ -0,0 +1,17 @@ + + + + + 405 Method Not Allowed + + +
+

405: Method Not Allowed

+

The request method is not supported for the requested resource.

+
+
+
+ Rocket +
+ + diff --git a/examples/tera_templates/src/tests.rs b/examples/tera_templates/src/tests.rs index 05f386b7f9..2384e33be0 100644 --- a/examples/tera_templates/src/tests.rs +++ b/examples/tera_templates/src/tests.rs @@ -30,10 +30,12 @@ fn test_root() { dispatch!(*method, "/", |client, response| { let mut map = std::collections::HashMap::new(); map.insert("path", "/"); - let expected = Template::show(client.rocket(), "error/404", &map).unwrap(); + //let expected = Template::show(client.cargo(), "error/405", &map).unwrap(); - assert_eq!(response.status(), Status::NotFound); - assert_eq!(response.into_string(), Some(expected)); + assert_eq!(response.status(), Status::MethodNotAllowed); + // FIND A MATCHING TEMPLATE TO HTTP 405 HERE + //assert_eq!(response.into_string(), Some(expected)); + //assert_eq!(response.status(), Status::MethodNotAllowed); }); } } diff --git a/examples/tera_templates/templates/error/405.html.tera b/examples/tera_templates/templates/error/405.html.tera new file mode 100644 index 0000000000..e290b55728 --- /dev/null +++ b/examples/tera_templates/templates/error/405.html.tera @@ -0,0 +1,17 @@ + + + + + 405 Method Not Allowed + + +
+

405: Method Not Allowed

+

The request method is not supported for the requested resource.

+
+
+
+ Rocket +
+ + \ No newline at end of file From dcc348198106688f54b605a50708ef3bdeb4558e Mon Sep 17 00:00:00 2001 From: Peng Guanwen Date: Wed, 30 Dec 2020 13:45:59 +0800 Subject: [PATCH 2/4] Typo fix and minor improvements --- core/lib/src/router/collider.rs | 6 +++--- core/lib/src/router/mod.rs | 2 +- core/lib/src/server.rs | 16 ++++++---------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/core/lib/src/router/collider.rs b/core/lib/src/router/collider.rs index 9767db5cf4..16ffa2f7bb 100644 --- a/core/lib/src/router/collider.rs +++ b/core/lib/src/router/collider.rs @@ -25,7 +25,7 @@ impl Route { && formats_collide(self, other) } - /// Determines if this route matches against the given request if . This means + /// Determines if this route matches against the given request. This means /// that: /// /// * The route's method matches that of the incoming request. @@ -41,11 +41,11 @@ impl Route { pub fn matches_by_method(&self, req: &Request<'_>) -> bool { self.method == req.method() && paths_match(self, req) - && queries_match(self, req) + && queries_match(self, req) && formats_match(self, req) } - /// Match agoinst any method. + /// Match against any method. #[doc(hidden)] pub fn match_any(&self, req: &Request<'_>) -> bool { paths_match(self, req) && queries_match(self, req) && formats_match(self, req) diff --git a/core/lib/src/router/mod.rs b/core/lib/src/router/mod.rs index 9dfbd50418..81b19fc73e 100644 --- a/core/lib/src/router/mod.rs +++ b/core/lib/src/router/mod.rs @@ -51,7 +51,7 @@ impl Router { } } - trace_!("Routing(restrict: {}): {}", &restrict, req); + trace_!("Routing(restrict: {}): {}", restrict, req); trace_!("All matches: {:?}", matches); matches } diff --git a/core/lib/src/server.rs b/core/lib/src/server.rs index 712498242e..1263f3700a 100644 --- a/core/lib/src/server.rs +++ b/core/lib/src/server.rs @@ -288,17 +288,13 @@ impl Rocket { // Find if a similar route exists let match_any = self.router.route(request, false); - if match_any.len() > 0 { - info_!("{}", Paint::yellow("A similar route exists: ").bold()); - for route in match_any { + for route in match_any { + if &request.method() != &Method::Head // Must pass HEAD requests foward + && &request.method() != &route.method + { + info_!("{}", Paint::yellow("A similar route exists: ").bold()); info_!(" - {}", Paint::yellow(&route).bold()); - // Must pass HEAD requests foward - if &request.method() == &Method::Head { - continue; - } - if &request.method() != &route.method { - return Outcome::Failure(Status::MethodNotAllowed); - } + return Outcome::Failure(Status::MethodNotAllowed); } } From 421a1bef0f35c889b30a50e5bf5367c96d497e06 Mon Sep 17 00:00:00 2001 From: Peng Guanwen Date: Wed, 30 Dec 2020 14:45:57 +0800 Subject: [PATCH 3/4] Make test pass --- .../return_method_not_allowed_issue_1224.rs | 16 ++++++++-------- examples/handlebars_templates/src/main.rs | 9 ++++++++- examples/handlebars_templates/src/tests.rs | 5 ++--- examples/tera_templates/src/main.rs | 9 ++++++++- examples/tera_templates/src/tests.rs | 6 ++---- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/core/lib/tests/return_method_not_allowed_issue_1224.rs b/core/lib/tests/return_method_not_allowed_issue_1224.rs index abb1691ccc..79a73de6e7 100644 --- a/core/lib/tests/return_method_not_allowed_issue_1224.rs +++ b/core/lib/tests/return_method_not_allowed_issue_1224.rs @@ -21,14 +21,14 @@ fn post_hello() -> &'static str { mod tests { use super::*; use rocket::http::Status; - use rocket::local::Client; + use rocket::local::blocking::Client; #[test] fn test_http_200_when_same_route_with_diff_meth() { let rocket = rocket::ignite() .mount("/", routes![get_index, post_index]); - let client = Client::new(rocket).unwrap(); + let client = Client::tracked(rocket).unwrap(); let response = client.post("/index").dispatch(); @@ -39,7 +39,7 @@ mod tests { fn test_http_200_when_head_request() { let rocket = rocket::ignite().mount("/", routes![get_index]); - let client = Client::new(rocket).unwrap(); + let client = Client::tracked(rocket).unwrap(); let response = client.head("/index").dispatch(); @@ -50,7 +50,7 @@ mod tests { fn test_http_200_when_route_is_ok() { let rocket = rocket::ignite().mount("/", routes![get_index]); - let client = Client::new(rocket).unwrap(); + let client = Client::tracked(rocket).unwrap(); let response = client.get("/index").dispatch(); @@ -61,7 +61,7 @@ mod tests { fn test_http_200_with_params() { let rocket = rocket::ignite().mount("/", routes![get_index]); - let client = Client::new(rocket).unwrap(); + let client = Client::tracked(rocket).unwrap(); let response = client.get("/index?say=hi").dispatch(); @@ -72,7 +72,7 @@ mod tests { fn test_http_404_when_route_not_match() { let rocket = rocket::ignite().mount("/", routes![get_index]); - let client = Client::new(rocket).unwrap(); + let client = Client::tracked(rocket).unwrap(); let response = client.get("/abc").dispatch(); @@ -83,7 +83,7 @@ mod tests { fn test_http_405_when_method_not_match() { let rocket = rocket::ignite().mount("/", routes![get_index]); - let client = Client::new(rocket).unwrap(); + let client = Client::tracked(rocket).unwrap(); let response = client.post("/index").dispatch(); @@ -94,7 +94,7 @@ mod tests { fn test_http_405_with_params() { let rocket = rocket::ignite().mount("/", routes![post_hello]); - let client = Client::new(rocket).unwrap(); + let client = Client::tracked(rocket).unwrap(); let response = client.get("/hello?say=hi").dispatch(); diff --git a/examples/handlebars_templates/src/main.rs b/examples/handlebars_templates/src/main.rs index 04d3cafea6..533de533a9 100644 --- a/examples/handlebars_templates/src/main.rs +++ b/examples/handlebars_templates/src/main.rs @@ -47,6 +47,13 @@ fn not_found(req: &Request<'_>) -> Template { Template::render("error/404", &map) } +#[catch(405)] +fn method_not_allowed(req: &Request<'_>) -> Template { + let mut map = std::collections::HashMap::new(); + map.insert("path", req.uri().path()); + Template::render("error/405", &map) +} + use self::handlebars::{Helper, Handlebars, Context, RenderContext, Output, HelperResult, JsonRender}; fn wow_helper( @@ -69,7 +76,7 @@ fn wow_helper( fn rocket() -> rocket::Rocket { rocket::ignite() .mount("/", routes![index, hello, about]) - .register(catchers![not_found]) + .register(catchers![not_found, method_not_allowed]) .attach(Template::custom(|engines| { engines.handlebars.register_helper("wow", Box::new(wow_helper)); })) diff --git a/examples/handlebars_templates/src/tests.rs b/examples/handlebars_templates/src/tests.rs index f3801c238e..4991af5f8c 100644 --- a/examples/handlebars_templates/src/tests.rs +++ b/examples/handlebars_templates/src/tests.rs @@ -31,11 +31,10 @@ fn test_root() { dispatch!(*method, "/", |client, response| { let mut map = std::collections::HashMap::new(); map.insert("path", "/"); - //let expected = Template::show(client.cargo(), "error/404", &map).unwrap(); + let expected = Template::show(client.rocket(), "error/405", &map).unwrap(); assert_eq!(response.status(), Status::MethodNotAllowed); - // FIND A MATCHING TEMPLATE TO HTTP 405 HERE - //assert_eq!(response.body_string(), Some(expected)); + assert_eq!(response.into_string(), Some(expected)); }); } } diff --git a/examples/tera_templates/src/main.rs b/examples/tera_templates/src/main.rs index 3f617773ce..1c225a6043 100644 --- a/examples/tera_templates/src/main.rs +++ b/examples/tera_templates/src/main.rs @@ -32,10 +32,17 @@ fn not_found(req: &Request<'_>) -> Template { Template::render("error/404", &map) } +#[catch(405)] +fn method_not_allowed(req: &Request<'_>) -> Template { + let mut map = HashMap::new(); + map.insert("path", req.uri().path()); + Template::render("error/405", &map) +} + #[launch] fn rocket() -> rocket::Rocket { rocket::ignite() .mount("/", routes![index, get]) .attach(Template::fairing()) - .register(catchers![not_found]) + .register(catchers![not_found, method_not_allowed]) } diff --git a/examples/tera_templates/src/tests.rs b/examples/tera_templates/src/tests.rs index 2384e33be0..7b17ebe36a 100644 --- a/examples/tera_templates/src/tests.rs +++ b/examples/tera_templates/src/tests.rs @@ -30,12 +30,10 @@ fn test_root() { dispatch!(*method, "/", |client, response| { let mut map = std::collections::HashMap::new(); map.insert("path", "/"); - //let expected = Template::show(client.cargo(), "error/405", &map).unwrap(); + let expected = Template::show(client.rocket(), "error/405", &map).unwrap(); assert_eq!(response.status(), Status::MethodNotAllowed); - // FIND A MATCHING TEMPLATE TO HTTP 405 HERE - //assert_eq!(response.into_string(), Some(expected)); - //assert_eq!(response.status(), Status::MethodNotAllowed); + assert_eq!(response.into_string(), Some(expected)); }); } } From 64985f1d575dacf557f9ead77e5a02b707f2db6e Mon Sep 17 00:00:00 2001 From: Peng Guanwen Date: Wed, 30 Dec 2020 15:20:40 +0800 Subject: [PATCH 4/4] Remove feature declaration in test --- core/lib/tests/return_method_not_allowed_issue_1224.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/lib/tests/return_method_not_allowed_issue_1224.rs b/core/lib/tests/return_method_not_allowed_issue_1224.rs index 79a73de6e7..9765f4bb4c 100644 --- a/core/lib/tests/return_method_not_allowed_issue_1224.rs +++ b/core/lib/tests/return_method_not_allowed_issue_1224.rs @@ -1,5 +1,3 @@ -#![feature(proc_macro_hygiene)] - #[macro_use] extern crate rocket;