mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-27 17:52:56 +01:00
Remove generic type for request payload, always use default
This commit is contained in:
parent
043f6e77ae
commit
4f30fa9d46
10
CHANGES.md
10
CHANGES.md
@ -1,5 +1,15 @@
|
||||
# Changes
|
||||
|
||||
## [1.0.0-alpha.6] - 2019-04-xx
|
||||
|
||||
### Changed
|
||||
|
||||
* Remove generic type for request payload, always use default.
|
||||
|
||||
* Removed `Decompress` middleware. Bytes, String, Json, Form extractors
|
||||
automatically decompress payload.
|
||||
|
||||
|
||||
## [1.0.0-alpha.5] - 2019-04-12
|
||||
|
||||
### Added
|
||||
|
@ -32,9 +32,8 @@ use self::error::{FilesError, UriSegmentError};
|
||||
pub use crate::named::NamedFile;
|
||||
pub use crate::range::HttpRange;
|
||||
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
|
||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
|
||||
/// Return the MIME type associated with a filename extension (case-insensitive).
|
||||
/// If `ext` is empty or no associated type for the extension was found, returns
|
||||
@ -225,18 +224,18 @@ type MimeOverride = Fn(&mime::Name) -> DispositionType;
|
||||
/// .service(fs::Files::new("/static", "."));
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Files<S> {
|
||||
pub struct Files {
|
||||
path: String,
|
||||
directory: PathBuf,
|
||||
index: Option<String>,
|
||||
show_index: bool,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService<S>>>>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
|
||||
renderer: Rc<DirectoryRenderer>,
|
||||
mime_override: Option<Rc<MimeOverride>>,
|
||||
file_flags: named::Flags,
|
||||
}
|
||||
|
||||
impl<S> Clone for Files<S> {
|
||||
impl Clone for Files {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
directory: self.directory.clone(),
|
||||
@ -251,13 +250,13 @@ impl<S> Clone for Files<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: 'static> Files<S> {
|
||||
impl Files {
|
||||
/// Create new `Files` instance for specified base directory.
|
||||
///
|
||||
/// `File` uses `ThreadPool` for blocking filesystem operations.
|
||||
/// By default pool with 5x threads of available cpus is used.
|
||||
/// Pool size can be changed by setting ACTIX_CPU_POOL environment variable.
|
||||
pub fn new<T: Into<PathBuf>>(path: &str, dir: T) -> Files<S> {
|
||||
pub fn new<T: Into<PathBuf>>(path: &str, dir: T) -> Files {
|
||||
let dir = dir.into().canonicalize().unwrap_or_else(|_| PathBuf::new());
|
||||
if !dir.is_dir() {
|
||||
log::error!("Specified path is not a directory");
|
||||
@ -335,7 +334,7 @@ impl<S: 'static> Files<S> {
|
||||
where
|
||||
F: IntoNewService<U>,
|
||||
U: NewService<
|
||||
Request = ServiceRequest<S>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
> + 'static,
|
||||
@ -349,11 +348,8 @@ impl<S: 'static> Files<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> HttpServiceFactory<P> for Files<P>
|
||||
where
|
||||
P: 'static,
|
||||
{
|
||||
fn register(self, config: &mut ServiceConfig<P>) {
|
||||
impl HttpServiceFactory for Files {
|
||||
fn register(self, config: &mut ServiceConfig) {
|
||||
if self.default.borrow().is_none() {
|
||||
*self.default.borrow_mut() = Some(config.default_service());
|
||||
}
|
||||
@ -366,11 +362,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: 'static> NewService for Files<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for Files {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Service = FilesService<P>;
|
||||
type Service = FilesService;
|
||||
type InitError = ();
|
||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||
|
||||
@ -401,22 +397,22 @@ impl<P: 'static> NewService for Files<P> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FilesService<P> {
|
||||
pub struct FilesService {
|
||||
directory: PathBuf,
|
||||
index: Option<String>,
|
||||
show_index: bool,
|
||||
default: Option<HttpService<P>>,
|
||||
default: Option<HttpService>,
|
||||
renderer: Rc<DirectoryRenderer>,
|
||||
mime_override: Option<Rc<MimeOverride>>,
|
||||
file_flags: named::Flags,
|
||||
}
|
||||
|
||||
impl<P> FilesService<P> {
|
||||
impl FilesService {
|
||||
fn handle_err(
|
||||
&mut self,
|
||||
e: io::Error,
|
||||
req: HttpRequest,
|
||||
payload: Payload<P>,
|
||||
payload: Payload,
|
||||
) -> Either<
|
||||
FutureResult<ServiceResponse, Error>,
|
||||
Box<Future<Item = ServiceResponse, Error = Error>>,
|
||||
@ -430,8 +426,8 @@ impl<P> FilesService<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Service for FilesService<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl Service for FilesService {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Future = Either<
|
||||
@ -443,7 +439,7 @@ impl<P> Service for FilesService<P> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
let (req, pl) = req.into_parts();
|
||||
|
||||
let real_path = match PathBufWrp::get_pathbuf(req.match_info().path()) {
|
||||
@ -547,11 +543,11 @@ impl PathBufWrp {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> FromRequest<P> for PathBufWrp {
|
||||
impl FromRequest for PathBufWrp {
|
||||
type Error = UriSegmentError;
|
||||
type Future = Result<Self, Self::Error>;
|
||||
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
PathBufWrp::get_pathbuf(req.match_info().path())
|
||||
}
|
||||
}
|
||||
@ -570,6 +566,7 @@ mod tests {
|
||||
self, ContentDisposition, DispositionParam, DispositionType,
|
||||
};
|
||||
use actix_web::http::{Method, StatusCode};
|
||||
use actix_web::middleware::Compress;
|
||||
use actix_web::test::{self, TestRequest};
|
||||
use actix_web::App;
|
||||
|
||||
@ -965,7 +962,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_named_file_content_encoding() {
|
||||
let mut srv = test::init_service(App::new().enable_encoding().service(
|
||||
let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
|
||||
web::resource("/").to(|| {
|
||||
NamedFile::open("Cargo.toml")
|
||||
.unwrap()
|
||||
@ -984,7 +981,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_named_file_content_encoding_gzip() {
|
||||
let mut srv = test::init_service(App::new().enable_encoding().service(
|
||||
let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
|
||||
web::resource("/").to(|| {
|
||||
NamedFile::open("Cargo.toml")
|
||||
.unwrap()
|
||||
@ -1053,15 +1050,15 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_static_files_bad_directory() {
|
||||
let _st: Files<()> = Files::new("/", "missing");
|
||||
let _st: Files<()> = Files::new("/", "Cargo.toml");
|
||||
let _st: Files = Files::new("/", "missing");
|
||||
let _st: Files = Files::new("/", "Cargo.toml");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_handler_file_missing() {
|
||||
let mut st = test::block_on(
|
||||
Files::new("/", ".")
|
||||
.default_handler(|req: ServiceRequest<_>| {
|
||||
.default_handler(|req: ServiceRequest| {
|
||||
Ok(req.into_response(HttpResponse::Ok().body("default content")))
|
||||
})
|
||||
.new_service(&()),
|
||||
|
@ -15,7 +15,7 @@ use actix_web::http::header::{
|
||||
self, ContentDisposition, DispositionParam, DispositionType,
|
||||
};
|
||||
use actix_web::http::{ContentEncoding, Method, StatusCode};
|
||||
use actix_web::middleware::encoding::BodyEncoding;
|
||||
use actix_web::middleware::BodyEncoding;
|
||||
use actix_web::{Error, HttpMessage, HttpRequest, HttpResponse, Responder};
|
||||
|
||||
use crate::range::HttpRange;
|
||||
|
@ -53,6 +53,7 @@ where
|
||||
type Item = Bytes;
|
||||
type Error = PayloadError;
|
||||
|
||||
#[inline]
|
||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||
match self {
|
||||
Payload::None => Ok(Async::Ready(None)),
|
||||
|
@ -1,9 +1,5 @@
|
||||
//! Multipart payload support
|
||||
use bytes::Bytes;
|
||||
use futures::Stream;
|
||||
|
||||
use actix_web::error::{Error, PayloadError};
|
||||
use actix_web::{dev::Payload, FromRequest, HttpRequest};
|
||||
use actix_web::{dev::Payload, Error, FromRequest, HttpRequest};
|
||||
|
||||
use crate::server::Multipart;
|
||||
|
||||
@ -34,15 +30,12 @@ use crate::server::Multipart;
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
impl<P> FromRequest<P> for Multipart
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
{
|
||||
impl FromRequest for Multipart {
|
||||
type Error = Error;
|
||||
type Future = Result<Multipart, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||
Ok(Multipart::new(req.headers(), payload.take()))
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ impl CookieSessionInner {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load<P>(&self, req: &ServiceRequest<P>) -> HashMap<String, String> {
|
||||
fn load(&self, req: &ServiceRequest) -> HashMap<String, String> {
|
||||
if let Ok(cookies) = req.cookies() {
|
||||
for cookie in cookies.iter() {
|
||||
if cookie.name() == self.name {
|
||||
@ -256,13 +256,13 @@ impl CookieSession {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P, B: 'static> Transform<S> for CookieSession
|
||||
impl<S, B: 'static> Transform<S> for CookieSession
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
@ -283,13 +283,13 @@ pub struct CookieSessionMiddleware<S> {
|
||||
inner: Rc<CookieSessionInner>,
|
||||
}
|
||||
|
||||
impl<S, P, B: 'static> Service for CookieSessionMiddleware<S>
|
||||
impl<S, B: 'static> Service for CookieSessionMiddleware<S>
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||
@ -298,7 +298,7 @@ where
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
||||
let inner = self.inner.clone();
|
||||
let state = self.inner.load(&req);
|
||||
Session::set_session(state.into_iter(), &mut req);
|
||||
|
@ -119,9 +119,9 @@ impl Session {
|
||||
inner.state.clear()
|
||||
}
|
||||
|
||||
pub fn set_session<P>(
|
||||
pub fn set_session(
|
||||
data: impl Iterator<Item = (String, String)>,
|
||||
req: &mut ServiceRequest<P>,
|
||||
req: &mut ServiceRequest,
|
||||
) {
|
||||
let session = Session::get_session(&mut *req.extensions_mut());
|
||||
let mut inner = session.0.borrow_mut();
|
||||
@ -172,12 +172,12 @@ impl Session {
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
impl<P> FromRequest<P> for Session {
|
||||
impl FromRequest for Session {
|
||||
type Error = Error;
|
||||
type Future = Result<Session, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
Ok(Session::get_session(&mut *req.extensions_mut()))
|
||||
}
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ impl fmt::Display for Args {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct {name};
|
||||
|
||||
impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for {name} {{
|
||||
fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {{
|
||||
impl actix_web::dev::HttpServiceFactory for {name} {{
|
||||
fn register(self, config: &mut actix_web::dev::ServiceConfig) {{
|
||||
{ast}
|
||||
|
||||
let resource = actix_web::Resource::new(\"{path}\"){guards}.{to}({name});
|
||||
|
@ -4,11 +4,6 @@ use actix_web::{http, App, HttpResponse, Responder};
|
||||
use actix_web_codegen::get;
|
||||
use futures::{future, Future};
|
||||
|
||||
//fn guard_head(head: &actix_web::dev::RequestHead) -> bool {
|
||||
// true
|
||||
//}
|
||||
|
||||
//#[get("/test", guard="guard_head")]
|
||||
#[get("/test")]
|
||||
fn test() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
|
@ -27,7 +27,7 @@ fn main() -> std::io::Result<()> {
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
|
||||
.wrap(middleware::encoding::Compress::default())
|
||||
.wrap(middleware::Compress::default())
|
||||
.wrap(middleware::Logger::default())
|
||||
.service(index)
|
||||
.service(no_params)
|
||||
|
594
src/app.rs
594
src/app.rs
@ -3,22 +3,18 @@ use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
|
||||
use actix_http::body::{Body, MessageBody};
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
use actix_http::encoding::{Decoder, Encoder};
|
||||
use actix_server_config::ServerConfig;
|
||||
use actix_service::boxed::{self, BoxedNewService};
|
||||
use actix_service::{
|
||||
apply_transform, IntoNewService, IntoTransform, NewService, Transform,
|
||||
};
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
use bytes::Bytes;
|
||||
use futures::{IntoFuture, Stream};
|
||||
use futures::IntoFuture;
|
||||
|
||||
use crate::app_service::{AppChain, AppEntry, AppInit, AppRouting, AppRoutingFactory};
|
||||
use crate::app_service::{AppEntry, AppInit, AppRoutingFactory};
|
||||
use crate::config::{AppConfig, AppConfigInner, RouterConfig};
|
||||
use crate::data::{Data, DataFactory};
|
||||
use crate::dev::{Payload, PayloadStream, ResourceDef};
|
||||
use crate::error::{Error, PayloadError};
|
||||
use crate::dev::ResourceDef;
|
||||
use crate::error::Error;
|
||||
use crate::resource::Resource;
|
||||
use crate::route::Route;
|
||||
use crate::service::{
|
||||
@ -26,40 +22,44 @@ use crate::service::{
|
||||
ServiceResponse,
|
||||
};
|
||||
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
|
||||
/// Application builder - structure that follows the builder pattern
|
||||
/// for building application instances.
|
||||
pub struct App<In, Out, T>
|
||||
where
|
||||
T: NewService<Request = ServiceRequest<In>, Response = ServiceRequest<Out>>,
|
||||
{
|
||||
chain: T,
|
||||
pub struct App<T, B> {
|
||||
endpoint: T,
|
||||
services: Vec<Box<ServiceFactory>>,
|
||||
default: Option<Rc<HttpNewService>>,
|
||||
factory_ref: Rc<RefCell<Option<AppRoutingFactory>>>,
|
||||
data: Vec<Box<DataFactory>>,
|
||||
config: AppConfigInner,
|
||||
_t: PhantomData<(In, Out)>,
|
||||
external: Vec<ResourceDef>,
|
||||
_t: PhantomData<(B)>,
|
||||
}
|
||||
|
||||
impl App<PayloadStream, PayloadStream, AppChain> {
|
||||
impl App<AppEntry, Body> {
|
||||
/// Create application builder. Application can be configured with a builder-like pattern.
|
||||
pub fn new() -> Self {
|
||||
let fref = Rc::new(RefCell::new(None));
|
||||
App {
|
||||
chain: AppChain,
|
||||
endpoint: AppEntry::new(fref.clone()),
|
||||
data: Vec::new(),
|
||||
services: Vec::new(),
|
||||
default: None,
|
||||
factory_ref: fref,
|
||||
config: AppConfigInner::default(),
|
||||
external: Vec::new(),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<In, Out, T> App<In, Out, T>
|
||||
impl<T, B> App<T, B>
|
||||
where
|
||||
In: 'static,
|
||||
Out: 'static,
|
||||
B: MessageBody,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<In>,
|
||||
Response = ServiceRequest<Out>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
@ -112,151 +112,6 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
/// Registers middleware, in the form of a middleware component (type),
|
||||
/// that runs during inbound and/or outbound processing in the request
|
||||
/// lifecycle (request -> response), modifying request/response as
|
||||
/// necessary, across all requests managed by the *Application*.
|
||||
///
|
||||
/// Use middleware when you need to read or modify *every* request or response in some way.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// # use futures::Future;
|
||||
/// use actix_web::{middleware, web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .wrap(middleware::Logger::default())
|
||||
/// .route("/index.html", web::get().to(index));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn wrap<M, B, F>(
|
||||
self,
|
||||
mw: F,
|
||||
) -> AppRouter<
|
||||
T,
|
||||
Out,
|
||||
B,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<Out>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
M: Transform<
|
||||
AppRouting<Out>,
|
||||
Request = ServiceRequest<Out>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
F: IntoTransform<M, AppRouting<Out>>,
|
||||
{
|
||||
let fref = Rc::new(RefCell::new(None));
|
||||
let endpoint = apply_transform(mw, AppEntry::new(fref.clone()));
|
||||
AppRouter {
|
||||
endpoint,
|
||||
chain: self.chain,
|
||||
data: self.data,
|
||||
services: Vec::new(),
|
||||
default: None,
|
||||
factory_ref: fref,
|
||||
config: self.config,
|
||||
external: Vec::new(),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers middleware, in the form of a closure, that runs during inbound
|
||||
/// and/or outbound processing in the request lifecycle (request -> response),
|
||||
/// modifying request/response as necessary, across all requests managed by
|
||||
/// the *Application*.
|
||||
///
|
||||
/// Use middleware when you need to read or modify *every* request or response in some way.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// # use futures::Future;
|
||||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .wrap_fn(|req, srv|
|
||||
/// srv.call(req).map(|mut res| {
|
||||
/// res.headers_mut().insert(
|
||||
/// CONTENT_TYPE, HeaderValue::from_static("text/plain"),
|
||||
/// );
|
||||
/// res
|
||||
/// }))
|
||||
/// .route("/index.html", web::get().to(index));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn wrap_fn<F, R, B>(
|
||||
self,
|
||||
mw: F,
|
||||
) -> AppRouter<
|
||||
T,
|
||||
Out,
|
||||
B,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<Out>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
F: FnMut(ServiceRequest<Out>, &mut AppRouting<Out>) -> R + Clone,
|
||||
R: IntoFuture<Item = ServiceResponse<B>, Error = Error>,
|
||||
{
|
||||
self.wrap(mw)
|
||||
}
|
||||
|
||||
/// Register a request modifier. It can modify any request parameters
|
||||
/// including request payload type.
|
||||
pub fn chain<C, F, P>(
|
||||
self,
|
||||
chain: F,
|
||||
) -> App<
|
||||
In,
|
||||
P,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<In>,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
C: NewService<
|
||||
Request = ServiceRequest<Out>,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
F: IntoNewService<C>,
|
||||
{
|
||||
let chain = self.chain.and_then(chain.into_new_service());
|
||||
App {
|
||||
chain,
|
||||
data: self.data,
|
||||
config: self.config,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Run external configuration as part of the application building
|
||||
/// process
|
||||
///
|
||||
@ -269,7 +124,7 @@ where
|
||||
/// use actix_web::{web, middleware, App, HttpResponse};
|
||||
///
|
||||
/// // this function could be located in different module
|
||||
/// fn config<P>(cfg: &mut web::RouterConfig<P>) {
|
||||
/// fn config(cfg: &mut web::RouterConfig) {
|
||||
/// cfg.service(web::resource("/test")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
|
||||
@ -283,27 +138,16 @@ where
|
||||
/// .route("/index.html", web::get().to(|| HttpResponse::Ok()));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn configure<F>(mut self, f: F) -> AppRouter<T, Out, Body, AppEntry<Out>>
|
||||
pub fn configure<F>(mut self, f: F) -> Self
|
||||
where
|
||||
F: Fn(&mut RouterConfig<Out>),
|
||||
F: Fn(&mut RouterConfig),
|
||||
{
|
||||
let mut cfg = RouterConfig::new();
|
||||
f(&mut cfg);
|
||||
self.data.extend(cfg.data);
|
||||
|
||||
let fref = Rc::new(RefCell::new(None));
|
||||
|
||||
AppRouter {
|
||||
chain: self.chain,
|
||||
default: None,
|
||||
endpoint: AppEntry::new(fref.clone()),
|
||||
factory_ref: fref,
|
||||
data: self.data,
|
||||
config: self.config,
|
||||
services: cfg.services,
|
||||
external: cfg.external,
|
||||
_t: PhantomData,
|
||||
}
|
||||
self.services.extend(cfg.services);
|
||||
self.external.extend(cfg.external);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure route for a specific path.
|
||||
@ -325,171 +169,7 @@ where
|
||||
/// .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn route(
|
||||
self,
|
||||
path: &str,
|
||||
mut route: Route<Out>,
|
||||
) -> AppRouter<T, Out, Body, AppEntry<Out>> {
|
||||
self.service(
|
||||
Resource::new(path)
|
||||
.add_guards(route.take_guards())
|
||||
.route(route),
|
||||
)
|
||||
}
|
||||
|
||||
/// Register http service.
|
||||
///
|
||||
/// Http service is any type that implements `HttpServiceFactory` trait.
|
||||
///
|
||||
/// Actix web provides several services implementations:
|
||||
///
|
||||
/// * *Resource* is an entry in resource table which corresponds to requested URL.
|
||||
/// * *Scope* is a set of resources with common root path.
|
||||
/// * "StaticFiles" is a service for static files support
|
||||
pub fn service<F>(self, service: F) -> AppRouter<T, Out, Body, AppEntry<Out>>
|
||||
where
|
||||
F: HttpServiceFactory<Out> + 'static,
|
||||
{
|
||||
let fref = Rc::new(RefCell::new(None));
|
||||
|
||||
AppRouter {
|
||||
chain: self.chain,
|
||||
default: None,
|
||||
endpoint: AppEntry::new(fref.clone()),
|
||||
factory_ref: fref,
|
||||
data: self.data,
|
||||
config: self.config,
|
||||
services: vec![Box::new(ServiceFactoryWrapper::new(service))],
|
||||
external: Vec::new(),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set server host name.
|
||||
///
|
||||
/// Host name is used by application router as a hostname for url
|
||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
||||
/// html#method.host) documentation for more information.
|
||||
///
|
||||
/// By default host name is set to a "localhost" value.
|
||||
pub fn hostname(mut self, val: &str) -> Self {
|
||||
self.config.host = val.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
/// Enable content compression and decompression.
|
||||
pub fn enable_encoding(
|
||||
self,
|
||||
) -> AppRouter<
|
||||
impl NewService<
|
||||
Request = ServiceRequest<In>,
|
||||
Response = ServiceRequest<Decoder<Payload<Out>>>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
Decoder<Payload<Out>>,
|
||||
Encoder<Body>,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<Decoder<Payload<Out>>>,
|
||||
Response = ServiceResponse<Encoder<Body>>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
Out: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
use crate::middleware::encoding::{Compress, Decompress};
|
||||
|
||||
self.chain(Decompress::new()).wrap(Compress::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// Application router builder - Structure that follows the builder pattern
|
||||
/// for building application instances.
|
||||
pub struct AppRouter<C, P, B, T> {
|
||||
chain: C,
|
||||
endpoint: T,
|
||||
services: Vec<Box<ServiceFactory<P>>>,
|
||||
default: Option<Rc<HttpNewService<P>>>,
|
||||
factory_ref: Rc<RefCell<Option<AppRoutingFactory<P>>>>,
|
||||
data: Vec<Box<DataFactory>>,
|
||||
config: AppConfigInner,
|
||||
external: Vec<ResourceDef>,
|
||||
_t: PhantomData<(P, B)>,
|
||||
}
|
||||
|
||||
impl<C, P, B, T> AppRouter<C, P, B, T>
|
||||
where
|
||||
P: 'static,
|
||||
B: MessageBody,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
/// Run external configuration as part of the application building
|
||||
/// process
|
||||
///
|
||||
/// This function is useful for moving parts of configuration to a
|
||||
/// different module or even library. For example,
|
||||
/// some of the resource's configuration could be moved to different module.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// use actix_web::{web, middleware, App, HttpResponse};
|
||||
///
|
||||
/// // this function could be located in different module
|
||||
/// fn config<P>(cfg: &mut web::RouterConfig<P>) {
|
||||
/// cfg.service(web::resource("/test")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
|
||||
/// );
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .wrap(middleware::Logger::default())
|
||||
/// .configure(config) // <- register resources
|
||||
/// .route("/index.html", web::get().to(|| HttpResponse::Ok()));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn configure<F>(mut self, f: F) -> Self
|
||||
where
|
||||
F: Fn(&mut RouterConfig<P>),
|
||||
{
|
||||
let mut cfg = RouterConfig::new();
|
||||
f(&mut cfg);
|
||||
self.data.extend(cfg.data);
|
||||
self.services.extend(cfg.services);
|
||||
self.external.extend(cfg.external);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure route for a specific path.
|
||||
///
|
||||
/// This is a simplified version of the `App::service()` method.
|
||||
/// This method can not be could multiple times, in that case
|
||||
/// multiple resources with one route would be registered for same resource path.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .route("/test1", web::get().to(index))
|
||||
/// .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn route(self, path: &str, mut route: Route<P>) -> Self {
|
||||
pub fn route(self, path: &str, mut route: Route) -> Self {
|
||||
self.service(
|
||||
Resource::new(path)
|
||||
.add_guards(route.take_guards())
|
||||
@ -508,94 +188,31 @@ where
|
||||
/// * "StaticFiles" is a service for static files support
|
||||
pub fn service<F>(mut self, factory: F) -> Self
|
||||
where
|
||||
F: HttpServiceFactory<P> + 'static,
|
||||
F: HttpServiceFactory + 'static,
|
||||
{
|
||||
self.services
|
||||
.push(Box::new(ServiceFactoryWrapper::new(factory)));
|
||||
self
|
||||
}
|
||||
|
||||
/// Registers middleware, in the form of a middleware component (type),
|
||||
/// that runs during inbound and/or outbound processing in the request
|
||||
/// lifecycle (request -> response), modifying request/response as
|
||||
/// necessary, across all requests managed by the *Route*.
|
||||
/// Set server host name.
|
||||
///
|
||||
/// Use middleware when you need to read or modify *every* request or response in some way.
|
||||
/// Host name is used by application router as a hostname for url
|
||||
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
|
||||
/// html#method.host) documentation for more information.
|
||||
///
|
||||
pub fn wrap<M, B1, F>(
|
||||
self,
|
||||
mw: F,
|
||||
) -> AppRouter<
|
||||
C,
|
||||
P,
|
||||
B1,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
M: Transform<
|
||||
T::Service,
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
B1: MessageBody,
|
||||
F: IntoTransform<M, T::Service>,
|
||||
{
|
||||
let endpoint = apply_transform(mw, self.endpoint);
|
||||
AppRouter {
|
||||
endpoint,
|
||||
chain: self.chain,
|
||||
data: self.data,
|
||||
services: self.services,
|
||||
default: self.default,
|
||||
factory_ref: self.factory_ref,
|
||||
config: self.config,
|
||||
external: self.external,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers middleware, in the form of a closure, that runs during inbound
|
||||
/// and/or outbound processing in the request lifecycle (request -> response),
|
||||
/// modifying request/response as necessary, across all requests managed by
|
||||
/// the *Route*.
|
||||
///
|
||||
/// Use middleware when you need to read or modify *every* request or response in some way.
|
||||
///
|
||||
pub fn wrap_fn<B1, F, R>(
|
||||
self,
|
||||
mw: F,
|
||||
) -> AppRouter<
|
||||
C,
|
||||
P,
|
||||
B1,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
B1: MessageBody,
|
||||
F: FnMut(ServiceRequest<P>, &mut T::Service) -> R + Clone,
|
||||
R: IntoFuture<Item = ServiceResponse<B1>, Error = Error>,
|
||||
{
|
||||
self.wrap(mw)
|
||||
/// By default host name is set to a "localhost" value.
|
||||
pub fn hostname(mut self, val: &str) -> Self {
|
||||
self.config.host = val.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
/// Default resource to be used if no matching resource could be found.
|
||||
pub fn default_resource<F, U>(mut self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(Resource<P>) -> Resource<P, U>,
|
||||
F: FnOnce(Resource) -> Resource<U>,
|
||||
U: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -641,27 +258,128 @@ where
|
||||
self.external.push(rdef);
|
||||
self
|
||||
}
|
||||
|
||||
/// Registers middleware, in the form of a middleware component (type),
|
||||
/// that runs during inbound and/or outbound processing in the request
|
||||
/// lifecycle (request -> response), modifying request/response as
|
||||
/// necessary, across all requests managed by the *Application*.
|
||||
///
|
||||
/// Use middleware when you need to read or modify *every* request or response in some way.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// # use futures::Future;
|
||||
/// use actix_web::{middleware, web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .wrap(middleware::Logger::default())
|
||||
/// .route("/index.html", web::get().to(index));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn wrap<M, B1, F>(
|
||||
self,
|
||||
mw: F,
|
||||
) -> App<
|
||||
impl NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
B1,
|
||||
>
|
||||
where
|
||||
M: Transform<
|
||||
T::Service,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
B1: MessageBody,
|
||||
F: IntoTransform<M, T::Service>,
|
||||
{
|
||||
let endpoint = apply_transform(mw, self.endpoint);
|
||||
App {
|
||||
endpoint,
|
||||
data: self.data,
|
||||
services: self.services,
|
||||
default: self.default,
|
||||
factory_ref: self.factory_ref,
|
||||
config: self.config,
|
||||
external: self.external,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers middleware, in the form of a closure, that runs during inbound
|
||||
/// and/or outbound processing in the request lifecycle (request -> response),
|
||||
/// modifying request/response as necessary, across all requests managed by
|
||||
/// the *Application*.
|
||||
///
|
||||
/// Use middleware when you need to read or modify *every* request or response in some way.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_service::Service;
|
||||
/// # use futures::Future;
|
||||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .wrap_fn(|req, srv|
|
||||
/// srv.call(req).map(|mut res| {
|
||||
/// res.headers_mut().insert(
|
||||
/// CONTENT_TYPE, HeaderValue::from_static("text/plain"),
|
||||
/// );
|
||||
/// res
|
||||
/// }))
|
||||
/// .route("/index.html", web::get().to(index));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn wrap_fn<B1, F, R>(
|
||||
self,
|
||||
mw: F,
|
||||
) -> App<
|
||||
impl NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B1>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
B1,
|
||||
>
|
||||
where
|
||||
B1: MessageBody,
|
||||
F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
|
||||
R: IntoFuture<Item = ServiceResponse<B1>, Error = Error>,
|
||||
{
|
||||
self.wrap(mw)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, T, P: 'static, B: MessageBody> IntoNewService<AppInit<C, T, P, B>, ServerConfig>
|
||||
for AppRouter<C, P, B, T>
|
||||
impl<T, B> IntoNewService<AppInit<T, B>, ServerConfig> for App<T, B>
|
||||
where
|
||||
B: MessageBody,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
C: NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
fn into_new_service(self) -> AppInit<C, T, P, B> {
|
||||
fn into_new_service(self) -> AppInit<T, B> {
|
||||
AppInit {
|
||||
chain: self.chain,
|
||||
data: self.data,
|
||||
endpoint: self.endpoint,
|
||||
services: RefCell::new(self.services),
|
||||
@ -742,13 +460,13 @@ mod tests {
|
||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
fn md<S, P, B>(
|
||||
req: ServiceRequest<P>,
|
||||
fn md<S, B>(
|
||||
req: ServiceRequest,
|
||||
srv: &mut S,
|
||||
) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error>
|
||||
where
|
||||
S: Service<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
>,
|
||||
|
@ -6,7 +6,7 @@ use actix_http::{Request, Response};
|
||||
use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url};
|
||||
use actix_server_config::ServerConfig;
|
||||
use actix_service::boxed::{self, BoxedNewService, BoxedService};
|
||||
use actix_service::{fn_service, AndThen, NewService, Service, ServiceExt};
|
||||
use actix_service::{fn_service, NewService, Service};
|
||||
use futures::future::{ok, Either, FutureResult};
|
||||
use futures::{Async, Future, Poll};
|
||||
|
||||
@ -19,9 +19,8 @@ use crate::rmap::ResourceMap;
|
||||
use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse};
|
||||
|
||||
type Guards = Vec<Box<Guard>>;
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
|
||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
type BoxedResponse = Either<
|
||||
FutureResult<ServiceResponse, Error>,
|
||||
Box<Future<Item = ServiceResponse, Error = Error>>,
|
||||
@ -29,36 +28,28 @@ type BoxedResponse = Either<
|
||||
|
||||
/// Service factory to convert `Request` to a `ServiceRequest<S>`.
|
||||
/// It also executes data factories.
|
||||
pub struct AppInit<C, T, P, B>
|
||||
pub struct AppInit<T, B>
|
||||
where
|
||||
C: NewService<Request = ServiceRequest, Response = ServiceRequest<P>>,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
pub(crate) chain: C,
|
||||
pub(crate) endpoint: T,
|
||||
pub(crate) data: Vec<Box<DataFactory>>,
|
||||
pub(crate) config: RefCell<AppConfig>,
|
||||
pub(crate) services: RefCell<Vec<Box<ServiceFactory<P>>>>,
|
||||
pub(crate) default: Option<Rc<HttpNewService<P>>>,
|
||||
pub(crate) factory_ref: Rc<RefCell<Option<AppRoutingFactory<P>>>>,
|
||||
pub(crate) services: RefCell<Vec<Box<ServiceFactory>>>,
|
||||
pub(crate) default: Option<Rc<HttpNewService>>,
|
||||
pub(crate) factory_ref: Rc<RefCell<Option<AppRoutingFactory>>>,
|
||||
pub(crate) external: RefCell<Vec<ResourceDef>>,
|
||||
}
|
||||
|
||||
impl<C, T, P: 'static, B> NewService<ServerConfig> for AppInit<C, T, P, B>
|
||||
impl<T, B> NewService<ServerConfig> for AppInit<T, B>
|
||||
where
|
||||
C: NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -66,15 +57,15 @@ where
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = C::Error;
|
||||
type InitError = C::InitError;
|
||||
type Service = AndThen<AppInitService<C::Service, P>, T::Service>;
|
||||
type Future = AppInitResult<C, T, P, B>;
|
||||
type Error = T::Error;
|
||||
type InitError = T::InitError;
|
||||
type Service = AppInitService<T::Service, B>;
|
||||
type Future = AppInitResult<T, B>;
|
||||
|
||||
fn new_service(&self, cfg: &ServerConfig) -> Self::Future {
|
||||
// update resource default service
|
||||
let default = self.default.clone().unwrap_or_else(|| {
|
||||
Rc::new(boxed::new_service(fn_service(|req: ServiceRequest<P>| {
|
||||
Rc::new(boxed::new_service(fn_service(|req: ServiceRequest| {
|
||||
Ok(req.into_response(Response::NotFound().finish()))
|
||||
})))
|
||||
});
|
||||
@ -121,8 +112,6 @@ where
|
||||
rmap.finish(rmap.clone());
|
||||
|
||||
AppInitResult {
|
||||
chain: None,
|
||||
chain_fut: self.chain.new_service(&()),
|
||||
endpoint: None,
|
||||
endpoint_fut: self.endpoint.new_service(&()),
|
||||
data: self.data.iter().map(|s| s.construct()).collect(),
|
||||
@ -133,38 +122,29 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppInitResult<C, T, P, B>
|
||||
pub struct AppInitResult<T, B>
|
||||
where
|
||||
C: NewService,
|
||||
T: NewService,
|
||||
{
|
||||
chain: Option<C::Service>,
|
||||
endpoint: Option<T::Service>,
|
||||
chain_fut: C::Future,
|
||||
endpoint_fut: T::Future,
|
||||
rmap: Rc<ResourceMap>,
|
||||
data: Vec<Box<DataFactoryResult>>,
|
||||
config: AppConfig,
|
||||
_t: PhantomData<(P, B)>,
|
||||
_t: PhantomData<B>,
|
||||
}
|
||||
|
||||
impl<C, T, P, B> Future for AppInitResult<C, T, P, B>
|
||||
impl<T, B> Future for AppInitResult<T, B>
|
||||
where
|
||||
C: NewService<
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceRequest<P>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
{
|
||||
type Item = AndThen<AppInitService<C::Service, P>, T::Service>;
|
||||
type Error = C::InitError;
|
||||
type Item = AppInitService<T::Service, B>;
|
||||
type Error = T::InitError;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
let mut idx = 0;
|
||||
@ -177,28 +157,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
if self.chain.is_none() {
|
||||
if let Async::Ready(srv) = self.chain_fut.poll()? {
|
||||
self.chain = Some(srv);
|
||||
}
|
||||
}
|
||||
|
||||
if self.endpoint.is_none() {
|
||||
if let Async::Ready(srv) = self.endpoint_fut.poll()? {
|
||||
self.endpoint = Some(srv);
|
||||
}
|
||||
}
|
||||
|
||||
if self.chain.is_some() && self.endpoint.is_some() {
|
||||
Ok(Async::Ready(
|
||||
AppInitService {
|
||||
chain: self.chain.take().unwrap(),
|
||||
if self.endpoint.is_some() {
|
||||
Ok(Async::Ready(AppInitService {
|
||||
service: self.endpoint.take().unwrap(),
|
||||
rmap: self.rmap.clone(),
|
||||
config: self.config.clone(),
|
||||
pool: HttpRequestPool::create(),
|
||||
}
|
||||
.and_then(self.endpoint.take().unwrap()),
|
||||
))
|
||||
}))
|
||||
} else {
|
||||
Ok(Async::NotReady)
|
||||
}
|
||||
@ -206,27 +177,27 @@ where
|
||||
}
|
||||
|
||||
/// Service to convert `Request` to a `ServiceRequest<S>`
|
||||
pub struct AppInitService<C, P>
|
||||
pub struct AppInitService<T: Service, B>
|
||||
where
|
||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>,
|
||||
T: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
{
|
||||
chain: C,
|
||||
service: T,
|
||||
rmap: Rc<ResourceMap>,
|
||||
config: AppConfig,
|
||||
pool: &'static HttpRequestPool,
|
||||
}
|
||||
|
||||
impl<C, P> Service for AppInitService<C, P>
|
||||
impl<T, B> Service for AppInitService<T, B>
|
||||
where
|
||||
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>,
|
||||
T: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = ServiceRequest<P>;
|
||||
type Error = C::Error;
|
||||
type Future = C::Future;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = T::Error;
|
||||
type Future = T::Future;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.chain.poll_ready()
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: Request) -> Self::Future {
|
||||
@ -247,22 +218,22 @@ where
|
||||
self.pool,
|
||||
)
|
||||
};
|
||||
self.chain.call(ServiceRequest::from_parts(req, payload))
|
||||
self.service.call(ServiceRequest::from_parts(req, payload))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppRoutingFactory<P> {
|
||||
services: Rc<Vec<(ResourceDef, HttpNewService<P>, RefCell<Option<Guards>>)>>,
|
||||
default: Rc<HttpNewService<P>>,
|
||||
pub struct AppRoutingFactory {
|
||||
services: Rc<Vec<(ResourceDef, HttpNewService, RefCell<Option<Guards>>)>>,
|
||||
default: Rc<HttpNewService>,
|
||||
}
|
||||
|
||||
impl<P: 'static> NewService for AppRoutingFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for AppRoutingFactory {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = AppRouting<P>;
|
||||
type Future = AppRoutingFactoryResponse<P>;
|
||||
type Service = AppRouting;
|
||||
type Future = AppRoutingFactoryResponse;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
AppRoutingFactoryResponse {
|
||||
@ -283,23 +254,23 @@ impl<P: 'static> NewService for AppRoutingFactory<P> {
|
||||
}
|
||||
}
|
||||
|
||||
type HttpServiceFut<P> = Box<Future<Item = HttpService<P>, Error = ()>>;
|
||||
type HttpServiceFut = Box<Future<Item = HttpService, Error = ()>>;
|
||||
|
||||
/// Create app service
|
||||
#[doc(hidden)]
|
||||
pub struct AppRoutingFactoryResponse<P> {
|
||||
fut: Vec<CreateAppRoutingItem<P>>,
|
||||
default: Option<HttpService<P>>,
|
||||
default_fut: Option<Box<Future<Item = HttpService<P>, Error = ()>>>,
|
||||
pub struct AppRoutingFactoryResponse {
|
||||
fut: Vec<CreateAppRoutingItem>,
|
||||
default: Option<HttpService>,
|
||||
default_fut: Option<Box<Future<Item = HttpService, Error = ()>>>,
|
||||
}
|
||||
|
||||
enum CreateAppRoutingItem<P> {
|
||||
Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut<P>),
|
||||
Service(ResourceDef, Option<Guards>, HttpService<P>),
|
||||
enum CreateAppRoutingItem {
|
||||
Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut),
|
||||
Service(ResourceDef, Option<Guards>, HttpService),
|
||||
}
|
||||
|
||||
impl<P> Future for AppRoutingFactoryResponse<P> {
|
||||
type Item = AppRouting<P>;
|
||||
impl Future for AppRoutingFactoryResponse {
|
||||
type Item = AppRouting;
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
@ -360,14 +331,14 @@ impl<P> Future for AppRoutingFactoryResponse<P> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppRouting<P> {
|
||||
router: Router<HttpService<P>, Guards>,
|
||||
ready: Option<(ServiceRequest<P>, ResourceInfo)>,
|
||||
default: Option<HttpService<P>>,
|
||||
pub struct AppRouting {
|
||||
router: Router<HttpService, Guards>,
|
||||
ready: Option<(ServiceRequest, ResourceInfo)>,
|
||||
default: Option<HttpService>,
|
||||
}
|
||||
|
||||
impl<P> Service for AppRouting<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl Service for AppRouting {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Future = BoxedResponse;
|
||||
@ -380,7 +351,7 @@ impl<P> Service for AppRouting<P> {
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
||||
let res = self.router.recognize_mut_checked(&mut req, |req, guards| {
|
||||
if let Some(ref guards) = guards {
|
||||
for f in guards {
|
||||
@ -404,58 +375,25 @@ impl<P> Service for AppRouting<P> {
|
||||
}
|
||||
|
||||
/// Wrapper service for routing
|
||||
pub struct AppEntry<P> {
|
||||
factory: Rc<RefCell<Option<AppRoutingFactory<P>>>>,
|
||||
pub struct AppEntry {
|
||||
factory: Rc<RefCell<Option<AppRoutingFactory>>>,
|
||||
}
|
||||
|
||||
impl<P> AppEntry<P> {
|
||||
pub fn new(factory: Rc<RefCell<Option<AppRoutingFactory<P>>>>) -> Self {
|
||||
impl AppEntry {
|
||||
pub fn new(factory: Rc<RefCell<Option<AppRoutingFactory>>>) -> Self {
|
||||
AppEntry { factory }
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: 'static> NewService for AppEntry<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for AppEntry {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = AppRouting<P>;
|
||||
type Future = AppRoutingFactoryResponse<P>;
|
||||
type Service = AppRouting;
|
||||
type Future = AppRoutingFactoryResponse;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
self.factory.borrow_mut().as_mut().unwrap().new_service(&())
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct AppChain;
|
||||
|
||||
impl NewService for AppChain {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceRequest;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = AppChain;
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
ok(AppChain)
|
||||
}
|
||||
}
|
||||
|
||||
impl Service for AppChain {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceRequest;
|
||||
type Error = Error;
|
||||
type Future = FutureResult<Self::Response, Self::Error>;
|
||||
|
||||
#[inline]
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
ok(req)
|
||||
}
|
||||
}
|
||||
|
@ -19,25 +19,25 @@ use crate::service::{
|
||||
};
|
||||
|
||||
type Guards = Vec<Box<Guard>>;
|
||||
type HttpNewService<P> =
|
||||
boxed::BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type HttpNewService =
|
||||
boxed::BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
|
||||
/// Application configuration
|
||||
pub struct ServiceConfig<P> {
|
||||
pub struct ServiceConfig {
|
||||
config: AppConfig,
|
||||
root: bool,
|
||||
default: Rc<HttpNewService<P>>,
|
||||
default: Rc<HttpNewService>,
|
||||
services: Vec<(
|
||||
ResourceDef,
|
||||
HttpNewService<P>,
|
||||
HttpNewService,
|
||||
Option<Guards>,
|
||||
Option<Rc<ResourceMap>>,
|
||||
)>,
|
||||
}
|
||||
|
||||
impl<P: 'static> ServiceConfig<P> {
|
||||
impl ServiceConfig {
|
||||
/// Crate server settings instance
|
||||
pub(crate) fn new(config: AppConfig, default: Rc<HttpNewService<P>>) -> Self {
|
||||
pub(crate) fn new(config: AppConfig, default: Rc<HttpNewService>) -> Self {
|
||||
ServiceConfig {
|
||||
config,
|
||||
default,
|
||||
@ -55,7 +55,7 @@ impl<P: 'static> ServiceConfig<P> {
|
||||
self,
|
||||
) -> Vec<(
|
||||
ResourceDef,
|
||||
HttpNewService<P>,
|
||||
HttpNewService,
|
||||
Option<Guards>,
|
||||
Option<Rc<ResourceMap>>,
|
||||
)> {
|
||||
@ -77,7 +77,7 @@ impl<P: 'static> ServiceConfig<P> {
|
||||
}
|
||||
|
||||
/// Default resource
|
||||
pub fn default_service(&self) -> Rc<HttpNewService<P>> {
|
||||
pub fn default_service(&self) -> Rc<HttpNewService> {
|
||||
self.default.clone()
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ impl<P: 'static> ServiceConfig<P> {
|
||||
) where
|
||||
F: IntoNewService<S>,
|
||||
S: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -169,13 +169,13 @@ impl Default for AppConfigInner {
|
||||
/// Part of application configuration could be offloaded
|
||||
/// to set of external methods. This could help with
|
||||
/// modularization of big application configuration.
|
||||
pub struct RouterConfig<P: 'static> {
|
||||
pub(crate) services: Vec<Box<ServiceFactory<P>>>,
|
||||
pub struct RouterConfig {
|
||||
pub(crate) services: Vec<Box<ServiceFactory>>,
|
||||
pub(crate) data: Vec<Box<DataFactory>>,
|
||||
pub(crate) external: Vec<ResourceDef>,
|
||||
}
|
||||
|
||||
impl<P: 'static> RouterConfig<P> {
|
||||
impl RouterConfig {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
services: Vec::new(),
|
||||
@ -211,7 +211,7 @@ impl<P: 'static> RouterConfig<P> {
|
||||
/// Configure route for a specific path.
|
||||
///
|
||||
/// This is same as `App::route()` method.
|
||||
pub fn route(&mut self, path: &str, mut route: Route<P>) -> &mut Self {
|
||||
pub fn route(&mut self, path: &str, mut route: Route) -> &mut Self {
|
||||
self.service(
|
||||
Resource::new(path)
|
||||
.add_guards(route.take_guards())
|
||||
@ -224,7 +224,7 @@ impl<P: 'static> RouterConfig<P> {
|
||||
/// This is same as `App::service()` method.
|
||||
pub fn service<F>(&mut self, factory: F) -> &mut Self
|
||||
where
|
||||
F: HttpServiceFactory<P> + 'static,
|
||||
F: HttpServiceFactory + 'static,
|
||||
{
|
||||
self.services
|
||||
.push(Box::new(ServiceFactoryWrapper::new(factory)));
|
||||
@ -261,7 +261,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_data() {
|
||||
let cfg = |cfg: &mut RouterConfig<_>| {
|
||||
let cfg = |cfg: &mut RouterConfig| {
|
||||
cfg.data(10usize);
|
||||
};
|
||||
|
||||
@ -276,7 +276,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_data_factory() {
|
||||
let cfg = |cfg: &mut RouterConfig<_>| {
|
||||
let cfg = |cfg: &mut RouterConfig| {
|
||||
cfg.data_factory(|| Ok::<_, ()>(10usize));
|
||||
};
|
||||
|
||||
@ -288,7 +288,7 @@ mod tests {
|
||||
let resp = block_on(srv.call(req)).unwrap();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let cfg2 = |cfg: &mut RouterConfig<_>| {
|
||||
let cfg2 = |cfg: &mut RouterConfig| {
|
||||
cfg.data_factory(|| Ok::<_, ()>(10u32));
|
||||
};
|
||||
let mut srv = init_service(
|
||||
|
@ -88,12 +88,12 @@ impl<T> Clone for Data<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static, P> FromRequest<P> for Data<T> {
|
||||
impl<T: 'static> FromRequest for Data<T> {
|
||||
type Error = Error;
|
||||
type Future = Result<Self, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
if let Some(st) = req.app_config().extensions().get::<Data<T>>() {
|
||||
Ok(st.clone())
|
||||
} else {
|
||||
@ -232,12 +232,12 @@ impl<T> Clone for RouteData<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static, P> FromRequest<P> for RouteData<T> {
|
||||
impl<T: 'static> FromRequest for RouteData<T> {
|
||||
type Error = Error;
|
||||
type Future = Result<Self, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
if let Some(st) = req.route_data::<T>() {
|
||||
Ok(st.clone())
|
||||
} else {
|
||||
|
@ -10,7 +10,7 @@ use crate::request::HttpRequest;
|
||||
/// Trait implemented by types that can be extracted from request.
|
||||
///
|
||||
/// Types that implement this trait can be used with `Route` handlers.
|
||||
pub trait FromRequest<P>: Sized {
|
||||
pub trait FromRequest: Sized {
|
||||
/// The associated error which can be returned.
|
||||
type Error: Into<Error>;
|
||||
|
||||
@ -18,7 +18,7 @@ pub trait FromRequest<P>: Sized {
|
||||
type Future: IntoFuture<Item = Self, Error = Self::Error>;
|
||||
|
||||
/// Convert request to a Self
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future;
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future;
|
||||
|
||||
/// Convert request to a Self
|
||||
///
|
||||
@ -45,11 +45,11 @@ pub trait FromRequest<P>: Sized {
|
||||
/// name: String
|
||||
/// }
|
||||
///
|
||||
/// impl<P> FromRequest<P> for Thing {
|
||||
/// impl FromRequest for Thing {
|
||||
/// type Error = Error;
|
||||
/// type Future = Result<Self, Self::Error>;
|
||||
///
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
|
||||
/// if rand::random() {
|
||||
/// Ok(Thing { name: "thingy".into() })
|
||||
/// } else {
|
||||
@ -75,16 +75,16 @@ pub trait FromRequest<P>: Sized {
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<T: 'static, P> FromRequest<P> for Option<T>
|
||||
impl<T: 'static> FromRequest for Option<T>
|
||||
where
|
||||
T: FromRequest<P>,
|
||||
T: FromRequest,
|
||||
T::Future: 'static,
|
||||
{
|
||||
type Error = Error;
|
||||
type Future = Box<Future<Item = Option<T>, Error = Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||
Box::new(
|
||||
T::from_request(req, payload)
|
||||
.into_future()
|
||||
@ -116,11 +116,11 @@ where
|
||||
/// name: String
|
||||
/// }
|
||||
///
|
||||
/// impl<P> FromRequest<P> for Thing {
|
||||
/// impl FromRequest for Thing {
|
||||
/// type Error = Error;
|
||||
/// type Future = Result<Thing, Error>;
|
||||
///
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
|
||||
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
|
||||
/// if rand::random() {
|
||||
/// Ok(Thing { name: "thingy".into() })
|
||||
/// } else {
|
||||
@ -143,9 +143,9 @@ where
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<T: 'static, P> FromRequest<P> for Result<T, T::Error>
|
||||
impl<T: 'static> FromRequest for Result<T, T::Error>
|
||||
where
|
||||
T: FromRequest<P>,
|
||||
T: FromRequest,
|
||||
T::Future: 'static,
|
||||
T::Error: 'static,
|
||||
{
|
||||
@ -153,7 +153,7 @@ where
|
||||
type Future = Box<Future<Item = Result<T, T::Error>, Error = Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||
Box::new(
|
||||
T::from_request(req, payload)
|
||||
.into_future()
|
||||
@ -166,11 +166,11 @@ where
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<P> FromRequest<P> for () {
|
||||
impl FromRequest for () {
|
||||
type Error = Error;
|
||||
type Future = Result<(), Error>;
|
||||
|
||||
fn from_request(_: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -179,12 +179,12 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||
|
||||
/// FromRequest implementation for tuple
|
||||
#[doc(hidden)]
|
||||
impl<P, $($T: FromRequest<P> + 'static),+> FromRequest<P> for ($($T,)+)
|
||||
impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
|
||||
{
|
||||
type Error = Error;
|
||||
type Future = $fut_type<P, $($T),+>;
|
||||
type Future = $fut_type<$($T),+>;
|
||||
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||
$fut_type {
|
||||
items: <($(Option<$T>,)+)>::default(),
|
||||
futs: ($($T::from_request(req, payload).into_future(),)+),
|
||||
@ -193,12 +193,12 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct $fut_type<P, $($T: FromRequest<P>),+> {
|
||||
pub struct $fut_type<$($T: FromRequest),+> {
|
||||
items: ($(Option<$T>,)+),
|
||||
futs: ($(<$T::Future as futures::IntoFuture>::Future,)+),
|
||||
}
|
||||
|
||||
impl<P, $($T: FromRequest<P>),+> Future for $fut_type<P, $($T),+>
|
||||
impl<$($T: FromRequest),+> Future for $fut_type<$($T),+>
|
||||
{
|
||||
type Item = ($($T,)+);
|
||||
type Error = Error;
|
||||
|
@ -242,13 +242,13 @@ where
|
||||
}
|
||||
|
||||
/// Extract arguments from request
|
||||
pub struct Extract<P, T: FromRequest<P>, S> {
|
||||
pub struct Extract<T: FromRequest, S> {
|
||||
config: Rc<RefCell<Option<Rc<Extensions>>>>,
|
||||
service: S,
|
||||
_t: PhantomData<(P, T)>,
|
||||
_t: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<P, T: FromRequest<P>, S> Extract<P, T, S> {
|
||||
impl<T: FromRequest, S> Extract<T, S> {
|
||||
pub fn new(config: Rc<RefCell<Option<Rc<Extensions>>>>, service: S) -> Self {
|
||||
Extract {
|
||||
config,
|
||||
@ -258,16 +258,16 @@ impl<P, T: FromRequest<P>, S> Extract<P, T, S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, T: FromRequest<P>, S> NewService for Extract<P, T, S>
|
||||
impl<T: FromRequest, S> NewService for Extract<T, S>
|
||||
where
|
||||
S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void>
|
||||
+ Clone,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = (Error, ServiceRequest<P>);
|
||||
type Error = (Error, ServiceRequest);
|
||||
type InitError = ();
|
||||
type Service = ExtractService<P, T, S>;
|
||||
type Service = ExtractService<T, S>;
|
||||
type Future = FutureResult<Self::Service, ()>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
@ -279,27 +279,27 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExtractService<P, T: FromRequest<P>, S> {
|
||||
pub struct ExtractService<T: FromRequest, S> {
|
||||
config: Option<Rc<Extensions>>,
|
||||
service: S,
|
||||
_t: PhantomData<(P, T)>,
|
||||
_t: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<P, T: FromRequest<P>, S> Service for ExtractService<P, T, S>
|
||||
impl<T: FromRequest, S> Service for ExtractService<T, S>
|
||||
where
|
||||
S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void>
|
||||
+ Clone,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = (Error, ServiceRequest<P>);
|
||||
type Future = ExtractResponse<P, T, S>;
|
||||
type Error = (Error, ServiceRequest);
|
||||
type Future = ExtractResponse<T, S>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
let (mut req, mut payload) = req.into_parts();
|
||||
req.set_route_data(self.config.clone());
|
||||
let fut = T::from_request(&req, &mut payload).into_future();
|
||||
@ -313,19 +313,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExtractResponse<P, T: FromRequest<P>, S: Service> {
|
||||
req: Option<(HttpRequest, Payload<P>)>,
|
||||
pub struct ExtractResponse<T: FromRequest, S: Service> {
|
||||
req: Option<(HttpRequest, Payload)>,
|
||||
service: S,
|
||||
fut: <T::Future as IntoFuture>::Future,
|
||||
fut_s: Option<S::Future>,
|
||||
}
|
||||
|
||||
impl<P, T: FromRequest<P>, S> Future for ExtractResponse<P, T, S>
|
||||
impl<T: FromRequest, S> Future for ExtractResponse<T, S>
|
||||
where
|
||||
S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void>,
|
||||
{
|
||||
type Item = ServiceResponse;
|
||||
type Error = (Error, ServiceRequest<P>);
|
||||
type Error = (Error, ServiceRequest);
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
if let Some(ref mut fut) = self.fut_s {
|
||||
|
@ -133,7 +133,6 @@ pub mod dev {
|
||||
//! use actix_web::dev::*;
|
||||
//! ```
|
||||
|
||||
pub use crate::app::AppRouter;
|
||||
pub use crate::config::{AppConfig, ServiceConfig};
|
||||
pub use crate::info::ConnectionInfo;
|
||||
pub use crate::rmap::ResourceMap;
|
||||
@ -143,6 +142,7 @@ pub mod dev {
|
||||
pub use crate::types::readlines::Readlines;
|
||||
|
||||
pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||
pub use actix_http::encoding::Decoder as Decompress;
|
||||
pub use actix_http::ResponseBuilder as HttpResponseBuilder;
|
||||
pub use actix_http::{
|
||||
Extensions, Payload, PayloadStream, RequestHead, ResponseHead,
|
||||
|
@ -41,11 +41,11 @@ impl<B> BodyEncoding for Response<B> {
|
||||
/// To disable compression set encoding to `ContentEncoding::Identity` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, middleware::encoding, App, HttpResponse};
|
||||
/// use actix_web::{web, middleware, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .wrap(encoding::Compress::default())
|
||||
/// .wrap(middleware::Compress::default())
|
||||
/// .service(
|
||||
/// web::resource("/test")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
@ -68,12 +68,12 @@ impl Default for Compress {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P, B> Transform<S> for Compress
|
||||
impl<S, B> Transform<S> for Compress
|
||||
where
|
||||
B: MessageBody,
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<Encoder<B>>;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
@ -93,21 +93,21 @@ pub struct CompressMiddleware<S> {
|
||||
encoding: ContentEncoding,
|
||||
}
|
||||
|
||||
impl<S, P, B> Service for CompressMiddleware<S>
|
||||
impl<S, B> Service for CompressMiddleware<S>
|
||||
where
|
||||
B: MessageBody,
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<Encoder<B>>;
|
||||
type Error = S::Error;
|
||||
type Future = CompressResponse<S, P, B>;
|
||||
type Future = CompressResponse<S, B>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
// negotiate content-encoding
|
||||
let encoding = if let Some(val) = req.headers().get(&ACCEPT_ENCODING) {
|
||||
if let Ok(enc) = val.to_str() {
|
||||
@ -128,20 +128,20 @@ where
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct CompressResponse<S, P, B>
|
||||
pub struct CompressResponse<S, B>
|
||||
where
|
||||
S: Service,
|
||||
B: MessageBody,
|
||||
{
|
||||
fut: S::Future,
|
||||
encoding: ContentEncoding,
|
||||
_t: PhantomData<(P, B)>,
|
||||
_t: PhantomData<(B)>,
|
||||
}
|
||||
|
||||
impl<S, P, B> Future for CompressResponse<S, P, B>
|
||||
impl<S, B> Future for CompressResponse<S, B>
|
||||
where
|
||||
B: MessageBody,
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
{
|
||||
type Item = ServiceResponse<Encoder<B>>;
|
||||
type Error = S::Error;
|
||||
|
@ -475,9 +475,9 @@ fn cors<'a>(
|
||||
parts.as_mut()
|
||||
}
|
||||
|
||||
impl<S, P, B> IntoTransform<CorsFactory, S> for Cors
|
||||
impl<S, B> IntoTransform<CorsFactory, S> for Cors
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
B: 'static,
|
||||
@ -537,14 +537,14 @@ pub struct CorsFactory {
|
||||
inner: Rc<Inner>,
|
||||
}
|
||||
|
||||
impl<S, P, B> Transform<S> for CorsFactory
|
||||
impl<S, B> Transform<S> for CorsFactory
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
@ -678,14 +678,14 @@ impl Inner {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P, B> Service for CorsMiddleware<S>
|
||||
impl<S, B> Service for CorsMiddleware<S>
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type Future = Either<
|
||||
@ -697,7 +697,7 @@ where
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
if self.inner.preflight && Method::OPTIONS == *req.method() {
|
||||
if let Err(e) = self
|
||||
.inner
|
||||
@ -815,13 +815,12 @@ mod tests {
|
||||
use actix_service::{FnService, Transform};
|
||||
|
||||
use super::*;
|
||||
use crate::dev::PayloadStream;
|
||||
use crate::test::{self, block_on, TestRequest};
|
||||
|
||||
impl Cors {
|
||||
fn finish<S, P, B>(self, srv: S) -> CorsMiddleware<S>
|
||||
fn finish<S, B>(self, srv: S) -> CorsMiddleware<S>
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>
|
||||
+ 'static,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
@ -1057,7 +1056,7 @@ mod tests {
|
||||
.allowed_headers(exposed_headers.clone())
|
||||
.expose_headers(exposed_headers.clone())
|
||||
.allowed_header(header::CONTENT_TYPE)
|
||||
.finish(FnService::new(move |req: ServiceRequest<PayloadStream>| {
|
||||
.finish(FnService::new(move |req: ServiceRequest| {
|
||||
req.into_response(
|
||||
HttpResponse::Ok().header(header::VARY, "Accept").finish(),
|
||||
)
|
||||
|
@ -1,75 +0,0 @@
|
||||
//! Chain service for decompressing request payload.
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use actix_http::encoding::Decoder;
|
||||
use actix_service::{NewService, Service};
|
||||
use bytes::Bytes;
|
||||
use futures::future::{ok, FutureResult};
|
||||
use futures::{Async, Poll, Stream};
|
||||
|
||||
use crate::dev::Payload;
|
||||
use crate::error::{Error, PayloadError};
|
||||
use crate::service::ServiceRequest;
|
||||
|
||||
/// `Middleware` for decompressing request's payload.
|
||||
/// `Decompress` middleware must be added with `App::chain()` method.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, middleware::encoding, App, HttpResponse};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new()
|
||||
/// .chain(encoding::Decompress::new())
|
||||
/// .service(
|
||||
/// web::resource("/test")
|
||||
/// .route(web::get().to(|| HttpResponse::Ok()))
|
||||
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Decompress<P>(PhantomData<P>);
|
||||
|
||||
impl<P> Decompress<P>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Decompress(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> NewService for Decompress<P>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceRequest<Decoder<Payload<P>>>;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = Decompress<P>;
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
ok(Decompress(PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Service for Decompress<P>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Response = ServiceRequest<Decoder<Payload<P>>>;
|
||||
type Error = Error;
|
||||
type Future = FutureResult<Self::Response, Self::Error>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
let (req, payload) = req.into_parts();
|
||||
let payload = Decoder::from_headers(payload, req.headers());
|
||||
ok(ServiceRequest::from_parts(req, Payload::Stream(payload)))
|
||||
}
|
||||
}
|
@ -85,12 +85,12 @@ impl DefaultHeaders {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P, B> Transform<S> for DefaultHeaders
|
||||
impl<S, B> Transform<S> for DefaultHeaders
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
@ -110,12 +110,12 @@ pub struct DefaultHeadersMiddleware<S> {
|
||||
inner: Rc<Inner>,
|
||||
}
|
||||
|
||||
impl<S, P, B> Service for DefaultHeadersMiddleware<S>
|
||||
impl<S, B> Service for DefaultHeadersMiddleware<S>
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||
@ -124,7 +124,7 @@ where
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
let inner = self.inner.clone();
|
||||
|
||||
Box::new(self.service.call(req).map(move |mut res| {
|
||||
@ -171,7 +171,7 @@ mod tests {
|
||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||
|
||||
let req = TestRequest::default().to_srv_request();
|
||||
let srv = FnService::new(|req: ServiceRequest<_>| {
|
||||
let srv = FnService::new(|req: ServiceRequest| {
|
||||
req.into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish())
|
||||
});
|
||||
let mut mw = block_on(
|
||||
@ -186,7 +186,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_content_type() {
|
||||
let srv = FnService::new(|req: ServiceRequest<_>| {
|
||||
let srv = FnService::new(|req: ServiceRequest| {
|
||||
req.into_response(HttpResponse::Ok().finish())
|
||||
});
|
||||
let mut mw =
|
||||
|
@ -81,18 +81,14 @@ impl<B> ErrorHandlers<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P, B> Transform<S> for ErrorHandlers<B>
|
||||
impl<S, B> Transform<S> for ErrorHandlers<B>
|
||||
where
|
||||
S: Service<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
@ -113,18 +109,14 @@ pub struct ErrorHandlersMiddleware<S, B> {
|
||||
handlers: Rc<HashMap<StatusCode, Box<ErrorHandler<B>>>>,
|
||||
}
|
||||
|
||||
impl<S, P, B> Service for ErrorHandlersMiddleware<S, B>
|
||||
impl<S, B> Service for ErrorHandlersMiddleware<S, B>
|
||||
where
|
||||
S: Service<
|
||||
Request = ServiceRequest<P>,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||
@ -133,7 +125,7 @@ where
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
let handlers = self.handlers.clone();
|
||||
|
||||
Box::new(self.service.call(req).and_then(move |res| {
|
||||
@ -169,7 +161,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_handler() {
|
||||
let srv = FnService::new(|req: ServiceRequest<_>| {
|
||||
let srv = FnService::new(|req: ServiceRequest| {
|
||||
req.into_response(HttpResponse::InternalServerError().finish())
|
||||
});
|
||||
|
||||
@ -195,7 +187,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_handler_async() {
|
||||
let srv = FnService::new(|req: ServiceRequest<_>| {
|
||||
let srv = FnService::new(|req: ServiceRequest| {
|
||||
req.into_response(HttpResponse::InternalServerError().finish())
|
||||
});
|
||||
|
||||
|
@ -140,12 +140,12 @@ struct IdentityItem {
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
impl<P> FromRequest<P> for Identity {
|
||||
impl FromRequest for Identity {
|
||||
type Error = Error;
|
||||
type Future = Result<Identity, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
Ok(Identity(req.clone()))
|
||||
}
|
||||
}
|
||||
@ -159,7 +159,7 @@ pub trait IdentityPolicy: Sized + 'static {
|
||||
type ResponseFuture: IntoFuture<Item = (), Error = Error>;
|
||||
|
||||
/// Parse the session from request and load data from a service identity.
|
||||
fn from_request<P>(&self, request: &mut ServiceRequest<P>) -> Self::Future;
|
||||
fn from_request(&self, request: &mut ServiceRequest) -> Self::Future;
|
||||
|
||||
/// Write changes to response
|
||||
fn to_response<B>(
|
||||
@ -198,16 +198,15 @@ impl<T> IdentityService<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T, P, B> Transform<S> for IdentityService<T>
|
||||
impl<S, T, B> Transform<S> for IdentityService<T>
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>> + 'static,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>> + 'static,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
T: IdentityPolicy,
|
||||
P: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
@ -228,16 +227,15 @@ pub struct IdentityServiceMiddleware<S, T> {
|
||||
service: Rc<RefCell<S>>,
|
||||
}
|
||||
|
||||
impl<S, T, P, B> Service for IdentityServiceMiddleware<S, T>
|
||||
impl<S, T, B> Service for IdentityServiceMiddleware<S, T>
|
||||
where
|
||||
P: 'static,
|
||||
B: 'static,
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>> + 'static,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>> + 'static,
|
||||
S::Future: 'static,
|
||||
S::Error: 'static,
|
||||
T: IdentityPolicy,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = S::Error;
|
||||
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
|
||||
@ -246,7 +244,7 @@ where
|
||||
self.service.borrow_mut().poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
||||
let srv = self.service.clone();
|
||||
let backend = self.backend.clone();
|
||||
|
||||
@ -348,7 +346,7 @@ impl CookieIdentityInner {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load<T>(&self, req: &ServiceRequest<T>) -> Option<String> {
|
||||
fn load(&self, req: &ServiceRequest) -> Option<String> {
|
||||
if let Ok(cookies) = req.cookies() {
|
||||
for cookie in cookies.iter() {
|
||||
if cookie.name() == self.name {
|
||||
@ -445,7 +443,7 @@ impl IdentityPolicy for CookieIdentityPolicy {
|
||||
type Future = Result<Option<String>, Error>;
|
||||
type ResponseFuture = Result<(), Error>;
|
||||
|
||||
fn from_request<P>(&self, req: &mut ServiceRequest<P>) -> Self::Future {
|
||||
fn from_request(&self, req: &mut ServiceRequest) -> Self::Future {
|
||||
Ok(self.0.load(req))
|
||||
}
|
||||
|
||||
|
@ -114,12 +114,12 @@ impl Default for Logger {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P, B> Transform<S> for Logger
|
||||
impl<S, B> Transform<S> for Logger
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
B: MessageBody,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<StreamLog<B>>;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
@ -140,21 +140,21 @@ pub struct LoggerMiddleware<S> {
|
||||
service: S,
|
||||
}
|
||||
|
||||
impl<S, P, B> Service for LoggerMiddleware<S>
|
||||
impl<S, B> Service for LoggerMiddleware<S>
|
||||
where
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
B: MessageBody,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<StreamLog<B>>;
|
||||
type Error = S::Error;
|
||||
type Future = LoggerResponse<S, P, B>;
|
||||
type Future = LoggerResponse<S, B>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
if self.inner.exclude.contains(req.path()) {
|
||||
LoggerResponse {
|
||||
fut: self.service.call(req),
|
||||
@ -180,7 +180,7 @@ where
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct LoggerResponse<S, P, B>
|
||||
pub struct LoggerResponse<S, B>
|
||||
where
|
||||
B: MessageBody,
|
||||
S: Service,
|
||||
@ -188,13 +188,13 @@ where
|
||||
fut: S::Future,
|
||||
time: time::Tm,
|
||||
format: Option<Format>,
|
||||
_t: PhantomData<(P, B)>,
|
||||
_t: PhantomData<(B,)>,
|
||||
}
|
||||
|
||||
impl<S, P, B> Future for LoggerResponse<S, P, B>
|
||||
impl<S, B> Future for LoggerResponse<S, B>
|
||||
where
|
||||
B: MessageBody,
|
||||
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
|
||||
{
|
||||
type Item = ServiceResponse<StreamLog<B>>;
|
||||
type Error = S::Error;
|
||||
@ -402,7 +402,7 @@ impl FormatText {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_request<P>(&mut self, now: time::Tm, req: &ServiceRequest<P>) {
|
||||
fn render_request(&mut self, now: time::Tm, req: &ServiceRequest) {
|
||||
match *self {
|
||||
FormatText::RequestLine => {
|
||||
*self = if req.query_string().is_empty() {
|
||||
@ -464,7 +464,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_logger() {
|
||||
let srv = FnService::new(|req: ServiceRequest<_>| {
|
||||
let srv = FnService::new(|req: ServiceRequest| {
|
||||
req.into_response(
|
||||
HttpResponse::build(StatusCode::OK)
|
||||
.header("X-Test", "ttt")
|
||||
|
@ -1,14 +1,6 @@
|
||||
//! Middlewares
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
mod compress;
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
mod decompress;
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
pub mod encoding {
|
||||
//! Middlewares for compressing/decompressing payloads.
|
||||
pub use super::compress::{BodyEncoding, Compress};
|
||||
pub use super::decompress::Decompress;
|
||||
}
|
||||
pub use self::compress::{BodyEncoding, Compress};
|
||||
|
||||
pub mod cors;
|
||||
mod defaultheaders;
|
||||
|
@ -265,12 +265,12 @@ impl Drop for HttpRequest {
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<P> FromRequest<P> for HttpRequest {
|
||||
impl FromRequest for HttpRequest {
|
||||
type Error = Error;
|
||||
type Future = Result<Self, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
Ok(req.clone())
|
||||
}
|
||||
}
|
||||
|
119
src/resource.rs
119
src/resource.rs
@ -17,9 +17,8 @@ use crate::responder::Responder;
|
||||
use crate::route::{CreateRouteService, Route, RouteService};
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
|
||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
|
||||
/// *Resource* is an entry in resources table which corresponds to requested URL.
|
||||
///
|
||||
@ -43,18 +42,18 @@ type HttpNewService<P> =
|
||||
///
|
||||
/// If no matching route could be found, *405* response code get returned.
|
||||
/// Default behavior could be overriden with `default_resource()` method.
|
||||
pub struct Resource<P, T = ResourceEndpoint<P>> {
|
||||
pub struct Resource<T = ResourceEndpoint> {
|
||||
endpoint: T,
|
||||
rdef: String,
|
||||
name: Option<String>,
|
||||
routes: Vec<Route<P>>,
|
||||
routes: Vec<Route>,
|
||||
guards: Vec<Box<Guard>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>,
|
||||
factory_ref: Rc<RefCell<Option<ResourceFactory<P>>>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
|
||||
factory_ref: Rc<RefCell<Option<ResourceFactory>>>,
|
||||
}
|
||||
|
||||
impl<P> Resource<P> {
|
||||
pub fn new(path: &str) -> Resource<P> {
|
||||
impl Resource {
|
||||
pub fn new(path: &str) -> Resource {
|
||||
let fref = Rc::new(RefCell::new(None));
|
||||
|
||||
Resource {
|
||||
@ -69,11 +68,10 @@ impl<P> Resource<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, T> Resource<P, T>
|
||||
impl<T> Resource<T>
|
||||
where
|
||||
P: 'static,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -154,7 +152,7 @@ where
|
||||
/// # fn post_handler() {}
|
||||
/// # fn delete_handler() {}
|
||||
/// ```
|
||||
pub fn route(mut self, route: Route<P>) -> Self {
|
||||
pub fn route(mut self, route: Route) -> Self {
|
||||
self.routes.push(route.finish());
|
||||
self
|
||||
}
|
||||
@ -182,7 +180,7 @@ where
|
||||
pub fn to<F, I, R>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: Factory<I, R> + 'static,
|
||||
I: FromRequest<P> + 'static,
|
||||
I: FromRequest + 'static,
|
||||
R: Responder + 'static,
|
||||
{
|
||||
self.routes.push(Route::new().to(handler));
|
||||
@ -216,7 +214,7 @@ where
|
||||
pub fn to_async<F, I, R>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: AsyncFactory<I, R>,
|
||||
I: FromRequest<P> + 'static,
|
||||
I: FromRequest + 'static,
|
||||
R: IntoFuture + 'static,
|
||||
R::Item: Into<Response>,
|
||||
R::Error: Into<Error>,
|
||||
@ -236,9 +234,8 @@ where
|
||||
self,
|
||||
mw: F,
|
||||
) -> Resource<
|
||||
P,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -247,7 +244,7 @@ where
|
||||
where
|
||||
M: Transform<
|
||||
T::Service,
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -302,16 +299,15 @@ where
|
||||
self,
|
||||
mw: F,
|
||||
) -> Resource<
|
||||
P,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
F: FnMut(ServiceRequest<P>, &mut T::Service) -> R + Clone,
|
||||
F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
|
||||
R: IntoFuture<Item = ServiceResponse, Error = Error>,
|
||||
{
|
||||
self.wrap(mw)
|
||||
@ -322,10 +318,10 @@ where
|
||||
/// default handler from `App` or `Scope`.
|
||||
pub fn default_resource<F, R, U>(mut self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(Resource<P>) -> R,
|
||||
F: FnOnce(Resource) -> R,
|
||||
R: IntoNewService<U>,
|
||||
U: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
> + 'static,
|
||||
@ -339,17 +335,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, T> HttpServiceFactory<P> for Resource<P, T>
|
||||
impl<T> HttpServiceFactory for Resource<T>
|
||||
where
|
||||
P: 'static,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
fn register(mut self, config: &mut ServiceConfig<P>) {
|
||||
fn register(mut self, config: &mut ServiceConfig) {
|
||||
let guards = if self.guards.is_empty() {
|
||||
None
|
||||
} else {
|
||||
@ -367,10 +362,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, T> IntoNewService<T> for Resource<P, T>
|
||||
impl<T> IntoNewService<T> for Resource<T>
|
||||
where
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -386,18 +381,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ResourceFactory<P> {
|
||||
routes: Vec<Route<P>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>,
|
||||
pub struct ResourceFactory {
|
||||
routes: Vec<Route>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
|
||||
}
|
||||
|
||||
impl<P: 'static> NewService for ResourceFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for ResourceFactory {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ResourceService<P>;
|
||||
type Future = CreateResourceService<P>;
|
||||
type Service = ResourceService;
|
||||
type Future = CreateResourceService;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
let default_fut = if let Some(ref default) = *self.default.borrow() {
|
||||
@ -418,19 +413,19 @@ impl<P: 'static> NewService for ResourceFactory<P> {
|
||||
}
|
||||
}
|
||||
|
||||
enum CreateRouteServiceItem<P> {
|
||||
Future(CreateRouteService<P>),
|
||||
Service(RouteService<P>),
|
||||
enum CreateRouteServiceItem {
|
||||
Future(CreateRouteService),
|
||||
Service(RouteService),
|
||||
}
|
||||
|
||||
pub struct CreateResourceService<P> {
|
||||
fut: Vec<CreateRouteServiceItem<P>>,
|
||||
default: Option<HttpService<P>>,
|
||||
default_fut: Option<Box<Future<Item = HttpService<P>, Error = ()>>>,
|
||||
pub struct CreateResourceService {
|
||||
fut: Vec<CreateRouteServiceItem>,
|
||||
default: Option<HttpService>,
|
||||
default_fut: Option<Box<Future<Item = HttpService, Error = ()>>>,
|
||||
}
|
||||
|
||||
impl<P> Future for CreateResourceService<P> {
|
||||
type Item = ResourceService<P>;
|
||||
impl Future for CreateResourceService {
|
||||
type Item = ResourceService;
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
@ -477,13 +472,13 @@ impl<P> Future for CreateResourceService<P> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ResourceService<P> {
|
||||
routes: Vec<RouteService<P>>,
|
||||
default: Option<HttpService<P>>,
|
||||
pub struct ResourceService {
|
||||
routes: Vec<RouteService>,
|
||||
default: Option<HttpService>,
|
||||
}
|
||||
|
||||
impl<P> Service for ResourceService<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl Service for ResourceService {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Future = Either<
|
||||
@ -495,7 +490,7 @@ impl<P> Service for ResourceService<P> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
||||
for route in self.routes.iter_mut() {
|
||||
if route.check(&mut req) {
|
||||
return route.call(req);
|
||||
@ -514,23 +509,23 @@ impl<P> Service for ResourceService<P> {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct ResourceEndpoint<P> {
|
||||
factory: Rc<RefCell<Option<ResourceFactory<P>>>>,
|
||||
pub struct ResourceEndpoint {
|
||||
factory: Rc<RefCell<Option<ResourceFactory>>>,
|
||||
}
|
||||
|
||||
impl<P> ResourceEndpoint<P> {
|
||||
fn new(factory: Rc<RefCell<Option<ResourceFactory<P>>>>) -> Self {
|
||||
impl ResourceEndpoint {
|
||||
fn new(factory: Rc<RefCell<Option<ResourceFactory>>>) -> Self {
|
||||
ResourceEndpoint { factory }
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: 'static> NewService for ResourceEndpoint<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for ResourceEndpoint {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ResourceService<P>;
|
||||
type Future = CreateResourceService<P>;
|
||||
type Service = ResourceService;
|
||||
type Future = CreateResourceService;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
self.factory.borrow_mut().as_mut().unwrap().new_service(&())
|
||||
@ -550,13 +545,13 @@ mod tests {
|
||||
use crate::test::{call_success, init_service, TestRequest};
|
||||
use crate::{web, App, Error, HttpResponse};
|
||||
|
||||
fn md<S, P, B>(
|
||||
req: ServiceRequest<P>,
|
||||
fn md<S, B>(
|
||||
req: ServiceRequest,
|
||||
srv: &mut S,
|
||||
) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error>
|
||||
where
|
||||
S: Service<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
>,
|
||||
|
96
src/route.rs
96
src/route.rs
@ -1,5 +1,4 @@
|
||||
use std::cell::RefCell;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
|
||||
use actix_http::{http::Method, Error, Extensions, Response};
|
||||
@ -42,16 +41,16 @@ type BoxedRouteNewService<Req, Res> = Box<
|
||||
///
|
||||
/// Route uses builder-like pattern for configuration.
|
||||
/// If handler is not explicitly set, default *404 Not Found* handler is used.
|
||||
pub struct Route<P> {
|
||||
service: BoxedRouteNewService<ServiceRequest<P>, ServiceResponse>,
|
||||
pub struct Route {
|
||||
service: BoxedRouteNewService<ServiceRequest, ServiceResponse>,
|
||||
guards: Rc<Vec<Box<Guard>>>,
|
||||
data: Option<Extensions>,
|
||||
data_ref: Rc<RefCell<Option<Rc<Extensions>>>>,
|
||||
}
|
||||
|
||||
impl<P: 'static> Route<P> {
|
||||
impl Route {
|
||||
/// Create new route which matches any request.
|
||||
pub fn new() -> Route<P> {
|
||||
pub fn new() -> Route {
|
||||
let data_ref = Rc::new(RefCell::new(None));
|
||||
Route {
|
||||
service: Box::new(RouteNewService::new(Extract::new(
|
||||
@ -74,13 +73,13 @@ impl<P: 'static> Route<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> NewService for Route<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for Route {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = RouteService<P>;
|
||||
type Future = CreateRouteService<P>;
|
||||
type Service = RouteService;
|
||||
type Future = CreateRouteService;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
CreateRouteService {
|
||||
@ -90,17 +89,16 @@ impl<P> NewService for Route<P> {
|
||||
}
|
||||
}
|
||||
|
||||
type RouteFuture<P> = Box<
|
||||
Future<Item = BoxedRouteService<ServiceRequest<P>, ServiceResponse>, Error = ()>,
|
||||
>;
|
||||
type RouteFuture =
|
||||
Box<Future<Item = BoxedRouteService<ServiceRequest, ServiceResponse>, Error = ()>>;
|
||||
|
||||
pub struct CreateRouteService<P> {
|
||||
fut: RouteFuture<P>,
|
||||
pub struct CreateRouteService {
|
||||
fut: RouteFuture,
|
||||
guards: Rc<Vec<Box<Guard>>>,
|
||||
}
|
||||
|
||||
impl<P> Future for CreateRouteService<P> {
|
||||
type Item = RouteService<P>;
|
||||
impl Future for CreateRouteService {
|
||||
type Item = RouteService;
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
@ -114,13 +112,13 @@ impl<P> Future for CreateRouteService<P> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RouteService<P> {
|
||||
service: BoxedRouteService<ServiceRequest<P>, ServiceResponse>,
|
||||
pub struct RouteService {
|
||||
service: BoxedRouteService<ServiceRequest, ServiceResponse>,
|
||||
guards: Rc<Vec<Box<Guard>>>,
|
||||
}
|
||||
|
||||
impl<P> RouteService<P> {
|
||||
pub fn check(&self, req: &mut ServiceRequest<P>) -> bool {
|
||||
impl RouteService {
|
||||
pub fn check(&self, req: &mut ServiceRequest) -> bool {
|
||||
for f in self.guards.iter() {
|
||||
if !f.check(req.head()) {
|
||||
return false;
|
||||
@ -130,8 +128,8 @@ impl<P> RouteService<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Service for RouteService<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl Service for RouteService {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Future = Either<
|
||||
@ -143,12 +141,12 @@ impl<P> Service for RouteService<P> {
|
||||
self.service.poll_ready()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
self.service.call(req)
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: 'static> Route<P> {
|
||||
impl Route {
|
||||
/// Add method guard to the route.
|
||||
///
|
||||
/// ```rust
|
||||
@ -235,10 +233,10 @@ impl<P: 'static> Route<P> {
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
pub fn to<F, T, R>(mut self, handler: F) -> Route<P>
|
||||
pub fn to<F, T, R>(mut self, handler: F) -> Route
|
||||
where
|
||||
F: Factory<T, R> + 'static,
|
||||
T: FromRequest<P> + 'static,
|
||||
T: FromRequest + 'static,
|
||||
R: Responder + 'static,
|
||||
{
|
||||
self.service = Box::new(RouteNewService::new(Extract::new(
|
||||
@ -278,7 +276,7 @@ impl<P: 'static> Route<P> {
|
||||
pub fn to_async<F, T, R>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: AsyncFactory<T, R>,
|
||||
T: FromRequest<P> + 'static,
|
||||
T: FromRequest + 'static,
|
||||
R: IntoFuture + 'static,
|
||||
R::Item: Into<Response>,
|
||||
R::Error: Into<Error>,
|
||||
@ -321,49 +319,45 @@ impl<P: 'static> Route<P> {
|
||||
}
|
||||
}
|
||||
|
||||
struct RouteNewService<P, T>
|
||||
struct RouteNewService<T>
|
||||
where
|
||||
T: NewService<Request = ServiceRequest<P>, Error = (Error, ServiceRequest<P>)>,
|
||||
T: NewService<Request = ServiceRequest, Error = (Error, ServiceRequest)>,
|
||||
{
|
||||
service: T,
|
||||
_t: PhantomData<P>,
|
||||
}
|
||||
|
||||
impl<P: 'static, T> RouteNewService<P, T>
|
||||
impl<T> RouteNewService<T>
|
||||
where
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = (Error, ServiceRequest<P>),
|
||||
Error = (Error, ServiceRequest),
|
||||
>,
|
||||
T::Future: 'static,
|
||||
T::Service: 'static,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
pub fn new(service: T) -> Self {
|
||||
RouteNewService {
|
||||
service,
|
||||
_t: PhantomData,
|
||||
}
|
||||
RouteNewService { service }
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: 'static, T> NewService for RouteNewService<P, T>
|
||||
impl<T> NewService for RouteNewService<T>
|
||||
where
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = (Error, ServiceRequest<P>),
|
||||
Error = (Error, ServiceRequest),
|
||||
>,
|
||||
T::Future: 'static,
|
||||
T::Service: 'static,
|
||||
<T::Service as Service>::Future: 'static,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = BoxedRouteService<ServiceRequest<P>, Self::Response>;
|
||||
type Service = BoxedRouteService<ServiceRequest, Self::Response>;
|
||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
@ -373,31 +367,27 @@ where
|
||||
.map_err(|_| ())
|
||||
.and_then(|service| {
|
||||
let service: BoxedRouteService<_, _> =
|
||||
Box::new(RouteServiceWrapper {
|
||||
service,
|
||||
_t: PhantomData,
|
||||
});
|
||||
Box::new(RouteServiceWrapper { service });
|
||||
Ok(service)
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct RouteServiceWrapper<P, T: Service> {
|
||||
struct RouteServiceWrapper<T: Service> {
|
||||
service: T,
|
||||
_t: PhantomData<P>,
|
||||
}
|
||||
|
||||
impl<P, T> Service for RouteServiceWrapper<P, T>
|
||||
impl<T> Service for RouteServiceWrapper<T>
|
||||
where
|
||||
T::Future: 'static,
|
||||
T: Service<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = (Error, ServiceRequest<P>),
|
||||
Error = (Error, ServiceRequest),
|
||||
>,
|
||||
{
|
||||
type Request = ServiceRequest<P>;
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Future = Either<
|
||||
@ -409,7 +399,7 @@ where
|
||||
self.service.poll_ready().map_err(|(e, _)| e)
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
let mut fut = self.service.call(req);
|
||||
match fut.poll() {
|
||||
Ok(Async::Ready(res)) => Either::A(ok(res)),
|
||||
|
117
src/scope.rs
117
src/scope.rs
@ -21,9 +21,8 @@ use crate::service::{
|
||||
};
|
||||
|
||||
type Guards = Vec<Box<Guard>>;
|
||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
|
||||
type HttpNewService<P> =
|
||||
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
|
||||
type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
|
||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||
type BoxedResponse = Either<
|
||||
FutureResult<ServiceResponse, Error>,
|
||||
Box<Future<Item = ServiceResponse, Error = Error>>,
|
||||
@ -58,18 +57,18 @@ type BoxedResponse = Either<
|
||||
/// * /{project_id}/path2 - `GET` requests
|
||||
/// * /{project_id}/path3 - `HEAD` requests
|
||||
///
|
||||
pub struct Scope<P, T = ScopeEndpoint<P>> {
|
||||
pub struct Scope<T = ScopeEndpoint> {
|
||||
endpoint: T,
|
||||
rdef: String,
|
||||
services: Vec<Box<ServiceFactory<P>>>,
|
||||
services: Vec<Box<ServiceFactory>>,
|
||||
guards: Vec<Box<Guard>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>,
|
||||
factory_ref: Rc<RefCell<Option<ScopeFactory<P>>>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
|
||||
factory_ref: Rc<RefCell<Option<ScopeFactory>>>,
|
||||
}
|
||||
|
||||
impl<P: 'static> Scope<P> {
|
||||
impl Scope {
|
||||
/// Create a new scope
|
||||
pub fn new(path: &str) -> Scope<P> {
|
||||
pub fn new(path: &str) -> Scope {
|
||||
let fref = Rc::new(RefCell::new(None));
|
||||
Scope {
|
||||
endpoint: ScopeEndpoint::new(fref.clone()),
|
||||
@ -82,11 +81,10 @@ impl<P: 'static> Scope<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, T> Scope<P, T>
|
||||
impl<T> Scope<T>
|
||||
where
|
||||
P: 'static,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -146,7 +144,7 @@ where
|
||||
/// ```
|
||||
pub fn service<F>(mut self, factory: F) -> Self
|
||||
where
|
||||
F: HttpServiceFactory<P> + 'static,
|
||||
F: HttpServiceFactory + 'static,
|
||||
{
|
||||
self.services
|
||||
.push(Box::new(ServiceFactoryWrapper::new(factory)));
|
||||
@ -174,7 +172,7 @@ where
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
pub fn route(self, path: &str, mut route: Route<P>) -> Self {
|
||||
pub fn route(self, path: &str, mut route: Route) -> Self {
|
||||
self.service(
|
||||
Resource::new(path)
|
||||
.add_guards(route.take_guards())
|
||||
@ -187,9 +185,9 @@ where
|
||||
/// If default resource is not registered, app's default resource is being used.
|
||||
pub fn default_resource<F, U>(mut self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(Resource<P>) -> Resource<P, U>,
|
||||
F: FnOnce(Resource) -> Resource<U>,
|
||||
U: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -216,9 +214,8 @@ where
|
||||
self,
|
||||
mw: F,
|
||||
) -> Scope<
|
||||
P,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -227,7 +224,7 @@ where
|
||||
where
|
||||
M: Transform<
|
||||
T::Service,
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
@ -279,33 +276,31 @@ where
|
||||
self,
|
||||
mw: F,
|
||||
) -> Scope<
|
||||
P,
|
||||
impl NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
>,
|
||||
>
|
||||
where
|
||||
F: FnMut(ServiceRequest<P>, &mut T::Service) -> R + Clone,
|
||||
F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
|
||||
R: IntoFuture<Item = ServiceResponse, Error = Error>,
|
||||
{
|
||||
self.wrap(mw)
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, T> HttpServiceFactory<P> for Scope<P, T>
|
||||
impl<T> HttpServiceFactory for Scope<T>
|
||||
where
|
||||
P: 'static,
|
||||
T: NewService<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse,
|
||||
Error = Error,
|
||||
InitError = (),
|
||||
> + 'static,
|
||||
{
|
||||
fn register(self, config: &mut ServiceConfig<P>) {
|
||||
fn register(self, config: &mut ServiceConfig) {
|
||||
// update default resource if needed
|
||||
if self.default.borrow().is_none() {
|
||||
*self.default.borrow_mut() = Some(config.default_service());
|
||||
@ -350,18 +345,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScopeFactory<P> {
|
||||
services: Rc<Vec<(ResourceDef, HttpNewService<P>, RefCell<Option<Guards>>)>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>,
|
||||
pub struct ScopeFactory {
|
||||
services: Rc<Vec<(ResourceDef, HttpNewService, RefCell<Option<Guards>>)>>,
|
||||
default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
|
||||
}
|
||||
|
||||
impl<P: 'static> NewService for ScopeFactory<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for ScopeFactory {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ScopeService<P>;
|
||||
type Future = ScopeFactoryResponse<P>;
|
||||
type Service = ScopeService;
|
||||
type Future = ScopeFactoryResponse;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
let default_fut = if let Some(ref default) = *self.default.borrow() {
|
||||
@ -390,21 +385,21 @@ impl<P: 'static> NewService for ScopeFactory<P> {
|
||||
|
||||
/// Create scope service
|
||||
#[doc(hidden)]
|
||||
pub struct ScopeFactoryResponse<P> {
|
||||
fut: Vec<CreateScopeServiceItem<P>>,
|
||||
default: Option<HttpService<P>>,
|
||||
default_fut: Option<Box<Future<Item = HttpService<P>, Error = ()>>>,
|
||||
pub struct ScopeFactoryResponse {
|
||||
fut: Vec<CreateScopeServiceItem>,
|
||||
default: Option<HttpService>,
|
||||
default_fut: Option<Box<Future<Item = HttpService, Error = ()>>>,
|
||||
}
|
||||
|
||||
type HttpServiceFut<P> = Box<Future<Item = HttpService<P>, Error = ()>>;
|
||||
type HttpServiceFut = Box<Future<Item = HttpService, Error = ()>>;
|
||||
|
||||
enum CreateScopeServiceItem<P> {
|
||||
Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut<P>),
|
||||
Service(ResourceDef, Option<Guards>, HttpService<P>),
|
||||
enum CreateScopeServiceItem {
|
||||
Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut),
|
||||
Service(ResourceDef, Option<Guards>, HttpService),
|
||||
}
|
||||
|
||||
impl<P> Future for ScopeFactoryResponse<P> {
|
||||
type Item = ScopeService<P>;
|
||||
impl Future for ScopeFactoryResponse {
|
||||
type Item = ScopeService;
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
@ -465,14 +460,14 @@ impl<P> Future for ScopeFactoryResponse<P> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScopeService<P> {
|
||||
router: Router<HttpService<P>, Vec<Box<Guard>>>,
|
||||
default: Option<HttpService<P>>,
|
||||
_ready: Option<(ServiceRequest<P>, ResourceInfo)>,
|
||||
pub struct ScopeService {
|
||||
router: Router<HttpService, Vec<Box<Guard>>>,
|
||||
default: Option<HttpService>,
|
||||
_ready: Option<(ServiceRequest, ResourceInfo)>,
|
||||
}
|
||||
|
||||
impl<P> Service for ScopeService<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl Service for ScopeService {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>;
|
||||
@ -481,7 +476,7 @@ impl<P> Service for ScopeService<P> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future {
|
||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
||||
let res = self.router.recognize_mut_checked(&mut req, |req, guards| {
|
||||
if let Some(ref guards) = guards {
|
||||
for f in guards {
|
||||
@ -505,23 +500,23 @@ impl<P> Service for ScopeService<P> {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct ScopeEndpoint<P> {
|
||||
factory: Rc<RefCell<Option<ScopeFactory<P>>>>,
|
||||
pub struct ScopeEndpoint {
|
||||
factory: Rc<RefCell<Option<ScopeFactory>>>,
|
||||
}
|
||||
|
||||
impl<P> ScopeEndpoint<P> {
|
||||
fn new(factory: Rc<RefCell<Option<ScopeFactory<P>>>>) -> Self {
|
||||
impl ScopeEndpoint {
|
||||
fn new(factory: Rc<RefCell<Option<ScopeFactory>>>) -> Self {
|
||||
ScopeEndpoint { factory }
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: 'static> NewService for ScopeEndpoint<P> {
|
||||
type Request = ServiceRequest<P>;
|
||||
impl NewService for ScopeEndpoint {
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Service = ScopeService<P>;
|
||||
type Future = ScopeFactoryResponse<P>;
|
||||
type Service = ScopeService;
|
||||
type Future = ScopeFactoryResponse;
|
||||
|
||||
fn new_service(&self, _: &()) -> Self::Future {
|
||||
self.factory.borrow_mut().as_mut().unwrap().new_service(&())
|
||||
@ -886,13 +881,13 @@ mod tests {
|
||||
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
fn md<S, P, B>(
|
||||
req: ServiceRequest<P>,
|
||||
fn md<S, B>(
|
||||
req: ServiceRequest,
|
||||
srv: &mut S,
|
||||
) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error>
|
||||
where
|
||||
S: Service<
|
||||
Request = ServiceRequest<P>,
|
||||
Request = ServiceRequest,
|
||||
Response = ServiceResponse<B>,
|
||||
Error = Error,
|
||||
>,
|
||||
|
@ -1,6 +1,5 @@
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use actix_http::body::{Body, MessageBody, ResponseBody};
|
||||
use actix_http::http::{HeaderMap, Method, StatusCode, Uri, Version};
|
||||
@ -15,52 +14,50 @@ use crate::config::{AppConfig, ServiceConfig};
|
||||
use crate::data::Data;
|
||||
use crate::request::HttpRequest;
|
||||
|
||||
pub trait HttpServiceFactory<P> {
|
||||
fn register(self, config: &mut ServiceConfig<P>);
|
||||
pub trait HttpServiceFactory {
|
||||
fn register(self, config: &mut ServiceConfig);
|
||||
}
|
||||
|
||||
pub(crate) trait ServiceFactory<P> {
|
||||
fn register(&mut self, config: &mut ServiceConfig<P>);
|
||||
pub(crate) trait ServiceFactory {
|
||||
fn register(&mut self, config: &mut ServiceConfig);
|
||||
}
|
||||
|
||||
pub(crate) struct ServiceFactoryWrapper<T, P> {
|
||||
pub(crate) struct ServiceFactoryWrapper<T> {
|
||||
factory: Option<T>,
|
||||
_t: PhantomData<P>,
|
||||
}
|
||||
|
||||
impl<T, P> ServiceFactoryWrapper<T, P> {
|
||||
impl<T> ServiceFactoryWrapper<T> {
|
||||
pub fn new(factory: T) -> Self {
|
||||
Self {
|
||||
factory: Some(factory),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, P> ServiceFactory<P> for ServiceFactoryWrapper<T, P>
|
||||
impl<T> ServiceFactory for ServiceFactoryWrapper<T>
|
||||
where
|
||||
T: HttpServiceFactory<P>,
|
||||
T: HttpServiceFactory,
|
||||
{
|
||||
fn register(&mut self, config: &mut ServiceConfig<P>) {
|
||||
fn register(&mut self, config: &mut ServiceConfig) {
|
||||
if let Some(item) = self.factory.take() {
|
||||
item.register(config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ServiceRequest<P = PayloadStream> {
|
||||
pub struct ServiceRequest {
|
||||
req: HttpRequest,
|
||||
payload: Payload<P>,
|
||||
payload: Payload,
|
||||
}
|
||||
|
||||
impl<P> ServiceRequest<P> {
|
||||
impl ServiceRequest {
|
||||
/// Construct service request from parts
|
||||
pub fn from_parts(req: HttpRequest, payload: Payload<P>) -> Self {
|
||||
pub fn from_parts(req: HttpRequest, payload: Payload) -> Self {
|
||||
ServiceRequest { req, payload }
|
||||
}
|
||||
|
||||
/// Deconstruct request into parts
|
||||
pub fn into_parts(self) -> (HttpRequest, Payload<P>) {
|
||||
pub fn into_parts(self) -> (HttpRequest, Payload) {
|
||||
(self.req, self.payload)
|
||||
}
|
||||
|
||||
@ -170,14 +167,14 @@ impl<P> ServiceRequest<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Resource<Url> for ServiceRequest<P> {
|
||||
impl Resource<Url> for ServiceRequest {
|
||||
fn resource_path(&mut self) -> &mut Path<Url> {
|
||||
self.match_info_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> HttpMessage for ServiceRequest<P> {
|
||||
type Stream = P;
|
||||
impl HttpMessage for ServiceRequest {
|
||||
type Stream = PayloadStream;
|
||||
|
||||
#[inline]
|
||||
/// Returns Request's headers.
|
||||
@ -203,7 +200,7 @@ impl<P> HttpMessage for ServiceRequest<P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> fmt::Debug for ServiceRequest<P> {
|
||||
impl fmt::Debug for ServiceRequest {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(
|
||||
f,
|
||||
|
23
src/test.rs
23
src/test.rs
@ -6,7 +6,7 @@ use actix_http::cookie::Cookie;
|
||||
use actix_http::http::header::{Header, HeaderName, IntoHeaderValue};
|
||||
use actix_http::http::{HttpTryFrom, Method, StatusCode, Version};
|
||||
use actix_http::test::TestRequest as HttpTestRequest;
|
||||
use actix_http::{Extensions, PayloadStream, Request};
|
||||
use actix_http::{Extensions, Request};
|
||||
use actix_router::{Path, ResourceDef, Url};
|
||||
use actix_rt::Runtime;
|
||||
use actix_server_config::ServerConfig;
|
||||
@ -60,23 +60,18 @@ where
|
||||
}
|
||||
|
||||
/// Create service that always responds with `HttpResponse::Ok()`
|
||||
pub fn ok_service() -> impl Service<
|
||||
Request = ServiceRequest<PayloadStream>,
|
||||
Response = ServiceResponse<Body>,
|
||||
Error = Error,
|
||||
> {
|
||||
pub fn ok_service(
|
||||
) -> impl Service<Request = ServiceRequest, Response = ServiceResponse<Body>, Error = Error>
|
||||
{
|
||||
default_service(StatusCode::OK)
|
||||
}
|
||||
|
||||
/// Create service that responds with response with specified status code
|
||||
pub fn default_service(
|
||||
status_code: StatusCode,
|
||||
) -> impl Service<
|
||||
Request = ServiceRequest<PayloadStream>,
|
||||
Response = ServiceResponse<Body>,
|
||||
Error = Error,
|
||||
> {
|
||||
FnService::new(move |req: ServiceRequest<PayloadStream>| {
|
||||
) -> impl Service<Request = ServiceRequest, Response = ServiceResponse<Body>, Error = Error>
|
||||
{
|
||||
FnService::new(move |req: ServiceRequest| {
|
||||
req.into_response(HttpResponse::build(status_code).finish())
|
||||
})
|
||||
}
|
||||
@ -298,12 +293,12 @@ impl TestRequest {
|
||||
}
|
||||
|
||||
/// Complete request creation and generate `Request` instance
|
||||
pub fn to_request(mut self) -> Request<PayloadStream> {
|
||||
pub fn to_request(mut self) -> Request {
|
||||
self.req.finish()
|
||||
}
|
||||
|
||||
/// Complete request creation and generate `ServiceRequest` instance
|
||||
pub fn to_srv_request(mut self) -> ServiceRequest<PayloadStream> {
|
||||
pub fn to_srv_request(mut self) -> ServiceRequest {
|
||||
let (head, payload) = self.req.finish().into_parts();
|
||||
|
||||
let req = HttpRequest::new(
|
||||
|
@ -3,15 +3,15 @@
|
||||
use std::rc::Rc;
|
||||
use std::{fmt, ops};
|
||||
|
||||
use actix_http::error::{Error, PayloadError};
|
||||
use actix_http::{HttpMessage, Payload};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use actix_http::{Error, HttpMessage, Payload};
|
||||
use bytes::BytesMut;
|
||||
use encoding::all::UTF_8;
|
||||
use encoding::types::{DecoderTrap, Encoding};
|
||||
use encoding::EncodingRef;
|
||||
use futures::{Future, Poll, Stream};
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use crate::dev::Decompress;
|
||||
use crate::error::UrlencodedError;
|
||||
use crate::extract::FromRequest;
|
||||
use crate::http::header::CONTENT_LENGTH;
|
||||
@ -69,16 +69,15 @@ impl<T> ops::DerefMut for Form<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, P> FromRequest<P> for Form<T>
|
||||
impl<T> FromRequest for Form<T>
|
||||
where
|
||||
T: DeserializeOwned + 'static,
|
||||
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
|
||||
{
|
||||
type Error = Error;
|
||||
type Future = Box<Future<Item = Self, Error = Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||
let req2 = req.clone();
|
||||
let (limit, err) = req
|
||||
.route_data::<FormConfig>()
|
||||
@ -182,8 +181,8 @@ impl Default for FormConfig {
|
||||
/// * content type is not `application/x-www-form-urlencoded`
|
||||
/// * content-length is greater than 32k
|
||||
///
|
||||
pub struct UrlEncoded<P, U> {
|
||||
stream: Payload<P>,
|
||||
pub struct UrlEncoded<U> {
|
||||
stream: Option<Decompress<Payload>>,
|
||||
limit: usize,
|
||||
length: Option<usize>,
|
||||
encoding: EncodingRef,
|
||||
@ -191,12 +190,9 @@ pub struct UrlEncoded<P, U> {
|
||||
fut: Option<Box<Future<Item = U, Error = UrlencodedError>>>,
|
||||
}
|
||||
|
||||
impl<P, U> UrlEncoded<P, U>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
impl<U> UrlEncoded<U> {
|
||||
/// Create a new future to URL encode a request
|
||||
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> UrlEncoded<P, U> {
|
||||
pub fn new(req: &HttpRequest, payload: &mut Payload) -> UrlEncoded<U> {
|
||||
// check content type
|
||||
if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
|
||||
return Self::err(UrlencodedError::ContentType);
|
||||
@ -219,9 +215,10 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
let payload = Decompress::from_headers(payload.take(), req.headers());
|
||||
UrlEncoded {
|
||||
encoding,
|
||||
stream: payload.take(),
|
||||
stream: Some(payload),
|
||||
limit: 32_768,
|
||||
length: len,
|
||||
fut: None,
|
||||
@ -231,7 +228,7 @@ where
|
||||
|
||||
fn err(e: UrlencodedError) -> Self {
|
||||
UrlEncoded {
|
||||
stream: Payload::None,
|
||||
stream: None,
|
||||
limit: 32_768,
|
||||
fut: None,
|
||||
err: Some(e),
|
||||
@ -247,9 +244,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, U> Future for UrlEncoded<P, U>
|
||||
impl<U> Future for UrlEncoded<U>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
U: DeserializeOwned + 'static,
|
||||
{
|
||||
type Item = U;
|
||||
@ -274,7 +270,10 @@ where
|
||||
|
||||
// future
|
||||
let encoding = self.encoding;
|
||||
let fut = std::mem::replace(&mut self.stream, Payload::None)
|
||||
let fut = self
|
||||
.stream
|
||||
.take()
|
||||
.unwrap()
|
||||
.from_err()
|
||||
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
|
||||
if (body.len() + chunk.len()) > limit {
|
||||
@ -355,20 +354,20 @@ mod tests {
|
||||
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.header(CONTENT_LENGTH, "xxxx")
|
||||
.to_http_parts();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
|
||||
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
|
||||
assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength));
|
||||
|
||||
let (req, mut pl) =
|
||||
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.header(CONTENT_LENGTH, "1000000")
|
||||
.to_http_parts();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
|
||||
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
|
||||
assert!(eq(info.err().unwrap(), UrlencodedError::Overflow));
|
||||
|
||||
let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain")
|
||||
.header(CONTENT_LENGTH, "10")
|
||||
.to_http_parts();
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl));
|
||||
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
|
||||
assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
|
||||
}
|
||||
|
||||
@ -380,7 +379,7 @@ mod tests {
|
||||
.set_payload(Bytes::from_static(b"hello=world"))
|
||||
.to_http_parts();
|
||||
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap();
|
||||
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
|
||||
assert_eq!(
|
||||
info,
|
||||
Info {
|
||||
@ -396,7 +395,7 @@ mod tests {
|
||||
.set_payload(Bytes::from_static(b"hello=world"))
|
||||
.to_http_parts();
|
||||
|
||||
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap();
|
||||
let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
|
||||
assert_eq!(
|
||||
info,
|
||||
Info {
|
||||
|
@ -3,7 +3,7 @@
|
||||
use std::rc::Rc;
|
||||
use std::{fmt, ops};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use bytes::BytesMut;
|
||||
use futures::{Future, Poll, Stream};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
@ -12,7 +12,8 @@ use serde_json;
|
||||
use actix_http::http::{header::CONTENT_LENGTH, StatusCode};
|
||||
use actix_http::{HttpMessage, Payload, Response};
|
||||
|
||||
use crate::error::{Error, JsonPayloadError, PayloadError};
|
||||
use crate::dev::Decompress;
|
||||
use crate::error::{Error, JsonPayloadError};
|
||||
use crate::extract::FromRequest;
|
||||
use crate::request::HttpRequest;
|
||||
use crate::responder::Responder;
|
||||
@ -163,16 +164,15 @@ impl<T: Serialize> Responder for Json<T> {
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<T, P> FromRequest<P> for Json<T>
|
||||
impl<T> FromRequest for Json<T>
|
||||
where
|
||||
T: DeserializeOwned + 'static,
|
||||
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
|
||||
{
|
||||
type Error = Error;
|
||||
type Future = Box<Future<Item = Self, Error = Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||
let req2 = req.clone();
|
||||
let (limit, err) = req
|
||||
.route_data::<JsonConfig>()
|
||||
@ -270,21 +270,20 @@ impl Default for JsonConfig {
|
||||
///
|
||||
/// * content type is not `application/json`
|
||||
/// * content length is greater than 256k
|
||||
pub struct JsonBody<P, U> {
|
||||
pub struct JsonBody<U> {
|
||||
limit: usize,
|
||||
length: Option<usize>,
|
||||
stream: Payload<P>,
|
||||
stream: Option<Decompress<Payload>>,
|
||||
err: Option<JsonPayloadError>,
|
||||
fut: Option<Box<Future<Item = U, Error = JsonPayloadError>>>,
|
||||
}
|
||||
|
||||
impl<P, U> JsonBody<P, U>
|
||||
impl<U> JsonBody<U>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
U: DeserializeOwned + 'static,
|
||||
{
|
||||
/// Create `JsonBody` for request.
|
||||
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> Self {
|
||||
pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self {
|
||||
// check content-type
|
||||
let json = if let Ok(Some(mime)) = req.mime_type() {
|
||||
mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON)
|
||||
@ -295,7 +294,7 @@ where
|
||||
return JsonBody {
|
||||
limit: 262_144,
|
||||
length: None,
|
||||
stream: Payload::None,
|
||||
stream: None,
|
||||
fut: None,
|
||||
err: Some(JsonPayloadError::ContentType),
|
||||
};
|
||||
@ -309,11 +308,12 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
let payload = Decompress::from_headers(payload.take(), req.headers());
|
||||
|
||||
JsonBody {
|
||||
limit: 262_144,
|
||||
length: len,
|
||||
stream: payload.take(),
|
||||
stream: Some(payload),
|
||||
fut: None,
|
||||
err: None,
|
||||
}
|
||||
@ -326,9 +326,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, U> Future for JsonBody<P, U>
|
||||
impl<U> Future for JsonBody<U>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
U: DeserializeOwned + 'static,
|
||||
{
|
||||
type Item = U;
|
||||
@ -350,7 +349,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let fut = std::mem::replace(&mut self.stream, Payload::None)
|
||||
let fut = self
|
||||
.stream
|
||||
.take()
|
||||
.unwrap()
|
||||
.from_err()
|
||||
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
|
||||
if (body.len() + chunk.len()) > limit {
|
||||
@ -508,7 +510,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_json_body() {
|
||||
let (req, mut pl) = TestRequest::default().to_http_parts();
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
|
||||
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
|
||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
||||
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
@ -517,7 +519,7 @@ mod tests {
|
||||
header::HeaderValue::from_static("application/text"),
|
||||
)
|
||||
.to_http_parts();
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
|
||||
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
|
||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
||||
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
@ -531,7 +533,7 @@ mod tests {
|
||||
)
|
||||
.to_http_parts();
|
||||
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl).limit(100));
|
||||
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl).limit(100));
|
||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::Overflow));
|
||||
|
||||
let (req, mut pl) = TestRequest::default()
|
||||
@ -546,7 +548,7 @@ mod tests {
|
||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||
.to_http_parts();
|
||||
|
||||
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl));
|
||||
let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
|
||||
assert_eq!(
|
||||
json.ok().unwrap(),
|
||||
MyObject {
|
||||
|
@ -152,7 +152,7 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<T, P> FromRequest<P> for Path<T>
|
||||
impl<T> FromRequest for Path<T>
|
||||
where
|
||||
T: de::DeserializeOwned,
|
||||
{
|
||||
@ -160,7 +160,7 @@ where
|
||||
type Future = Result<Self, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))
|
||||
.map(|inner| Path { inner })
|
||||
.map_err(ErrorNotFound)
|
||||
|
@ -44,7 +44,7 @@ use crate::request::HttpRequest;
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Payload(crate::dev::Payload<Box<Stream<Item = Bytes, Error = PayloadError>>>);
|
||||
pub struct Payload(crate::dev::Payload);
|
||||
|
||||
impl Stream for Payload {
|
||||
type Item = Bytes;
|
||||
@ -85,26 +85,13 @@ impl Stream for Payload {
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<P> FromRequest<P> for Payload
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
{
|
||||
impl FromRequest for Payload {
|
||||
type Error = Error;
|
||||
type Future = Result<Payload, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(_: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
|
||||
let pl = match payload.take() {
|
||||
crate::dev::Payload::Stream(s) => {
|
||||
let pl: Box<dyn Stream<Item = Bytes, Error = PayloadError>> =
|
||||
Box::new(s);
|
||||
crate::dev::Payload::Stream(pl)
|
||||
}
|
||||
crate::dev::Payload::None => crate::dev::Payload::None,
|
||||
crate::dev::Payload::H1(pl) => crate::dev::Payload::H1(pl),
|
||||
crate::dev::Payload::H2(pl) => crate::dev::Payload::H2(pl),
|
||||
};
|
||||
Ok(Payload(pl))
|
||||
fn from_request(_: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
|
||||
Ok(Payload(payload.take()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,16 +120,13 @@ where
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<P> FromRequest<P> for Bytes
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
{
|
||||
impl FromRequest for Bytes {
|
||||
type Error = Error;
|
||||
type Future =
|
||||
Either<Box<Future<Item = Bytes, Error = Error>>, FutureResult<Bytes, Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
|
||||
let mut tmp;
|
||||
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
|
||||
cfg
|
||||
@ -188,16 +172,13 @@ where
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
impl<P> FromRequest<P> for String
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
{
|
||||
impl FromRequest for String {
|
||||
type Error = Error;
|
||||
type Future =
|
||||
Either<Box<Future<Item = String, Error = Error>>, FutureResult<String, Error>>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
|
||||
let mut tmp;
|
||||
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
|
||||
cfg
|
||||
@ -300,20 +281,17 @@ impl Default for PayloadConfig {
|
||||
/// By default only 256Kb payload reads to a memory, then
|
||||
/// `PayloadError::Overflow` get returned. Use `MessageBody::limit()`
|
||||
/// method to change upper limit.
|
||||
pub struct HttpMessageBody<P> {
|
||||
pub struct HttpMessageBody {
|
||||
limit: usize,
|
||||
length: Option<usize>,
|
||||
stream: dev::Payload<P>,
|
||||
stream: Option<dev::Decompress<dev::Payload>>,
|
||||
err: Option<PayloadError>,
|
||||
fut: Option<Box<Future<Item = Bytes, Error = PayloadError>>>,
|
||||
}
|
||||
|
||||
impl<P> HttpMessageBody<P>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError>,
|
||||
{
|
||||
impl HttpMessageBody {
|
||||
/// Create `MessageBody` for request.
|
||||
pub fn new(req: &HttpRequest, payload: &mut dev::Payload<P>) -> HttpMessageBody<P> {
|
||||
pub fn new(req: &HttpRequest, payload: &mut dev::Payload) -> HttpMessageBody {
|
||||
let mut len = None;
|
||||
if let Some(l) = req.headers().get(&header::CONTENT_LENGTH) {
|
||||
if let Ok(s) = l.to_str() {
|
||||
@ -328,7 +306,7 @@ where
|
||||
}
|
||||
|
||||
HttpMessageBody {
|
||||
stream: payload.take(),
|
||||
stream: Some(dev::Decompress::from_headers(payload.take(), req.headers())),
|
||||
limit: 262_144,
|
||||
length: len,
|
||||
fut: None,
|
||||
@ -344,7 +322,7 @@ where
|
||||
|
||||
fn err(e: PayloadError) -> Self {
|
||||
HttpMessageBody {
|
||||
stream: dev::Payload::None,
|
||||
stream: None,
|
||||
limit: 262_144,
|
||||
fut: None,
|
||||
err: Some(e),
|
||||
@ -353,10 +331,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Future for HttpMessageBody<P>
|
||||
where
|
||||
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
|
||||
{
|
||||
impl Future for HttpMessageBody {
|
||||
type Item = Bytes;
|
||||
type Error = PayloadError;
|
||||
|
||||
@ -378,7 +353,9 @@ where
|
||||
// future
|
||||
let limit = self.limit;
|
||||
self.fut = Some(Box::new(
|
||||
std::mem::replace(&mut self.stream, actix_http::Payload::None)
|
||||
self.stream
|
||||
.take()
|
||||
.unwrap()
|
||||
.from_err()
|
||||
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
|
||||
if (body.len() + chunk.len()) > limit {
|
||||
|
@ -111,7 +111,7 @@ impl<T: fmt::Display> fmt::Display for Query<T> {
|
||||
/// .route(web::get().to(index))); // <- use `Query` extractor
|
||||
/// }
|
||||
/// ```
|
||||
impl<T, P> FromRequest<P> for Query<T>
|
||||
impl<T> FromRequest for Query<T>
|
||||
where
|
||||
T: de::DeserializeOwned,
|
||||
{
|
||||
@ -119,7 +119,7 @@ where
|
||||
type Future = Result<Self, Error>;
|
||||
|
||||
#[inline]
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future {
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
serde_urlencoded::from_str::<T>(req.query_string())
|
||||
.map(|val| Ok(Query(val)))
|
||||
.unwrap_or_else(|e| {
|
||||
|
28
src/web.rs
28
src/web.rs
@ -50,7 +50,7 @@ pub use crate::types::*;
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
pub fn resource<P: 'static>(path: &str) -> Resource<P> {
|
||||
pub fn resource(path: &str) -> Resource {
|
||||
Resource::new(path)
|
||||
}
|
||||
|
||||
@ -77,12 +77,12 @@ pub fn resource<P: 'static>(path: &str) -> Resource<P> {
|
||||
/// * /{project_id}/path2
|
||||
/// * /{project_id}/path3
|
||||
///
|
||||
pub fn scope<P: 'static>(path: &str) -> Scope<P> {
|
||||
pub fn scope(path: &str) -> Scope {
|
||||
Scope::new(path)
|
||||
}
|
||||
|
||||
/// Create *route* without configuration.
|
||||
pub fn route<P: 'static>() -> Route<P> {
|
||||
pub fn route() -> Route {
|
||||
Route::new()
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ pub fn route<P: 'static>() -> Route<P> {
|
||||
/// In the above example, one `GET` route get added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn get<P: 'static>() -> Route<P> {
|
||||
pub fn get() -> Route {
|
||||
Route::new().method(Method::GET)
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ pub fn get<P: 'static>() -> Route<P> {
|
||||
/// In the above example, one `POST` route get added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn post<P: 'static>() -> Route<P> {
|
||||
pub fn post() -> Route {
|
||||
Route::new().method(Method::POST)
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ pub fn post<P: 'static>() -> Route<P> {
|
||||
/// In the above example, one `PUT` route get added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn put<P: 'static>() -> Route<P> {
|
||||
pub fn put() -> Route {
|
||||
Route::new().method(Method::PUT)
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ pub fn put<P: 'static>() -> Route<P> {
|
||||
/// In the above example, one `PATCH` route get added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn patch<P: 'static>() -> Route<P> {
|
||||
pub fn patch() -> Route {
|
||||
Route::new().method(Method::PATCH)
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ pub fn patch<P: 'static>() -> Route<P> {
|
||||
/// In the above example, one `DELETE` route get added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn delete<P: 'static>() -> Route<P> {
|
||||
pub fn delete() -> Route {
|
||||
Route::new().method(Method::DELETE)
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ pub fn delete<P: 'static>() -> Route<P> {
|
||||
/// In the above example, one `HEAD` route get added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn head<P: 'static>() -> Route<P> {
|
||||
pub fn head() -> Route {
|
||||
Route::new().method(Method::HEAD)
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ pub fn head<P: 'static>() -> Route<P> {
|
||||
/// In the above example, one `GET` route get added:
|
||||
/// * /{project_id}
|
||||
///
|
||||
pub fn method<P: 'static>(method: Method) -> Route<P> {
|
||||
pub fn method(method: Method) -> Route {
|
||||
Route::new().method(method)
|
||||
}
|
||||
|
||||
@ -240,10 +240,10 @@ pub fn method<P: 'static>(method: Method) -> Route<P> {
|
||||
/// web::to(index))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn to<F, I, R, P: 'static>(handler: F) -> Route<P>
|
||||
pub fn to<F, I, R>(handler: F) -> Route
|
||||
where
|
||||
F: Factory<I, R> + 'static,
|
||||
I: FromRequest<P> + 'static,
|
||||
I: FromRequest + 'static,
|
||||
R: Responder + 'static,
|
||||
{
|
||||
Route::new().to(handler)
|
||||
@ -263,10 +263,10 @@ where
|
||||
/// web::to_async(index))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn to_async<F, I, R, P: 'static>(handler: F) -> Route<P>
|
||||
pub fn to_async<F, I, R>(handler: F) -> Route
|
||||
where
|
||||
F: AsyncFactory<I, R>,
|
||||
I: FromRequest<P> + 'static,
|
||||
I: FromRequest + 'static,
|
||||
R: IntoFuture + 'static,
|
||||
R::Item: Into<Response>,
|
||||
R::Error: Into<Error>,
|
||||
|
@ -19,9 +19,7 @@ use rand::{distributions::Alphanumeric, Rng};
|
||||
use actix_web::{http, test, web, App, HttpResponse, HttpServer};
|
||||
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
use actix_web::middleware::encoding;
|
||||
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
|
||||
use actix_web::middleware::encoding::BodyEncoding;
|
||||
use actix_web::middleware::{BodyEncoding, Compress};
|
||||
|
||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World \
|
||||
@ -68,7 +66,7 @@ fn test_body_gzip() {
|
||||
let mut srv = TestServer::new(|| {
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Gzip))
|
||||
.wrap(Compress::new(ContentEncoding::Gzip))
|
||||
.service(web::resource("/").route(web::to(|| Response::Ok().body(STR)))),
|
||||
)
|
||||
});
|
||||
@ -99,13 +97,11 @@ fn test_body_encoding_override() {
|
||||
let mut srv = TestServer::new(|| {
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Gzip))
|
||||
.wrap(Compress::new(ContentEncoding::Gzip))
|
||||
.service(web::resource("/").route(web::to(|| {
|
||||
use actix_web::middleware::encoding::BodyEncoding;
|
||||
Response::Ok().encoding(ContentEncoding::Deflate).body(STR)
|
||||
})))
|
||||
.service(web::resource("/raw").route(web::to(|| {
|
||||
use actix_web::middleware::encoding::BodyEncoding;
|
||||
let body = actix_web::dev::Body::Bytes(STR.into());
|
||||
let mut response =
|
||||
Response::with_body(actix_web::http::StatusCode::OK, body);
|
||||
@ -168,7 +164,7 @@ fn test_body_gzip_large() {
|
||||
let data = srv_data.clone();
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Gzip))
|
||||
.wrap(Compress::new(ContentEncoding::Gzip))
|
||||
.service(
|
||||
web::resource("/")
|
||||
.route(web::to(move || Response::Ok().body(data.clone()))),
|
||||
@ -209,7 +205,7 @@ fn test_body_gzip_large_random() {
|
||||
let data = srv_data.clone();
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Gzip))
|
||||
.wrap(Compress::new(ContentEncoding::Gzip))
|
||||
.service(
|
||||
web::resource("/")
|
||||
.route(web::to(move || Response::Ok().body(data.clone()))),
|
||||
@ -244,7 +240,7 @@ fn test_body_chunked_implicit() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Gzip))
|
||||
.wrap(Compress::new(ContentEncoding::Gzip))
|
||||
.service(web::resource("/").route(web::get().to(move || {
|
||||
Response::Ok().streaming(once(Ok::<_, Error>(Bytes::from_static(
|
||||
STR.as_ref(),
|
||||
@ -281,15 +277,12 @@ fn test_body_chunked_implicit() {
|
||||
#[cfg(feature = "brotli")]
|
||||
fn test_body_br_streaming() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Br))
|
||||
.service(web::resource("/").route(web::to(move || {
|
||||
Response::Ok().streaming(once(Ok::<_, Error>(Bytes::from_static(
|
||||
STR.as_ref(),
|
||||
))))
|
||||
}))),
|
||||
)
|
||||
h1::H1Service::new(App::new().wrap(Compress::new(ContentEncoding::Br)).service(
|
||||
web::resource("/").route(web::to(move || {
|
||||
Response::Ok()
|
||||
.streaming(once(Ok::<_, Error>(Bytes::from_static(STR.as_ref()))))
|
||||
})),
|
||||
))
|
||||
});
|
||||
|
||||
let mut response = srv
|
||||
@ -361,7 +354,7 @@ fn test_body_deflate() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Deflate))
|
||||
.wrap(Compress::new(ContentEncoding::Deflate))
|
||||
.service(
|
||||
web::resource("/").route(web::to(move || Response::Ok().body(STR))),
|
||||
),
|
||||
@ -392,13 +385,9 @@ fn test_body_deflate() {
|
||||
#[cfg(any(feature = "brotli"))]
|
||||
fn test_body_brotli() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new()
|
||||
.wrap(encoding::Compress::new(ContentEncoding::Br))
|
||||
.service(
|
||||
h1::H1Service::new(App::new().wrap(Compress::new(ContentEncoding::Br)).service(
|
||||
web::resource("/").route(web::to(move || Response::Ok().body(STR))),
|
||||
),
|
||||
)
|
||||
))
|
||||
});
|
||||
|
||||
// client request
|
||||
@ -427,7 +416,7 @@ fn test_body_brotli() {
|
||||
fn test_encoding() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
HttpService::new(
|
||||
App::new().enable_encoding().service(
|
||||
App::new().wrap(Compress::default()).service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -456,7 +445,7 @@ fn test_encoding() {
|
||||
fn test_gzip_encoding() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
HttpService::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -486,7 +475,7 @@ fn test_gzip_encoding_large() {
|
||||
let data = STR.repeat(10);
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -520,7 +509,7 @@ fn test_reading_gzip_encoding_large_random() {
|
||||
|
||||
let mut srv = TestServer::new(move || {
|
||||
HttpService::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -550,7 +539,7 @@ fn test_reading_gzip_encoding_large_random() {
|
||||
fn test_reading_deflate_encoding() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -580,7 +569,7 @@ fn test_reading_deflate_encoding_large() {
|
||||
let data = STR.repeat(10);
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -614,7 +603,7 @@ fn test_reading_deflate_encoding_large_random() {
|
||||
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -644,7 +633,7 @@ fn test_reading_deflate_encoding_large_random() {
|
||||
fn test_brotli_encoding() {
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
@ -674,7 +663,7 @@ fn test_brotli_encoding_large() {
|
||||
let data = STR.repeat(10);
|
||||
let mut srv = TestServer::new(move || {
|
||||
h1::H1Service::new(
|
||||
App::new().chain(encoding::Decompress::new()).service(
|
||||
App::new().service(
|
||||
web::resource("/")
|
||||
.route(web::to(move |body: Bytes| Response::Ok().body(body))),
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user