diff --git a/src/app.rs b/src/app.rs index 29dd1ab60..54b5ded25 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3,8 +3,6 @@ use std::marker::PhantomData; use std::rc::Rc; use actix_http::body::{Body, MessageBody}; -use actix_http::PayloadStream; -use actix_router::ResourceDef; use actix_server_config::ServerConfig; use actix_service::boxed::{self, BoxedNewService}; use actix_service::{ @@ -14,6 +12,8 @@ use futures::IntoFuture; use crate::app_service::{AppChain, AppEntry, AppInit, AppRouting, AppRoutingFactory}; use crate::config::{AppConfig, AppConfigInner}; +use crate::dev::{PayloadStream, ResourceDef}; +use crate::error::Error; use crate::resource::Resource; use crate::route::Route; use crate::service::{ @@ -22,7 +22,8 @@ use crate::service::{ }; use crate::state::{State, StateFactory}; -type HttpNewService

= BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; +type HttpNewService

= + BoxedNewService<(), ServiceRequest

, ServiceResponse, Error, ()>; /// Application builder - structure that follows the builder pattern /// for building application instances. @@ -55,7 +56,7 @@ where T: NewService< Request = ServiceRequest, Response = ServiceRequest

, - Error = (), + Error = Error, InitError = (), >, { @@ -118,7 +119,7 @@ where impl NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, > @@ -127,7 +128,7 @@ where AppRouting

, Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, F: IntoTransform>, @@ -157,7 +158,7 @@ where impl NewService< Request = ServiceRequest, Response = ServiceRequest, - Error = (), + Error = Error, InitError = (), >, > @@ -165,7 +166,7 @@ where C: NewService< Request = ServiceRequest

, Response = ServiceRequest, - Error = (), + Error = Error, InitError = (), >, F: IntoNewService, @@ -264,7 +265,7 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, { @@ -324,7 +325,7 @@ where impl NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, > @@ -333,7 +334,7 @@ where T::Service, Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, B1: MessageBody, @@ -363,7 +364,7 @@ where U: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), > + 'static, { @@ -415,13 +416,13 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, C: NewService< Request = ServiceRequest, Response = ServiceRequest

, - Error = (), + Error = Error, InitError = (), >, { diff --git a/src/app_service.rs b/src/app_service.rs index 75e4b3164..c59b80bcc 100644 --- a/src/app_service.rs +++ b/src/app_service.rs @@ -11,15 +11,17 @@ use futures::future::{ok, Either, FutureResult}; use futures::{Async, Future, Poll}; use crate::config::{AppConfig, ServiceConfig}; +use crate::error::Error; use crate::guard::Guard; use crate::rmap::ResourceMap; use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse}; use crate::state::{StateFactory, StateFactoryResult}; type Guards = Vec>; -type HttpService

= BoxedService, ServiceResponse, ()>; -type HttpNewService

= BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; -type BoxedResponse = Box>; +type HttpService

= BoxedService, ServiceResponse, Error>; +type HttpNewService

= + BoxedNewService<(), ServiceRequest

, ServiceResponse, Error, ()>; +type BoxedResponse = Box>; /// Service factory to convert `Request` to a `ServiceRequest`. /// It also executes state factories. @@ -29,7 +31,7 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, { @@ -48,13 +50,13 @@ where C: NewService< Request = ServiceRequest, Response = ServiceRequest

, - Error = (), + Error = Error, InitError = (), >, T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, { @@ -147,13 +149,13 @@ where C: NewService< Request = ServiceRequest, Response = ServiceRequest

, - Error = (), + Error = Error, InitError = (), >, T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, { @@ -201,7 +203,7 @@ where /// Service to convert `Request` to a `ServiceRequest` pub struct AppInitService where - C: Service, Error = ()>, + C: Service, Error = Error>, { chain: C, rmap: Rc, @@ -210,7 +212,7 @@ where impl Service for AppInitService where - C: Service, Error = ()>, + C: Service, Error = Error>, { type Request = Request; type Response = ServiceRequest

; @@ -240,7 +242,7 @@ pub struct AppRoutingFactory

{ impl NewService for AppRoutingFactory

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = AppRouting

; type Future = AppRoutingFactoryResponse

; @@ -350,7 +352,7 @@ pub struct AppRouting

{ impl

Service for AppRouting

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type Future = Either>; fn poll_ready(&mut self) -> Poll<(), Self::Error> { @@ -398,7 +400,7 @@ impl

AppEntry

{ impl NewService for AppEntry

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = AppRouting

; type Future = AppRoutingFactoryResponse

; @@ -414,7 +416,7 @@ pub struct AppChain; impl NewService for AppChain { type Request = ServiceRequest; type Response = ServiceRequest; - type Error = (); + type Error = Error; type InitError = (); type Service = AppChain; type Future = FutureResult; @@ -427,7 +429,7 @@ impl NewService for AppChain { impl Service for AppChain { type Request = ServiceRequest; type Response = ServiceRequest; - type Error = (); + type Error = Error; type Future = FutureResult; #[inline] diff --git a/src/config.rs b/src/config.rs index f84376c76..ceb58feb7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,13 +6,14 @@ use actix_http::Extensions; use actix_router::ResourceDef; use actix_service::{boxed, IntoNewService, NewService}; +use crate::error::Error; use crate::guard::Guard; use crate::rmap::ResourceMap; use crate::service::{ServiceRequest, ServiceResponse}; type Guards = Vec>; type HttpNewService

= - boxed::BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; + boxed::BoxedNewService<(), ServiceRequest

, ServiceResponse, Error, ()>; /// Application configuration pub struct ServiceConfig

{ @@ -84,7 +85,7 @@ impl ServiceConfig

{ S: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), > + 'static, { diff --git a/src/handler.rs b/src/handler.rs index 876456510..4ff3193c8 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -193,7 +193,7 @@ where { type Request = (T, HttpRequest); type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = AsyncHandlerService; type Future = FutureResult; @@ -227,7 +227,7 @@ where { type Request = (T, HttpRequest); type Response = ServiceResponse; - type Error = (); + type Error = Error; type Future = AsyncHandlerServiceResponse; fn poll_ready(&mut self) -> Poll<(), Self::Error> { @@ -255,7 +255,7 @@ where T::Error: Into, { type Item = ServiceResponse; - type Error = (); + type Error = Error; fn poll(&mut self) -> Poll { match self.fut.poll() { diff --git a/src/lib.rs b/src/lib.rs index f6f722be6..c04480af5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,6 @@ pub use crate::responder::{Either, Responder}; pub use crate::route::Route; pub use crate::scope::Scope; pub use crate::server::HttpServer; -pub use crate::service::{ServiceFromRequest, ServiceRequest, ServiceResponse}; pub mod dev { //! The `actix-web` prelude for library developers @@ -58,7 +57,9 @@ pub mod dev { pub use crate::config::{AppConfig, ServiceConfig}; pub use crate::info::ConnectionInfo; pub use crate::rmap::ResourceMap; - pub use crate::service::HttpServiceFactory; + pub use crate::service::{ + HttpServiceFactory, ServiceFromRequest, ServiceRequest, ServiceResponse, + }; pub use actix_http::body::{Body, BodyLength, MessageBody, ResponseBody}; pub use actix_http::dev::ResponseBuilder as HttpResponseBuilder; diff --git a/src/middleware/defaultheaders.rs b/src/middleware/defaultheaders.rs index b4927962f..bca2cf6e0 100644 --- a/src/middleware/defaultheaders.rs +++ b/src/middleware/defaultheaders.rs @@ -152,9 +152,10 @@ mod tests { use actix_service::FnService; use super::*; + use crate::dev::ServiceRequest; use crate::http::header::CONTENT_TYPE; use crate::test::{block_on, TestRequest}; - use crate::{HttpResponse, ServiceRequest}; + use crate::HttpResponse; #[test] fn test_default_headers() { diff --git a/src/middleware/errhandlers.rs b/src/middleware/errhandlers.rs new file mode 100644 index 000000000..7a79aae16 --- /dev/null +++ b/src/middleware/errhandlers.rs @@ -0,0 +1,210 @@ +use std::rc::Rc; + +use actix_service::{Service, Transform}; +use futures::future::{err, ok, Either, Future, FutureResult}; +use futures::Poll; +use hashbrown::HashMap; + +use crate::dev::{ServiceRequest, ServiceResponse}; +use crate::error::{Error, Result}; +use crate::http::StatusCode; + +/// Error handler response +pub enum ErrorHandlerResponse { + /// New http response got generated + Response(ServiceResponse), + /// Result is a future that resolves to a new http response + Future(Box, Error = Error>>), +} + +type ErrorHandler = Fn(ServiceResponse) -> Result>; + +/// `Middleware` for allowing custom handlers for responses. +/// +/// You can use `ErrorHandlers::handler()` method to register a custom error +/// handler for specific status code. You can modify existing response or +/// create completely new one. +/// +/// ## Example +/// +/// ```rust +/// use actix_web::middleware::{ErrorHandlers, ErrorHandlerResponse}; +/// use actix_web::{web, http, dev, App, HttpRequest, HttpResponse, Result}; +/// +/// fn render_500(mut res: dev::ServiceResponse) -> Result> { +/// res.response_mut() +/// .headers_mut() +/// .insert(http::header::CONTENT_TYPE, http::HeaderValue::from_static("Error")); +/// Ok(ErrorHandlerResponse::Response(res)) +/// } +/// +/// fn main() { +/// let app = App::new() +/// .middleware( +/// ErrorHandlers::new() +/// .handler(http::StatusCode::INTERNAL_SERVER_ERROR, render_500), +/// ) +/// .service(web::resource("/test") +/// .route(web::get().to(|| HttpResponse::Ok())) +/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()) +/// )); +/// } +/// ``` +pub struct ErrorHandlers { + handlers: Rc>>>, +} + +impl Default for ErrorHandlers { + fn default() -> Self { + ErrorHandlers { + handlers: Rc::new(HashMap::new()), + } + } +} + +impl ErrorHandlers { + /// Construct new `ErrorHandlers` instance + pub fn new() -> Self { + ErrorHandlers::default() + } + + /// Register error handler for specified status code + pub fn handler(mut self, status: StatusCode, handler: F) -> Self + where + F: Fn(ServiceResponse) -> Result> + 'static, + { + Rc::get_mut(&mut self.handlers) + .unwrap() + .insert(status, Box::new(handler)); + self + } +} + +impl Transform for ErrorHandlers +where + S: Service< + Request = ServiceRequest

, + Response = ServiceResponse, + Error = Error, + >, + S::Future: 'static, + S::Error: 'static, + B: 'static, +{ + type Request = ServiceRequest

; + type Response = ServiceResponse; + type Error = Error; + type InitError = (); + type Transform = ErrorHandlersMiddleware; + type Future = FutureResult; + + fn new_transform(&self, service: S) -> Self::Future { + ok(ErrorHandlersMiddleware { + service, + handlers: self.handlers.clone(), + }) + } +} + +pub struct ErrorHandlersMiddleware { + service: S, + handlers: Rc>>>, +} + +impl Service for ErrorHandlersMiddleware +where + S: Service< + Request = ServiceRequest

, + Response = ServiceResponse, + Error = Error, + >, + S::Future: 'static, + S::Error: 'static, + B: 'static, +{ + type Request = ServiceRequest

; + type Response = ServiceResponse; + type Error = Error; + type Future = Box>; + + fn poll_ready(&mut self) -> Poll<(), Self::Error> { + self.service.poll_ready() + } + + fn call(&mut self, req: ServiceRequest

) -> Self::Future { + let handlers = self.handlers.clone(); + + Box::new(self.service.call(req).and_then(move |res| { + if let Some(handler) = handlers.get(&res.status()) { + match handler(res) { + Ok(ErrorHandlerResponse::Response(res)) => Either::A(ok(res)), + Ok(ErrorHandlerResponse::Future(fut)) => Either::B(fut), + Err(e) => Either::A(err(e)), + } + } else { + Either::A(ok(res)) + } + })) + } +} + +#[cfg(test)] +mod tests { + use actix_service::FnService; + use futures::future::ok; + + use super::*; + use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode}; + use crate::test::{self, TestRequest}; + use crate::HttpResponse; + + fn render_500(mut res: ServiceResponse) -> Result> { + res.response_mut() + .headers_mut() + .insert(CONTENT_TYPE, HeaderValue::from_static("0001")); + Ok(ErrorHandlerResponse::Response(res)) + } + + #[test] + fn test_handler() { + let srv = FnService::new(|req: ServiceRequest<_>| { + req.into_response(HttpResponse::InternalServerError().finish()) + }); + + let mut mw = test::block_on( + ErrorHandlers::new() + .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500) + .new_transform(srv), + ) + .unwrap(); + + let resp = test::call_success(&mut mw, TestRequest::default().to_service()); + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); + } + + fn render_500_async( + mut res: ServiceResponse, + ) -> Result> { + res.response_mut() + .headers_mut() + .insert(CONTENT_TYPE, HeaderValue::from_static("0001")); + Ok(ErrorHandlerResponse::Future(Box::new(ok(res)))) + } + + #[test] + fn test_handler_async() { + let srv = FnService::new(|req: ServiceRequest<_>| { + req.into_response(HttpResponse::InternalServerError().finish()) + }); + + let mut mw = test::block_on( + ErrorHandlers::new() + .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500_async) + .new_transform(srv), + ) + .unwrap(); + + let resp = test::call_success(&mut mw, TestRequest::default().to_service()); + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); + } +} diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index 288c1d63b..6e55cd67e 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -4,13 +4,15 @@ mod compress; pub use self::compress::Compress; mod defaultheaders; +mod errhandlers; +mod logger; + pub use self::defaultheaders::DefaultHeaders; +pub use self::errhandlers::{ErrorHandlerResponse, ErrorHandlers}; +pub use self::logger::Logger; // #[cfg(feature = "session")] // pub use actix_session as session; -mod logger; -pub use self::logger::Logger; - #[cfg(feature = "session")] pub mod identity; diff --git a/src/resource.rs b/src/resource.rs index 57f6f710a..e4fe65c05 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -17,8 +17,9 @@ use crate::responder::Responder; use crate::route::{CreateRouteService, Route, RouteService}; use crate::service::{ServiceRequest, ServiceResponse}; -type HttpService

= BoxedService, ServiceResponse, ()>; -type HttpNewService

= BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; +type HttpService

= BoxedService, ServiceResponse, Error>; +type HttpNewService

= + BoxedNewService<(), ServiceRequest

, ServiceResponse, Error, ()>; /// *Resource* is an entry in route table which corresponds to requested URL. /// @@ -70,7 +71,7 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, { @@ -232,7 +233,7 @@ where impl NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, > @@ -241,7 +242,7 @@ where T::Service, Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, F: IntoTransform, @@ -266,7 +267,7 @@ where U: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, > + 'static, { // create and configure default resource @@ -284,7 +285,7 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), > + 'static, { @@ -314,7 +315,7 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, { @@ -336,7 +337,7 @@ pub struct ResourceFactory

{ impl NewService for ResourceFactory

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = ResourceService

; type Future = CreateResourceService

; @@ -427,9 +428,9 @@ pub struct ResourceService

{ impl

Service for ResourceService

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type Future = Either< - Box>, + Box>, Either< Box>, FutureResult, @@ -472,7 +473,7 @@ impl

ResourceEndpoint

{ impl NewService for ResourceEndpoint

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = ResourceService

; type Future = CreateResourceService

; diff --git a/src/route.rs b/src/route.rs index 1955a81ad..707da3d85 100644 --- a/src/route.rs +++ b/src/route.rs @@ -17,8 +17,8 @@ type BoxedRouteService = Box< Service< Request = Req, Response = Res, - Error = (), - Future = Box>, + Error = Error, + Future = Box>, >, >; @@ -26,7 +26,7 @@ type BoxedRouteNewService = Box< NewService< Request = Req, Response = Res, - Error = (), + Error = Error, InitError = (), Service = BoxedRouteService, Future = Box, Error = ()>>, @@ -73,7 +73,7 @@ impl Route

{ impl

NewService for Route

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = RouteService

; type Future = CreateRouteService

; @@ -129,7 +129,7 @@ impl

RouteService

{ impl

Service for RouteService

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type Future = Box>; fn poll_ready(&mut self) -> Poll<(), Self::Error> { @@ -188,7 +188,7 @@ impl Route

{ // T: NewService< // Request = HandlerRequest, // Response = HandlerRequest, - // InitError = (), + // InitError = Error, // >, // { // RouteServiceBuilder { @@ -372,7 +372,7 @@ where { type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = BoxedRouteService, Self::Response>; type Future = Box>; @@ -410,11 +410,11 @@ where { type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type Future = Box>; fn poll_ready(&mut self) -> Poll<(), Self::Error> { - self.service.poll_ready().map_err(|_| ()) + self.service.poll_ready().map_err(|(e, _)| e) } fn call(&mut self, req: ServiceRequest

) -> Self::Future { diff --git a/src/scope.rs b/src/scope.rs index 3b5061737..9f5b650cd 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -11,6 +11,7 @@ use futures::future::{ok, Either, Future, FutureResult}; use futures::{Async, Poll}; use crate::dev::{HttpServiceFactory, ServiceConfig}; +use crate::error::Error; use crate::guard::Guard; use crate::resource::Resource; use crate::rmap::ResourceMap; @@ -20,9 +21,10 @@ use crate::service::{ }; type Guards = Vec>; -type HttpService

= BoxedService, ServiceResponse, ()>; -type HttpNewService

= BoxedNewService<(), ServiceRequest

, ServiceResponse, (), ()>; -type BoxedResponse = Box>; +type HttpService

= BoxedService, ServiceResponse, Error>; +type HttpNewService

= + BoxedNewService<(), ServiceRequest

, ServiceResponse, Error, ()>; +type BoxedResponse = Box>; /// Resources scope /// @@ -83,7 +85,7 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, { @@ -176,7 +178,7 @@ where U: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), > + 'static, { @@ -201,7 +203,7 @@ where impl NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, > @@ -210,7 +212,7 @@ where T::Service, Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), >, F: IntoTransform, @@ -233,7 +235,7 @@ where T: NewService< Request = ServiceRequest

, Response = ServiceResponse, - Error = (), + Error = Error, InitError = (), > + 'static, { @@ -290,7 +292,7 @@ pub struct ScopeFactory

{ impl NewService for ScopeFactory

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = ScopeService

; type Future = ScopeFactoryResponse

; @@ -406,7 +408,7 @@ pub struct ScopeService

{ impl

Service for ScopeService

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type Future = Either>; fn poll_ready(&mut self) -> Poll<(), Self::Error> { @@ -450,7 +452,7 @@ impl

ScopeEndpoint

{ impl NewService for ScopeEndpoint

{ type Request = ServiceRequest

; type Response = ServiceResponse; - type Error = (); + type Error = Error; type InitError = (); type Service = ScopeService

; type Future = ScopeFactoryResponse

; diff --git a/src/service.rs b/src/service.rs index 08330282d..e907a1abc 100644 --- a/src/service.rs +++ b/src/service.rs @@ -340,6 +340,12 @@ impl ServiceResponse { Self::from_err(err, self.request) } + /// Create service response + #[inline] + pub fn into_response(self, response: Response) -> ServiceResponse { + ServiceResponse::new(self.request, response) + } + /// Get reference to original request #[inline] pub fn request(&self) -> &HttpRequest { @@ -358,18 +364,6 @@ impl ServiceResponse { &mut self.response } - /// Get the headers from the response - #[inline] - pub fn headers(&self) -> &HeaderMap { - self.response.headers() - } - - /// Get a mutable reference to the headers - #[inline] - pub fn headers_mut(&mut self) -> &mut HeaderMap { - self.response.headers_mut() - } - /// Execute closure and in case of error convert it to response. pub fn checked_expr(mut self, f: F) -> Self where diff --git a/src/test.rs b/src/test.rs index b47daa2c6..445924006 100644 --- a/src/test.rs +++ b/src/test.rs @@ -14,9 +14,9 @@ use bytes::Bytes; use futures::Future; use crate::config::{AppConfig, AppConfigInner}; -use crate::request::HttpRequest; use crate::rmap::ResourceMap; use crate::service::{ServiceFromRequest, ServiceRequest, ServiceResponse}; +use crate::{HttpRequest, HttpResponse}; thread_local! { static RT: RefCell = { @@ -277,6 +277,11 @@ impl TestRequest { self.req.finish() } + /// Complete request creation and generate `ServiceResponse` instance + pub fn to_response(self, res: HttpResponse) -> ServiceResponse { + self.to_service().into_response(res) + } + /// Complete request creation and generate `HttpRequest` instance pub fn to_http_request(mut self) -> HttpRequest { let req = self.req.finish();