1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +01:00

Allow to re-construct ServiceRequest from HttpRequest and Payload #1088

This commit is contained in:
Nikolay Kim 2019-09-13 11:56:24 +06:00
parent e35d930ef9
commit a32573bb58
3 changed files with 55 additions and 4 deletions

View File

@ -1,13 +1,13 @@
# Changes
## not released yet
## [1.0.8] - 2019-09-xx
### Added
* Add `middleware::Conditon` that conditionally enables another middleware
* Add `middleware::Conditon` that conditionally enables another middleware
### Fixed
* Allow to re-construct `ServiceRequest` from `HttpRequest` and `Payload`
* h2 will use error response #1080
## [1.0.7] - 2019-08-29

View File

@ -8,6 +8,8 @@
### Fixed
* h2 will use error response #1080
* on_connect result isn't added to request extensions for http2 requests #1009

View File

@ -68,6 +68,34 @@ impl ServiceRequest {
(self.0, pl)
}
/// Construct request from parts.
///
/// `ServiceRequest` can be re-constructed only if `req` hasnt been cloned.
pub fn from_parts(
mut req: HttpRequest,
pl: Payload,
) -> Result<Self, (HttpRequest, Payload)> {
if Rc::strong_count(&req.0) == 1 && Rc::weak_count(&req.0) == 0 {
Rc::get_mut(&mut req.0).unwrap().payload = pl;
Ok(ServiceRequest(req))
} else {
Err((req, pl))
}
}
/// Construct request from request.
///
/// `HttpRequest` implements `Clone` trait via `Rc` type. `ServiceRequest`
/// can be re-constructed only if rc's strong pointers count eq 1 and
/// weak pointers count is 0.
pub fn from_request(req: HttpRequest) -> Result<Self, HttpRequest> {
if Rc::strong_count(&req.0) == 1 && Rc::weak_count(&req.0) == 0 {
Ok(ServiceRequest(req))
} else {
Err(req)
}
}
/// Create service response
#[inline]
pub fn into_response<B, R: Into<Response<B>>>(self, res: R) -> ServiceResponse<B> {
@ -514,6 +542,27 @@ mod tests {
use crate::test::{call_service, init_service, TestRequest};
use crate::{guard, http, web, App, HttpResponse};
#[test]
fn test_service_request() {
let req = TestRequest::default().to_srv_request();
let (r, pl) = req.into_parts();
assert!(ServiceRequest::from_parts(r, pl).is_ok());
let req = TestRequest::default().to_srv_request();
let (r, pl) = req.into_parts();
let _r2 = r.clone();
assert!(ServiceRequest::from_parts(r, pl).is_err());
let req = TestRequest::default().to_srv_request();
let (r, _pl) = req.into_parts();
assert!(ServiceRequest::from_request(r).is_ok());
let req = TestRequest::default().to_srv_request();
let (r, _pl) = req.into_parts();
let _r2 = r.clone();
assert!(ServiceRequest::from_request(r).is_err());
}
#[test]
fn test_service() {
let mut srv = init_service(