Skip to content

Commit a77063a

Browse files
authored
fix: breaking on unsupported methods (#1241)
* fix: breaking on unsupported methods * update * fix formatting
1 parent c82be70 commit a77063a

3 files changed

Lines changed: 51 additions & 19 deletions

File tree

src/server.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,11 @@ async fn index(
466466
excluded_response_headers_paths: web::Data<Option<Vec<String>>>,
467467
req: HttpRequest,
468468
) -> ResponseType {
469+
// Check if the HTTP method is supported
470+
if !HttpMethod::is_supported(req.method()) {
471+
return ResponseType::Standard(Response::method_not_allowed(None));
472+
}
473+
469474
let mut request = Request::from_actix_request(&req, payload, &global_request_headers).await;
470475

471476
let route = format!("{}{}", req.method(), req.uri().path());
@@ -500,15 +505,15 @@ async fn index(
500505
}
501506

502507
// Route execution
503-
let mut response = if let Some(res) = const_router.get_route(
504-
&HttpMethod::from_actix_method(req.method()),
505-
req.uri().path(),
506-
) {
508+
let http_method = match HttpMethod::from_actix_method(req.method()) {
509+
Ok(method) => method,
510+
Err(_) => return ResponseType::Standard(Response::method_not_allowed(None)),
511+
};
512+
513+
let mut response = if let Some(res) = const_router.get_route(&http_method, req.uri().path()) {
507514
ResponseType::Standard(res)
508-
} else if let Some((function, route_params)) = router.get_route(
509-
&HttpMethod::from_actix_method(req.method()),
510-
req.uri().path(),
511-
) {
515+
} else if let Some((function, route_params)) = router.get_route(&http_method, req.uri().path())
516+
{
512517
request.path_params = route_params;
513518
match execute_http_function(&request, &function).await {
514519
Ok(r) => r,

src/types/mod.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,33 @@ pub enum HttpMethod {
3434
}
3535

3636
impl HttpMethod {
37-
pub fn from_actix_method(method: &actix_web::http::Method) -> Self {
37+
pub fn is_supported(method: &actix_web::http::Method) -> bool {
38+
matches!(
39+
*method,
40+
actix_web::http::Method::GET
41+
| actix_web::http::Method::POST
42+
| actix_web::http::Method::PUT
43+
| actix_web::http::Method::DELETE
44+
| actix_web::http::Method::PATCH
45+
| actix_web::http::Method::HEAD
46+
| actix_web::http::Method::OPTIONS
47+
| actix_web::http::Method::CONNECT
48+
| actix_web::http::Method::TRACE
49+
)
50+
}
51+
52+
pub fn from_actix_method(method: &actix_web::http::Method) -> Result<Self, &'static str> {
3853
match *method {
39-
actix_web::http::Method::GET => Self::GET,
40-
actix_web::http::Method::POST => Self::POST,
41-
actix_web::http::Method::PUT => Self::PUT,
42-
actix_web::http::Method::DELETE => Self::DELETE,
43-
actix_web::http::Method::PATCH => Self::PATCH,
44-
actix_web::http::Method::HEAD => Self::HEAD,
45-
actix_web::http::Method::OPTIONS => Self::OPTIONS,
46-
actix_web::http::Method::CONNECT => Self::CONNECT,
47-
actix_web::http::Method::TRACE => Self::TRACE,
48-
_ => panic!("Unsupported HTTP method"),
54+
actix_web::http::Method::GET => Ok(Self::GET),
55+
actix_web::http::Method::POST => Ok(Self::POST),
56+
actix_web::http::Method::PUT => Ok(Self::PUT),
57+
actix_web::http::Method::DELETE => Ok(Self::DELETE),
58+
actix_web::http::Method::PATCH => Ok(Self::PATCH),
59+
actix_web::http::Method::HEAD => Ok(Self::HEAD),
60+
actix_web::http::Method::OPTIONS => Ok(Self::OPTIONS),
61+
actix_web::http::Method::CONNECT => Ok(Self::CONNECT),
62+
actix_web::http::Method::TRACE => Ok(Self::TRACE),
63+
_ => Err("Method Not Allowed"),
4964
}
5065
}
5166
}

src/types/response.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ impl Response {
193193
file_path: None,
194194
}
195195
}
196+
197+
pub fn method_not_allowed(headers: Option<&Headers>) -> Self {
198+
const METHOD_NOT_ALLOWED_BYTES: &[u8] = b"Method not allowed";
199+
200+
Self {
201+
status_code: 405,
202+
response_type: "text".to_string(),
203+
headers: headers.cloned().unwrap_or_else(|| Headers::new(None)),
204+
description: METHOD_NOT_ALLOWED_BYTES.to_vec(),
205+
file_path: None,
206+
}
207+
}
196208
}
197209

198210
impl<'py> IntoPyObject<'py> for Response {

0 commit comments

Comments
 (0)