1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-05-20 09:18:26 +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 {
quote! {
.guard(
actix_web::guard::Any(actix_web::guard::#first())
#(.or(actix_web::guard::#others()))*
::actix_web::guard::Any(::actix_web::guard::#first())
#(.or(::actix_web::guard::#others()))*
)
}
} else {
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)]
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) {
#ast
let __resource = actix_web::Resource::new(#path)
let __resource = ::actix_web::Resource::new(#path)
.name(#resource_name)
#method_guards
#(.guard(actix_web::guard::fn_guard(#guards)))*
#(.guard(::actix_web::guard::fn_guard(#guards)))*
#(.wrap(#wrappers))*
.#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
}
/// Returns a mutable reference to the URL parameters container.
///
/// # Panics
/// Panics if this `HttpRequest` has been cloned.
#[inline]
pub(crate) fn match_info_mut(&mut self) -> &mut Path<Url> {
&mut Rc::get_mut(&mut self.inner).unwrap().path

View file

@ -97,6 +97,11 @@ impl ServiceRequest {
/// Construct request from parts.
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 }
}
@ -663,7 +668,7 @@ service_tuple! { A B C D E F G H I J K L }
#[cfg(test)]
mod tests {
use super::*;
use crate::test::{init_service, TestRequest};
use crate::test::{self, init_service, TestRequest};
use crate::{guard, http, web, App, HttpResponse};
use actix_service::Service;
use actix_utils::future::ok;
@ -810,4 +815,29 @@ mod tests {
let resp = srv.call(req).await.unwrap();
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;
}
}