1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-11-25 19:11:10 +00:00

add warn log to from_parts if given request is cloned

closes #2562
This commit is contained in:
Rob Ede 2022-01-19 22:23:53 +00:00
parent 1bc1538118
commit 81ef12a0fd
No known key found for this signature in database
GPG key ID: 97C636207D3EF933
3 changed files with 42 additions and 8 deletions

View file

@ -302,13 +302,13 @@ impl ToTokens for Route {
if methods.len() > 1 { if methods.len() > 1 {
quote! { quote! {
.guard( .guard(
actix_web::guard::Any(actix_web::guard::#first()) ::actix_web::guard::Any(::actix_web::guard::#first())
#(.or(actix_web::guard::#others()))* #(.or(::actix_web::guard::#others()))*
) )
} }
} else { } else {
quote! { quote! {
.guard(actix_web::guard::#first()) .guard(::actix_web::guard::#first())
} }
} }
}; };
@ -318,17 +318,17 @@ impl ToTokens for Route {
#[allow(non_camel_case_types, missing_docs)] #[allow(non_camel_case_types, missing_docs)]
pub struct #name; pub struct #name;
impl actix_web::dev::HttpServiceFactory for #name { impl ::actix_web::dev::HttpServiceFactory for #name {
fn register(self, __config: &mut actix_web::dev::AppService) { fn register(self, __config: &mut actix_web::dev::AppService) {
#ast #ast
let __resource = actix_web::Resource::new(#path) let __resource = ::actix_web::Resource::new(#path)
.name(#resource_name) .name(#resource_name)
#method_guards #method_guards
#(.guard(actix_web::guard::fn_guard(#guards)))* #(.guard(::actix_web::guard::fn_guard(#guards)))*
#(.wrap(#wrappers))* #(.wrap(#wrappers))*
.#resource_type(#name); .#resource_type(#name);
actix_web::dev::HttpServiceFactory::register(__resource, __config) ::actix_web::dev::HttpServiceFactory::register(__resource, __config)
} }
} }
}; };

View file

@ -138,6 +138,10 @@ impl HttpRequest {
&self.inner.path &self.inner.path
} }
/// Returns a mutable reference to the URL parameters container.
///
/// # Panics
/// Panics if this `HttpRequest` has been cloned.
#[inline] #[inline]
pub(crate) fn match_info_mut(&mut self) -> &mut Path<Url> { pub(crate) fn match_info_mut(&mut self) -> &mut Path<Url> {
&mut Rc::get_mut(&mut self.inner).unwrap().path &mut Rc::get_mut(&mut self.inner).unwrap().path

View file

@ -97,6 +97,11 @@ impl ServiceRequest {
/// Construct request from parts. /// Construct request from parts.
pub fn from_parts(req: HttpRequest, payload: Payload) -> Self { pub fn from_parts(req: HttpRequest, payload: Payload) -> Self {
#[cfg(debug_assertions)]
if Rc::strong_count(&req.inner) > 1 {
log::warn!("Cloning an `HttpRequest` might cause panics.");
}
Self { req, payload } Self { req, payload }
} }
@ -663,7 +668,7 @@ service_tuple! { A B C D E F G H I J K L }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::test::{init_service, TestRequest}; use crate::test::{self, init_service, TestRequest};
use crate::{guard, http, web, App, HttpResponse}; use crate::{guard, http, web, App, HttpResponse};
use actix_service::Service; use actix_service::Service;
use actix_utils::future::ok; use actix_utils::future::ok;
@ -810,4 +815,29 @@ mod tests {
let resp = srv.call(req).await.unwrap(); let resp = srv.call(req).await.unwrap();
assert_eq!(resp.status(), http::StatusCode::OK); assert_eq!(resp.status(), http::StatusCode::OK);
} }
#[actix_rt::test]
#[should_panic(expected = "called `Option::unwrap()` on a `None` value")]
async fn cloning_request_panics() {
async fn index(_name: web::Path<(String,)>) -> &'static str {
""
}
let app = test::init_service(
App::new()
.wrap_fn(|req, svc| {
let (req, pl) = req.into_parts();
let _req2 = req.clone();
let req = ServiceRequest::from_parts(req, pl);
svc.call(req)
})
.service(
web::resource("/resource1/{name}/index.html").route(web::get().to(index)),
),
)
.await;
let req = test::TestRequest::default().to_request();
let _res = test::call_service(&app, req).await;
}
} }