mirror of
https://github.com/actix/actix-web.git
synced 2024-12-21 07:36:43 +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 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<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, 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<P>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -118,7 +119,7 @@ where
|
|||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
|
@ -127,7 +128,7 @@ where
|
|||
AppRouting<P>,
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
F: IntoTransform<M, AppRouting<P>>,
|
||||
|
@ -157,7 +158,7 @@ where
|
|||
impl NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceRequest<P1>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
|
@ -165,7 +166,7 @@ where
|
|||
C: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceRequest<P1>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
F: IntoNewService<C>,
|
||||
|
@ -264,7 +265,7 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -324,7 +325,7 @@ where
|
|||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
|
@ -333,7 +334,7 @@ where
|
|||
T::Service,
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
B1: MessageBody,
|
||||
|
@ -363,7 +364,7 @@ where
|
|||
U: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
|
@ -415,13 +416,13 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
C: NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
|
|
@ -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<Box<Guard>>;
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = ()>>;
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = Error>>;
|
||||
|
||||
/// Service factory to convert `Request` to a `ServiceRequest<S>`.
|
||||
/// It also executes state factories.
|
||||
|
@ -29,7 +31,7 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -48,13 +50,13 @@ where
|
|||
C: NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -147,13 +149,13 @@ where
|
|||
C: NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -201,7 +203,7 @@ where
|
|||
/// Service to convert `Request` to a `ServiceRequest<S>`
|
||||
pub struct AppInitService<C, P>
|
||||
where
|
||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = ()>,
|
||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>,
|
||||
{
|
||||
chain: C,
|
||||
rmap: Rc<ResourceMap>,
|
||||
|
@ -210,7 +212,7 @@ where
|
|||
|
||||
impl<C, P> Service for AppInitService<C, P>
|
||||
where
|
||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = ()>,
|
||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = ServiceRequest<P>;
|
||||
|
@ -240,7 +242,7 @@ pub struct AppRoutingFactory<P> {
|
|||
impl<P: 'static> NewService for AppRoutingFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = AppRouting<P>;
|
||||
type Future = AppRoutingFactoryResponse<P>;
|
||||
|
@ -350,7 +352,7 @@ pub struct AppRouting<P> {
|
|||
impl<P> Service for AppRouting<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type Future = Either<BoxedResponse, FutureResult<Self::Response, 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> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = AppRouting<P>;
|
||||
type Future = AppRoutingFactoryResponse<P>;
|
||||
|
@ -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<Self::Service, Self::InitError>;
|
||||
|
@ -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<Self::Response, Self::Error>;
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -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<Box<Guard>>;
|
||||
type HttpNewService<P> =
|
||||
boxed::BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||
boxed::BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
|
||||
/// Application configuration
|
||||
pub struct ServiceConfig<P> {
|
||||
|
@ -84,7 +85,7 @@ impl<P: 'static> ServiceConfig<P> {
|
|||
S: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
|
|
|
@ -193,7 +193,7 @@ where
|
|||
{
|
||||
type Request = (T, HttpRequest);
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = AsyncHandlerService<F, T, R>;
|
||||
type Future = FutureResult<Self::Service, ()>;
|
||||
|
@ -227,7 +227,7 @@ where
|
|||
{
|
||||
type Request = (T, HttpRequest);
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type Future = AsyncHandlerServiceResponse<R::Future>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
|
@ -255,7 +255,7 @@ where
|
|||
T::Error: Into<Error>,
|
||||
{
|
||||
type Item = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
match self.fut.poll() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
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;
|
||||
|
||||
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;
|
||||
|
|
|
@ -17,8 +17,9 @@ use crate::responder::Responder;
|
|||
use crate::route::{CreateRouteService, Route, RouteService};
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
|
||||
/// *Resource* is an entry in route table which corresponds to requested URL.
|
||||
///
|
||||
|
@ -70,7 +71,7 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -232,7 +233,7 @@ where
|
|||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
|
@ -241,7 +242,7 @@ where
|
|||
T::Service,
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
F: IntoTransform<M, T::Service>,
|
||||
|
@ -266,7 +267,7 @@ where
|
|||
U: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
> + 'static,
|
||||
{
|
||||
// create and configure default resource
|
||||
|
@ -284,7 +285,7 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
|
@ -314,7 +315,7 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -336,7 +337,7 @@ pub struct ResourceFactory<P> {
|
|||
impl<P: 'static> NewService for ResourceFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ResourceService<P>;
|
||||
type Future = CreateResourceService<P>;
|
||||
|
@ -427,9 +428,9 @@ pub struct ResourceService<P> {
|
|||
impl<P> Service for ResourceService<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type Future = Either<
|
||||
Box<Future<Item = ServiceResponse, Error = ()>>,
|
||||
Box<Future<Item = ServiceResponse, Error = Error>>,
|
||||
Either<
|
||||
Box<Future<Item = Self::Response, Error = Self::Error>>,
|
||||
FutureResult<Self::Response, Self::Error>,
|
||||
|
@ -472,7 +473,7 @@ impl<P> ResourceEndpoint<P> {
|
|||
impl<P: 'static> NewService for ResourceEndpoint<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ResourceService<P>;
|
||||
type Future = CreateResourceService<P>;
|
||||
|
|
18
src/route.rs
18
src/route.rs
|
@ -17,8 +17,8 @@ type BoxedRouteService<Req, Res> = Box<
|
|||
Service<
|
||||
Request = Req,
|
||||
Response = Res,
|
||||
Error = (),
|
||||
Future = Box<Future<Item = Res, Error = ()>>,
|
||||
Error = Error,
|
||||
Future = Box<Future<Item = Res, Error = Error>>,
|
||||
>,
|
||||
>;
|
||||
|
||||
|
@ -26,7 +26,7 @@ type BoxedRouteNewService<Req, Res> = Box<
|
|||
NewService<
|
||||
Request = Req,
|
||||
Response = Res,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
Service = BoxedRouteService<Req, Res>,
|
||||
Future = Box<Future<Item = BoxedRouteService<Req, Res>, Error = ()>>,
|
||||
|
@ -73,7 +73,7 @@ impl<P: 'static> Route<P> {
|
|||
impl<P> NewService for Route<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = RouteService<P>;
|
||||
type Future = CreateRouteService<P>;
|
||||
|
@ -129,7 +129,7 @@ impl<P> RouteService<P> {
|
|||
impl<P> Service for RouteService<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
|
@ -188,7 +188,7 @@ impl<P: 'static> Route<P> {
|
|||
// T: NewService<
|
||||
// Request = HandlerRequest<S>,
|
||||
// Response = HandlerRequest<S, U>,
|
||||
// InitError = (),
|
||||
// InitError = Error,
|
||||
// >,
|
||||
// {
|
||||
// RouteServiceBuilder {
|
||||
|
@ -372,7 +372,7 @@ where
|
|||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = BoxedRouteService<ServiceRequest<P>, Self::Response>;
|
||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||
|
@ -410,11 +410,11 @@ where
|
|||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
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().map_err(|_| ())
|
||||
self.service.poll_ready().map_err(|(e, _)| e)
|
||||
}
|
||||
|
||||
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 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<Box<Guard>>;
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = ()>>;
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = Error>>;
|
||||
|
||||
/// Resources scope
|
||||
///
|
||||
|
@ -83,7 +85,7 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
|
@ -176,7 +178,7 @@ where
|
|||
U: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
|
@ -201,7 +203,7 @@ where
|
|||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
|
@ -210,7 +212,7 @@ where
|
|||
T::Service,
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
F: IntoTransform<M, T::Service>,
|
||||
|
@ -233,7 +235,7 @@ where
|
|||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse,
|
||||
Error = (),
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
|
@ -290,7 +292,7 @@ pub struct ScopeFactory<P> {
|
|||
impl<P: 'static> NewService for ScopeFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ScopeService<P>;
|
||||
type Future = ScopeFactoryResponse<P>;
|
||||
|
@ -406,7 +408,7 @@ pub struct ScopeService<P> {
|
|||
impl<P> Service for ScopeService<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type Future = Either<BoxedResponse, FutureResult<Self::Response, 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> {
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceResponse;
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ScopeService<P>;
|
||||
type Future = ScopeFactoryResponse<P>;
|
||||
|
|
|
@ -340,6 +340,12 @@ impl<B> ServiceResponse<B> {
|
|||
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
|
||||
#[inline]
|
||||
pub fn request(&self) -> &HttpRequest {
|
||||
|
@ -358,18 +364,6 @@ impl<B> ServiceResponse<B> {
|
|||
&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<F, E>(mut self, f: F) -> Self
|
||||
where
|
||||
|
|
|
@ -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<Runtime> = {
|
||||
|
@ -277,6 +277,11 @@ impl TestRequest {
|
|||
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
|
||||
pub fn to_http_request(mut self) -> HttpRequest {
|
||||
let req = self.req.finish();
|
||||
|
|
Loading…
Reference in a new issue