mirror of
https://github.com/actix/actix-web.git
synced 2024-12-30 12:00:38 +00:00
use actix_web::Error for middleware errors
This commit is contained in:
parent
79875ea039
commit
4d96abb639
13 changed files with 305 additions and 85 deletions
29
src/app.rs
29
src/app.rs
|
@ -3,8 +3,6 @@ use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use actix_http::body::{Body, MessageBody};
|
use actix_http::body::{Body, MessageBody};
|
||||||
use actix_http::PayloadStream;
|
|
||||||
use actix_router::ResourceDef;
|
|
||||||
use actix_server_config::ServerConfig;
|
use actix_server_config::ServerConfig;
|
||||||
use actix_service::boxed::{self, BoxedNewService};
|
use actix_service::boxed::{self, BoxedNewService};
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
|
@ -14,6 +12,8 @@ use futures::IntoFuture;
|
||||||
|
|
||||||
use crate::app_service::{AppChain, AppEntry, AppInit, AppRouting, AppRoutingFactory};
|
use crate::app_service::{AppChain, AppEntry, AppInit, AppRouting, AppRoutingFactory};
|
||||||
use crate::config::{AppConfig, AppConfigInner};
|
use crate::config::{AppConfig, AppConfigInner};
|
||||||
|
use crate::dev::{PayloadStream, ResourceDef};
|
||||||
|
use crate::error::Error;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
use crate::route::Route;
|
use crate::route::Route;
|
||||||
use crate::service::{
|
use crate::service::{
|
||||||
|
@ -22,7 +22,8 @@ use crate::service::{
|
||||||
};
|
};
|
||||||
use crate::state::{State, StateFactory};
|
use crate::state::{State, StateFactory};
|
||||||
|
|
||||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
type HttpNewService<P> =
|
||||||
|
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||||
|
|
||||||
/// Application builder - structure that follows the builder pattern
|
/// Application builder - structure that follows the builder pattern
|
||||||
/// for building application instances.
|
/// for building application instances.
|
||||||
|
@ -55,7 +56,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest,
|
Request = ServiceRequest,
|
||||||
Response = ServiceRequest<P>,
|
Response = ServiceRequest<P>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -118,7 +119,7 @@ where
|
||||||
impl NewService<
|
impl NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B>,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
>
|
>
|
||||||
|
@ -127,7 +128,7 @@ where
|
||||||
AppRouting<P>,
|
AppRouting<P>,
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B>,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
F: IntoTransform<M, AppRouting<P>>,
|
F: IntoTransform<M, AppRouting<P>>,
|
||||||
|
@ -157,7 +158,7 @@ where
|
||||||
impl NewService<
|
impl NewService<
|
||||||
Request = ServiceRequest,
|
Request = ServiceRequest,
|
||||||
Response = ServiceRequest<P1>,
|
Response = ServiceRequest<P1>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
>
|
>
|
||||||
|
@ -165,7 +166,7 @@ where
|
||||||
C: NewService<
|
C: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceRequest<P1>,
|
Response = ServiceRequest<P1>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
F: IntoNewService<C>,
|
F: IntoNewService<C>,
|
||||||
|
@ -264,7 +265,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B>,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -324,7 +325,7 @@ where
|
||||||
impl NewService<
|
impl NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B1>,
|
Response = ServiceResponse<B1>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
>
|
>
|
||||||
|
@ -333,7 +334,7 @@ where
|
||||||
T::Service,
|
T::Service,
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B1>,
|
Response = ServiceResponse<B1>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
B1: MessageBody,
|
B1: MessageBody,
|
||||||
|
@ -363,7 +364,7 @@ where
|
||||||
U: NewService<
|
U: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
{
|
{
|
||||||
|
@ -415,13 +416,13 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B>,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
C: NewService<
|
C: NewService<
|
||||||
Request = ServiceRequest,
|
Request = ServiceRequest,
|
||||||
Response = ServiceRequest<P>,
|
Response = ServiceRequest<P>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,15 +11,17 @@ use futures::future::{ok, Either, FutureResult};
|
||||||
use futures::{Async, Future, Poll};
|
use futures::{Async, Future, Poll};
|
||||||
|
|
||||||
use crate::config::{AppConfig, ServiceConfig};
|
use crate::config::{AppConfig, ServiceConfig};
|
||||||
|
use crate::error::Error;
|
||||||
use crate::guard::Guard;
|
use crate::guard::Guard;
|
||||||
use crate::rmap::ResourceMap;
|
use crate::rmap::ResourceMap;
|
||||||
use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse};
|
||||||
use crate::state::{StateFactory, StateFactoryResult};
|
use crate::state::{StateFactory, StateFactoryResult};
|
||||||
|
|
||||||
type Guards = Vec<Box<Guard>>;
|
type Guards = Vec<Box<Guard>>;
|
||||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
type HttpNewService<P> =
|
||||||
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = ()>>;
|
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||||
|
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = Error>>;
|
||||||
|
|
||||||
/// Service factory to convert `Request` to a `ServiceRequest<S>`.
|
/// Service factory to convert `Request` to a `ServiceRequest<S>`.
|
||||||
/// It also executes state factories.
|
/// It also executes state factories.
|
||||||
|
@ -29,7 +31,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B>,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -48,13 +50,13 @@ where
|
||||||
C: NewService<
|
C: NewService<
|
||||||
Request = ServiceRequest,
|
Request = ServiceRequest,
|
||||||
Response = ServiceRequest<P>,
|
Response = ServiceRequest<P>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B>,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -147,13 +149,13 @@ where
|
||||||
C: NewService<
|
C: NewService<
|
||||||
Request = ServiceRequest,
|
Request = ServiceRequest,
|
||||||
Response = ServiceRequest<P>,
|
Response = ServiceRequest<P>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse<B>,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -201,7 +203,7 @@ where
|
||||||
/// Service to convert `Request` to a `ServiceRequest<S>`
|
/// Service to convert `Request` to a `ServiceRequest<S>`
|
||||||
pub struct AppInitService<C, P>
|
pub struct AppInitService<C, P>
|
||||||
where
|
where
|
||||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = ()>,
|
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>,
|
||||||
{
|
{
|
||||||
chain: C,
|
chain: C,
|
||||||
rmap: Rc<ResourceMap>,
|
rmap: Rc<ResourceMap>,
|
||||||
|
@ -210,7 +212,7 @@ where
|
||||||
|
|
||||||
impl<C, P> Service for AppInitService<C, P>
|
impl<C, P> Service for AppInitService<C, P>
|
||||||
where
|
where
|
||||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = ()>,
|
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>,
|
||||||
{
|
{
|
||||||
type Request = Request;
|
type Request = Request;
|
||||||
type Response = ServiceRequest<P>;
|
type Response = ServiceRequest<P>;
|
||||||
|
@ -240,7 +242,7 @@ pub struct AppRoutingFactory<P> {
|
||||||
impl<P: 'static> NewService for AppRoutingFactory<P> {
|
impl<P: 'static> NewService for AppRoutingFactory<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = AppRouting<P>;
|
type Service = AppRouting<P>;
|
||||||
type Future = AppRoutingFactoryResponse<P>;
|
type Future = AppRoutingFactoryResponse<P>;
|
||||||
|
@ -350,7 +352,7 @@ pub struct AppRouting<P> {
|
||||||
impl<P> Service for AppRouting<P> {
|
impl<P> Service for AppRouting<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>;
|
type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
@ -398,7 +400,7 @@ impl<P> AppEntry<P> {
|
||||||
impl<P: 'static> NewService for AppEntry<P> {
|
impl<P: 'static> NewService for AppEntry<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = AppRouting<P>;
|
type Service = AppRouting<P>;
|
||||||
type Future = AppRoutingFactoryResponse<P>;
|
type Future = AppRoutingFactoryResponse<P>;
|
||||||
|
@ -414,7 +416,7 @@ pub struct AppChain;
|
||||||
impl NewService for AppChain {
|
impl NewService for AppChain {
|
||||||
type Request = ServiceRequest;
|
type Request = ServiceRequest;
|
||||||
type Response = ServiceRequest;
|
type Response = ServiceRequest;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = AppChain;
|
type Service = AppChain;
|
||||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||||
|
@ -427,7 +429,7 @@ impl NewService for AppChain {
|
||||||
impl Service for AppChain {
|
impl Service for AppChain {
|
||||||
type Request = ServiceRequest;
|
type Request = ServiceRequest;
|
||||||
type Response = ServiceRequest;
|
type Response = ServiceRequest;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type Future = FutureResult<Self::Response, Self::Error>;
|
type Future = FutureResult<Self::Response, Self::Error>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -6,13 +6,14 @@ use actix_http::Extensions;
|
||||||
use actix_router::ResourceDef;
|
use actix_router::ResourceDef;
|
||||||
use actix_service::{boxed, IntoNewService, NewService};
|
use actix_service::{boxed, IntoNewService, NewService};
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
use crate::guard::Guard;
|
use crate::guard::Guard;
|
||||||
use crate::rmap::ResourceMap;
|
use crate::rmap::ResourceMap;
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceRequest, ServiceResponse};
|
||||||
|
|
||||||
type Guards = Vec<Box<Guard>>;
|
type Guards = Vec<Box<Guard>>;
|
||||||
type HttpNewService<P> =
|
type HttpNewService<P> =
|
||||||
boxed::BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
boxed::BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||||
|
|
||||||
/// Application configuration
|
/// Application configuration
|
||||||
pub struct ServiceConfig<P> {
|
pub struct ServiceConfig<P> {
|
||||||
|
@ -84,7 +85,7 @@ impl<P: 'static> ServiceConfig<P> {
|
||||||
S: NewService<
|
S: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
{
|
{
|
||||||
|
|
|
@ -193,7 +193,7 @@ where
|
||||||
{
|
{
|
||||||
type Request = (T, HttpRequest);
|
type Request = (T, HttpRequest);
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = AsyncHandlerService<F, T, R>;
|
type Service = AsyncHandlerService<F, T, R>;
|
||||||
type Future = FutureResult<Self::Service, ()>;
|
type Future = FutureResult<Self::Service, ()>;
|
||||||
|
@ -227,7 +227,7 @@ where
|
||||||
{
|
{
|
||||||
type Request = (T, HttpRequest);
|
type Request = (T, HttpRequest);
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type Future = AsyncHandlerServiceResponse<R::Future>;
|
type Future = AsyncHandlerServiceResponse<R::Future>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
@ -255,7 +255,7 @@ where
|
||||||
T::Error: Into<Error>,
|
T::Error: Into<Error>,
|
||||||
{
|
{
|
||||||
type Item = ServiceResponse;
|
type Item = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
match self.fut.poll() {
|
match self.fut.poll() {
|
||||||
|
|
|
@ -40,7 +40,6 @@ pub use crate::responder::{Either, Responder};
|
||||||
pub use crate::route::Route;
|
pub use crate::route::Route;
|
||||||
pub use crate::scope::Scope;
|
pub use crate::scope::Scope;
|
||||||
pub use crate::server::HttpServer;
|
pub use crate::server::HttpServer;
|
||||||
pub use crate::service::{ServiceFromRequest, ServiceRequest, ServiceResponse};
|
|
||||||
|
|
||||||
pub mod dev {
|
pub mod dev {
|
||||||
//! The `actix-web` prelude for library developers
|
//! The `actix-web` prelude for library developers
|
||||||
|
@ -58,7 +57,9 @@ pub mod dev {
|
||||||
pub use crate::config::{AppConfig, ServiceConfig};
|
pub use crate::config::{AppConfig, ServiceConfig};
|
||||||
pub use crate::info::ConnectionInfo;
|
pub use crate::info::ConnectionInfo;
|
||||||
pub use crate::rmap::ResourceMap;
|
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::body::{Body, BodyLength, MessageBody, ResponseBody};
|
||||||
pub use actix_http::dev::ResponseBuilder as HttpResponseBuilder;
|
pub use actix_http::dev::ResponseBuilder as HttpResponseBuilder;
|
||||||
|
|
|
@ -152,9 +152,10 @@ mod tests {
|
||||||
use actix_service::FnService;
|
use actix_service::FnService;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::dev::ServiceRequest;
|
||||||
use crate::http::header::CONTENT_TYPE;
|
use crate::http::header::CONTENT_TYPE;
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::{block_on, TestRequest};
|
||||||
use crate::{HttpResponse, ServiceRequest};
|
use crate::HttpResponse;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default_headers() {
|
fn test_default_headers() {
|
||||||
|
|
210
src/middleware/errhandlers.rs
Normal file
210
src/middleware/errhandlers.rs
Normal file
|
@ -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<B> {
|
||||||
|
/// New http response got generated
|
||||||
|
Response(ServiceResponse<B>),
|
||||||
|
/// Result is a future that resolves to a new http response
|
||||||
|
Future(Box<Future<Item = ServiceResponse<B>, Error = Error>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorHandler<B> = Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>>;
|
||||||
|
|
||||||
|
/// `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<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||||
|
/// 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<B> {
|
||||||
|
handlers: Rc<HashMap<StatusCode, Box<ErrorHandler<B>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B> Default for ErrorHandlers<B> {
|
||||||
|
fn default() -> Self {
|
||||||
|
ErrorHandlers {
|
||||||
|
handlers: Rc::new(HashMap::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B> ErrorHandlers<B> {
|
||||||
|
/// Construct new `ErrorHandlers` instance
|
||||||
|
pub fn new() -> Self {
|
||||||
|
ErrorHandlers::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register error handler for specified status code
|
||||||
|
pub fn handler<F>(mut self, status: StatusCode, handler: F) -> Self
|
||||||
|
where
|
||||||
|
F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,
|
||||||
|
{
|
||||||
|
Rc::get_mut(&mut self.handlers)
|
||||||
|
.unwrap()
|
||||||
|
.insert(status, Box::new(handler));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, P, B> Transform<S> for ErrorHandlers<B>
|
||||||
|
where
|
||||||
|
S: Service<
|
||||||
|
Request = ServiceRequest<P>,
|
||||||
|
Response = ServiceResponse<B>,
|
||||||
|
Error = Error,
|
||||||
|
>,
|
||||||
|
S::Future: 'static,
|
||||||
|
S::Error: 'static,
|
||||||
|
B: 'static,
|
||||||
|
{
|
||||||
|
type Request = ServiceRequest<P>;
|
||||||
|
type Response = ServiceResponse<B>;
|
||||||
|
type Error = Error;
|
||||||
|
type InitError = ();
|
||||||
|
type Transform = ErrorHandlersMiddleware<S, B>;
|
||||||
|
type Future = FutureResult<Self::Transform, Self::InitError>;
|
||||||
|
|
||||||
|
fn new_transform(&self, service: S) -> Self::Future {
|
||||||
|
ok(ErrorHandlersMiddleware {
|
||||||
|
service,
|
||||||
|
handlers: self.handlers.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ErrorHandlersMiddleware<S, B> {
|
||||||
|
service: S,
|
||||||
|
handlers: Rc<HashMap<StatusCode, Box<ErrorHandler<B>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, P, B> Service for ErrorHandlersMiddleware<S, B>
|
||||||
|
where
|
||||||
|
S: Service<
|
||||||
|
Request = ServiceRequest<P>,
|
||||||
|
Response = ServiceResponse<B>,
|
||||||
|
Error = Error,
|
||||||
|
>,
|
||||||
|
S::Future: 'static,
|
||||||
|
S::Error: 'static,
|
||||||
|
B: 'static,
|
||||||
|
{
|
||||||
|
type Request = ServiceRequest<P>;
|
||||||
|
type Response = ServiceResponse<B>;
|
||||||
|
type Error = Error;
|
||||||
|
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
self.service.poll_ready()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: ServiceRequest<P>) -> 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<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||||
|
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<B: 'static>(
|
||||||
|
mut res: ServiceResponse<B>,
|
||||||
|
) -> Result<ErrorHandlerResponse<B>> {
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,13 +4,15 @@ mod compress;
|
||||||
pub use self::compress::Compress;
|
pub use self::compress::Compress;
|
||||||
|
|
||||||
mod defaultheaders;
|
mod defaultheaders;
|
||||||
|
mod errhandlers;
|
||||||
|
mod logger;
|
||||||
|
|
||||||
pub use self::defaultheaders::DefaultHeaders;
|
pub use self::defaultheaders::DefaultHeaders;
|
||||||
|
pub use self::errhandlers::{ErrorHandlerResponse, ErrorHandlers};
|
||||||
|
pub use self::logger::Logger;
|
||||||
|
|
||||||
// #[cfg(feature = "session")]
|
// #[cfg(feature = "session")]
|
||||||
// pub use actix_session as session;
|
// pub use actix_session as session;
|
||||||
|
|
||||||
mod logger;
|
|
||||||
pub use self::logger::Logger;
|
|
||||||
|
|
||||||
#[cfg(feature = "session")]
|
#[cfg(feature = "session")]
|
||||||
pub mod identity;
|
pub mod identity;
|
||||||
|
|
|
@ -17,8 +17,9 @@ use crate::responder::Responder;
|
||||||
use crate::route::{CreateRouteService, Route, RouteService};
|
use crate::route::{CreateRouteService, Route, RouteService};
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceRequest, ServiceResponse};
|
||||||
|
|
||||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
type HttpNewService<P> =
|
||||||
|
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||||
|
|
||||||
/// *Resource* is an entry in route table which corresponds to requested URL.
|
/// *Resource* is an entry in route table which corresponds to requested URL.
|
||||||
///
|
///
|
||||||
|
@ -70,7 +71,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -232,7 +233,7 @@ where
|
||||||
impl NewService<
|
impl NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
>
|
>
|
||||||
|
@ -241,7 +242,7 @@ where
|
||||||
T::Service,
|
T::Service,
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
F: IntoTransform<M, T::Service>,
|
F: IntoTransform<M, T::Service>,
|
||||||
|
@ -266,7 +267,7 @@ where
|
||||||
U: NewService<
|
U: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
> + 'static,
|
> + 'static,
|
||||||
{
|
{
|
||||||
// create and configure default resource
|
// create and configure default resource
|
||||||
|
@ -284,7 +285,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
{
|
{
|
||||||
|
@ -314,7 +315,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -336,7 +337,7 @@ pub struct ResourceFactory<P> {
|
||||||
impl<P: 'static> NewService for ResourceFactory<P> {
|
impl<P: 'static> NewService for ResourceFactory<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = ResourceService<P>;
|
type Service = ResourceService<P>;
|
||||||
type Future = CreateResourceService<P>;
|
type Future = CreateResourceService<P>;
|
||||||
|
@ -427,9 +428,9 @@ pub struct ResourceService<P> {
|
||||||
impl<P> Service for ResourceService<P> {
|
impl<P> Service for ResourceService<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
Box<Future<Item = ServiceResponse, Error = ()>>,
|
Box<Future<Item = ServiceResponse, Error = Error>>,
|
||||||
Either<
|
Either<
|
||||||
Box<Future<Item = Self::Response, Error = Self::Error>>,
|
Box<Future<Item = Self::Response, Error = Self::Error>>,
|
||||||
FutureResult<Self::Response, Self::Error>,
|
FutureResult<Self::Response, Self::Error>,
|
||||||
|
@ -472,7 +473,7 @@ impl<P> ResourceEndpoint<P> {
|
||||||
impl<P: 'static> NewService for ResourceEndpoint<P> {
|
impl<P: 'static> NewService for ResourceEndpoint<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = ResourceService<P>;
|
type Service = ResourceService<P>;
|
||||||
type Future = CreateResourceService<P>;
|
type Future = CreateResourceService<P>;
|
||||||
|
|
18
src/route.rs
18
src/route.rs
|
@ -17,8 +17,8 @@ type BoxedRouteService<Req, Res> = Box<
|
||||||
Service<
|
Service<
|
||||||
Request = Req,
|
Request = Req,
|
||||||
Response = Res,
|
Response = Res,
|
||||||
Error = (),
|
Error = Error,
|
||||||
Future = Box<Future<Item = Res, Error = ()>>,
|
Future = Box<Future<Item = Res, Error = Error>>,
|
||||||
>,
|
>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ type BoxedRouteNewService<Req, Res> = Box<
|
||||||
NewService<
|
NewService<
|
||||||
Request = Req,
|
Request = Req,
|
||||||
Response = Res,
|
Response = Res,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
Service = BoxedRouteService<Req, Res>,
|
Service = BoxedRouteService<Req, Res>,
|
||||||
Future = Box<Future<Item = BoxedRouteService<Req, Res>, Error = ()>>,
|
Future = Box<Future<Item = BoxedRouteService<Req, Res>, Error = ()>>,
|
||||||
|
@ -73,7 +73,7 @@ impl<P: 'static> Route<P> {
|
||||||
impl<P> NewService for Route<P> {
|
impl<P> NewService for Route<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = RouteService<P>;
|
type Service = RouteService<P>;
|
||||||
type Future = CreateRouteService<P>;
|
type Future = CreateRouteService<P>;
|
||||||
|
@ -129,7 +129,7 @@ impl<P> RouteService<P> {
|
||||||
impl<P> Service for RouteService<P> {
|
impl<P> Service for RouteService<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
@ -188,7 +188,7 @@ impl<P: 'static> Route<P> {
|
||||||
// T: NewService<
|
// T: NewService<
|
||||||
// Request = HandlerRequest<S>,
|
// Request = HandlerRequest<S>,
|
||||||
// Response = HandlerRequest<S, U>,
|
// Response = HandlerRequest<S, U>,
|
||||||
// InitError = (),
|
// InitError = Error,
|
||||||
// >,
|
// >,
|
||||||
// {
|
// {
|
||||||
// RouteServiceBuilder {
|
// RouteServiceBuilder {
|
||||||
|
@ -372,7 +372,7 @@ where
|
||||||
{
|
{
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = BoxedRouteService<ServiceRequest<P>, Self::Response>;
|
type Service = BoxedRouteService<ServiceRequest<P>, Self::Response>;
|
||||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||||
|
@ -410,11 +410,11 @@ where
|
||||||
{
|
{
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
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<P>) -> Self::Future {
|
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||||
|
|
24
src/scope.rs
24
src/scope.rs
|
@ -11,6 +11,7 @@ use futures::future::{ok, Either, Future, FutureResult};
|
||||||
use futures::{Async, Poll};
|
use futures::{Async, Poll};
|
||||||
|
|
||||||
use crate::dev::{HttpServiceFactory, ServiceConfig};
|
use crate::dev::{HttpServiceFactory, ServiceConfig};
|
||||||
|
use crate::error::Error;
|
||||||
use crate::guard::Guard;
|
use crate::guard::Guard;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
use crate::rmap::ResourceMap;
|
use crate::rmap::ResourceMap;
|
||||||
|
@ -20,9 +21,10 @@ use crate::service::{
|
||||||
};
|
};
|
||||||
|
|
||||||
type Guards = Vec<Box<Guard>>;
|
type Guards = Vec<Box<Guard>>;
|
||||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
type HttpNewService<P> =
|
||||||
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = ()>>;
|
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||||
|
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = Error>>;
|
||||||
|
|
||||||
/// Resources scope
|
/// Resources scope
|
||||||
///
|
///
|
||||||
|
@ -83,7 +85,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
|
@ -176,7 +178,7 @@ where
|
||||||
U: NewService<
|
U: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
{
|
{
|
||||||
|
@ -201,7 +203,7 @@ where
|
||||||
impl NewService<
|
impl NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
>
|
>
|
||||||
|
@ -210,7 +212,7 @@ where
|
||||||
T::Service,
|
T::Service,
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
F: IntoTransform<M, T::Service>,
|
F: IntoTransform<M, T::Service>,
|
||||||
|
@ -233,7 +235,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (),
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
{
|
{
|
||||||
|
@ -290,7 +292,7 @@ pub struct ScopeFactory<P> {
|
||||||
impl<P: 'static> NewService for ScopeFactory<P> {
|
impl<P: 'static> NewService for ScopeFactory<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = ScopeService<P>;
|
type Service = ScopeService<P>;
|
||||||
type Future = ScopeFactoryResponse<P>;
|
type Future = ScopeFactoryResponse<P>;
|
||||||
|
@ -406,7 +408,7 @@ pub struct ScopeService<P> {
|
||||||
impl<P> Service for ScopeService<P> {
|
impl<P> Service for ScopeService<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>;
|
type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
@ -450,7 +452,7 @@ impl<P> ScopeEndpoint<P> {
|
||||||
impl<P: 'static> NewService for ScopeEndpoint<P> {
|
impl<P: 'static> NewService for ScopeEndpoint<P> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = ();
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = ScopeService<P>;
|
type Service = ScopeService<P>;
|
||||||
type Future = ScopeFactoryResponse<P>;
|
type Future = ScopeFactoryResponse<P>;
|
||||||
|
|
|
@ -340,6 +340,12 @@ impl<B> ServiceResponse<B> {
|
||||||
Self::from_err(err, self.request)
|
Self::from_err(err, self.request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create service response
|
||||||
|
#[inline]
|
||||||
|
pub fn into_response<B1>(self, response: Response<B1>) -> ServiceResponse<B1> {
|
||||||
|
ServiceResponse::new(self.request, response)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get reference to original request
|
/// Get reference to original request
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn request(&self) -> &HttpRequest {
|
pub fn request(&self) -> &HttpRequest {
|
||||||
|
@ -358,18 +364,6 @@ impl<B> ServiceResponse<B> {
|
||||||
&mut self.response
|
&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.
|
/// Execute closure and in case of error convert it to response.
|
||||||
pub fn checked_expr<F, E>(mut self, f: F) -> Self
|
pub fn checked_expr<F, E>(mut self, f: F) -> Self
|
||||||
where
|
where
|
||||||
|
|
|
@ -14,9 +14,9 @@ use bytes::Bytes;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
use crate::config::{AppConfig, AppConfigInner};
|
use crate::config::{AppConfig, AppConfigInner};
|
||||||
use crate::request::HttpRequest;
|
|
||||||
use crate::rmap::ResourceMap;
|
use crate::rmap::ResourceMap;
|
||||||
use crate::service::{ServiceFromRequest, ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceFromRequest, ServiceRequest, ServiceResponse};
|
||||||
|
use crate::{HttpRequest, HttpResponse};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static RT: RefCell<Runtime> = {
|
static RT: RefCell<Runtime> = {
|
||||||
|
@ -277,6 +277,11 @@ impl TestRequest {
|
||||||
self.req.finish()
|
self.req.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Complete request creation and generate `ServiceResponse` instance
|
||||||
|
pub fn to_response<B>(self, res: HttpResponse<B>) -> ServiceResponse<B> {
|
||||||
|
self.to_service().into_response(res)
|
||||||
|
}
|
||||||
|
|
||||||
/// Complete request creation and generate `HttpRequest` instance
|
/// Complete request creation and generate `HttpRequest` instance
|
||||||
pub fn to_http_request(mut self) -> HttpRequest {
|
pub fn to_http_request(mut self) -> HttpRequest {
|
||||||
let req = self.req.finish();
|
let req = self.req.finish();
|
||||||
|
|
Loading…
Reference in a new issue