mirror of
https://github.com/ntex-rs/ntex.git
synced 2025-04-04 21:37:58 +03:00
stopping point
This commit is contained in:
parent
13af01d5a9
commit
0886f27082
31 changed files with 1074 additions and 1002 deletions
|
@ -151,9 +151,9 @@ impl Route {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub struct #name;
|
pub struct #name;
|
||||||
|
|
||||||
impl ntex::web::dev::WebServiceFactory<#error> for #name
|
impl<'a> ntex::web::WebService<'a, #error> for #name
|
||||||
{
|
{
|
||||||
fn register(self, __config: &mut ntex::web::dev::WebServiceConfig<#error>) {
|
fn register(self, __config: &mut ntex::web::WebServiceConfig<'a, #error>) {
|
||||||
#ast
|
#ast
|
||||||
|
|
||||||
let __resource = ntex::web::Resource::new(#path)
|
let __resource = ntex::web::Resource::new(#path)
|
||||||
|
@ -162,7 +162,7 @@ impl Route {
|
||||||
#(.guard(ntex::web::guard::fn_guard(#extra_guards)))*
|
#(.guard(ntex::web::guard::fn_guard(#extra_guards)))*
|
||||||
.to(#name);
|
.to(#name);
|
||||||
|
|
||||||
ntex::web::dev::WebServiceFactory::register(__resource, __config)
|
ntex::web::WebService::register(__resource, __config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -135,7 +135,7 @@ pub trait Service<Req> {
|
||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving service and returns a
|
/// Note that this function consumes the receiving service and returns a
|
||||||
/// wrapped version of it.
|
/// wrapped version of it.
|
||||||
fn map_err<F, E>(self, f: F) -> crate::dev::MapErr<Self, Req, F, E>
|
fn map_err<F, E>(self, f: F) -> crate::dev::MapErr<Self, F, E>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(Self::Error) -> E,
|
F: Fn(Self::Error) -> E,
|
||||||
|
@ -185,23 +185,17 @@ pub trait ServiceFactory<Req, Cfg = ()> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Map this service's error to a different error, returning a new service.
|
/// Map this service's error to a different error, returning a new service.
|
||||||
fn map_err<F, E>(
|
fn map_err<F, E>(self, f: F) -> crate::map_err::MapErrServiceFactory<Self, Cfg, F, E>
|
||||||
self,
|
|
||||||
f: F,
|
|
||||||
) -> crate::map_err::MapErrServiceFactory<Self, Req, Cfg, F, E>
|
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(Self::Error) -> E + Clone,
|
F: Fn(Self::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
crate::map_err::MapErrServiceFactory::<_, _, Cfg, _, _>::new(self, f)
|
crate::map_err::MapErrServiceFactory::new(self, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Map this factory's init error to a different error, returning a new service.
|
/// Map this factory's init error to a different error, returning a new service.
|
||||||
fn map_init_err<F, E>(
|
fn map_init_err<F, E>(self, f: F) -> crate::map_init_err::MapInitErr<Self, F, E>
|
||||||
self,
|
|
||||||
f: F,
|
|
||||||
) -> crate::map_init_err::MapInitErr<Self, Req, Cfg, F, E>
|
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(Self::InitError) -> E + Clone,
|
F: Fn(Self::InitError) -> E + Clone,
|
||||||
|
|
|
@ -6,19 +6,15 @@ use super::{Service, ServiceFactory};
|
||||||
/// error.
|
/// error.
|
||||||
///
|
///
|
||||||
/// This is created by the `ServiceExt::map_err` method.
|
/// This is created by the `ServiceExt::map_err` method.
|
||||||
pub struct MapErr<A, R, F, E> {
|
pub struct MapErr<A, F, E> {
|
||||||
service: A,
|
service: A,
|
||||||
f: F,
|
f: F,
|
||||||
_t: PhantomData<fn(R) -> E>,
|
_t: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, F, E> MapErr<A, R, F, E> {
|
impl<A, F, E> MapErr<A, F, E> {
|
||||||
/// Create new `MapErr` combinator
|
/// Create new `MapErr` combinator
|
||||||
pub(crate) fn new(service: A, f: F) -> Self
|
pub(crate) fn new(service: A, f: F) -> Self {
|
||||||
where
|
|
||||||
A: Service<R>,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
Self {
|
Self {
|
||||||
service,
|
service,
|
||||||
f,
|
f,
|
||||||
|
@ -27,7 +23,7 @@ impl<A, R, F, E> MapErr<A, R, F, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, F, E> Clone for MapErr<A, R, F, E>
|
impl<A, F, E> Clone for MapErr<A, F, E>
|
||||||
where
|
where
|
||||||
A: Clone,
|
A: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
|
@ -42,7 +38,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, F, E> Service<R> for MapErr<A, R, F, E>
|
impl<A, R, F, E> Service<R> for MapErr<A, F, E>
|
||||||
where
|
where
|
||||||
A: Service<R>,
|
A: Service<R>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
|
@ -106,21 +102,13 @@ where
|
||||||
/// service's error.
|
/// service's error.
|
||||||
///
|
///
|
||||||
/// This is created by the `NewServiceExt::map_err` method.
|
/// This is created by the `NewServiceExt::map_err` method.
|
||||||
pub struct MapErrServiceFactory<A, R, C, F, E>
|
pub struct MapErrServiceFactory<A, C, F, E> {
|
||||||
where
|
|
||||||
A: ServiceFactory<R, C>,
|
|
||||||
F: Fn(A::Error) -> E + Clone,
|
|
||||||
{
|
|
||||||
a: A,
|
a: A,
|
||||||
f: F,
|
f: F,
|
||||||
e: PhantomData<fn(R, C) -> E>,
|
e: PhantomData<(C, E)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, C, F, E> MapErrServiceFactory<A, R, C, F, E>
|
impl<A, C, F, E> MapErrServiceFactory<A, C, F, E> {
|
||||||
where
|
|
||||||
A: ServiceFactory<R, C>,
|
|
||||||
F: Fn(A::Error) -> E + Clone,
|
|
||||||
{
|
|
||||||
/// Create new `MapErr` new service instance
|
/// Create new `MapErr` new service instance
|
||||||
pub(crate) fn new(a: A, f: F) -> Self {
|
pub(crate) fn new(a: A, f: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -131,10 +119,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, C, F, E> Clone for MapErrServiceFactory<A, R, C, F, E>
|
impl<A, C, F, E> Clone for MapErrServiceFactory<A, C, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory<R, C> + Clone,
|
A: Clone,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -145,7 +133,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, C, F, E> ServiceFactory<R, C> for MapErrServiceFactory<A, R, C, F, E>
|
impl<A, R, C, F, E> ServiceFactory<R, C> for MapErrServiceFactory<A, C, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory<R, C>,
|
A: ServiceFactory<R, C>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
|
@ -153,7 +141,7 @@ where
|
||||||
type Response = A::Response;
|
type Response = A::Response;
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
|
||||||
type Service = MapErr<A::Service, R, F, E>;
|
type Service = MapErr<A::Service, F, E>;
|
||||||
type InitError = A::InitError;
|
type InitError = A::InitError;
|
||||||
type Future = MapErrServiceFuture<A, R, C, F, E>;
|
type Future = MapErrServiceFuture<A, R, C, F, E>;
|
||||||
|
|
||||||
|
@ -190,7 +178,7 @@ where
|
||||||
A: ServiceFactory<R, C>,
|
A: ServiceFactory<R, C>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
type Output = Result<MapErr<A::Service, R, F, E>, A::InitError>;
|
type Output = Result<MapErr<A::Service, F, E>, A::InitError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
|
|
|
@ -3,17 +3,13 @@ use std::{future::Future, marker::PhantomData, pin::Pin, task::Context, task::Po
|
||||||
use super::ServiceFactory;
|
use super::ServiceFactory;
|
||||||
|
|
||||||
/// `MapInitErr` service combinator
|
/// `MapInitErr` service combinator
|
||||||
pub struct MapInitErr<A, R, C, F, E> {
|
pub struct MapInitErr<A, F, E> {
|
||||||
a: A,
|
a: A,
|
||||||
f: F,
|
f: F,
|
||||||
e: PhantomData<fn(R, C) -> E>,
|
e: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, C, F, E> MapInitErr<A, R, C, F, E>
|
impl<A, F, E> MapInitErr<A, F, E> {
|
||||||
where
|
|
||||||
A: ServiceFactory<R, C>,
|
|
||||||
F: Fn(A::InitError) -> E,
|
|
||||||
{
|
|
||||||
/// Create new `MapInitErr` combinator
|
/// Create new `MapInitErr` combinator
|
||||||
pub(crate) fn new(a: A, f: F) -> Self {
|
pub(crate) fn new(a: A, f: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -24,7 +20,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, C, F, E> Clone for MapInitErr<A, R, C, F, E>
|
impl<A, F, E> Clone for MapInitErr<A, F, E>
|
||||||
where
|
where
|
||||||
A: Clone,
|
A: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
|
@ -38,7 +34,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, C, F, E> ServiceFactory<R, C> for MapInitErr<A, R, C, F, E>
|
impl<A, R, C, F, E> ServiceFactory<R, C> for MapInitErr<A, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory<R, C>,
|
A: ServiceFactory<R, C>,
|
||||||
F: Fn(A::InitError) -> E + Clone,
|
F: Fn(A::InitError) -> E + Clone,
|
||||||
|
@ -48,7 +44,7 @@ where
|
||||||
|
|
||||||
type Service = A::Service;
|
type Service = A::Service;
|
||||||
type InitError = E;
|
type InitError = E;
|
||||||
type Future = MapInitErrFuture<A, R, C, F, E>;
|
type Future = MapInitErrFuture<A::Future, A::Service, A::InitError, F, E>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: C) -> Self::Future {
|
fn new_service(&self, cfg: C) -> Self::Future {
|
||||||
MapInitErrFuture {
|
MapInitErrFuture {
|
||||||
|
@ -59,23 +55,23 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
pub struct MapInitErrFuture<A, R, C, F, E>
|
pub struct MapInitErrFuture<Fut, Srv, Err, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory<R, C>,
|
F: Fn(Err) -> E,
|
||||||
F: Fn(A::InitError) -> E,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
{
|
{
|
||||||
f: F,
|
f: F,
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: A::Future,
|
fut: Fut,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, R, C, F, E> Future for MapInitErrFuture<A, R, C, F, E>
|
impl<Fut, Srv, Err, F, E> Future for MapInitErrFuture<Fut, Srv, Err, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory<R, C>,
|
F: Fn(Err) -> E,
|
||||||
F: Fn(A::InitError) -> E,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
{
|
{
|
||||||
type Output = Result<A::Service, E>;
|
type Output = Result<Srv, E>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl<T: Service<R>, R> Pipeline<T, R> {
|
||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving service and returns a
|
/// Note that this function consumes the receiving service and returns a
|
||||||
/// wrapped version of it.
|
/// wrapped version of it.
|
||||||
pub fn map_err<F, E>(self, f: F) -> Pipeline<MapErr<T, R, F, E>, R>
|
pub fn map_err<F, E>(self, f: F) -> Pipeline<MapErr<T, F, E>, R>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(T::Error) -> E,
|
F: Fn(T::Error) -> E,
|
||||||
|
@ -228,7 +228,7 @@ impl<T: ServiceFactory<R, C>, R, C> PipelineFactory<T, R, C> {
|
||||||
pub fn map_err<F, E>(
|
pub fn map_err<F, E>(
|
||||||
self,
|
self,
|
||||||
f: F,
|
f: F,
|
||||||
) -> PipelineFactory<MapErrServiceFactory<T, R, C, F, E>, R, C>
|
) -> PipelineFactory<MapErrServiceFactory<T, C, F, E>, R, C>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(T::Error) -> E + Clone,
|
F: Fn(T::Error) -> E + Clone,
|
||||||
|
@ -240,10 +240,7 @@ impl<T: ServiceFactory<R, C>, R, C> PipelineFactory<T, R, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map this factory's init error to a different error, returning a new service.
|
/// Map this factory's init error to a different error, returning a new service.
|
||||||
pub fn map_init_err<F, E>(
|
pub fn map_init_err<F, E>(self, f: F) -> PipelineFactory<MapInitErr<T, F, E>, R, C>
|
||||||
self,
|
|
||||||
f: F,
|
|
||||||
) -> PipelineFactory<MapInitErr<T, R, C, F, E>, R, C>
|
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(T::InitError) -> E + Clone,
|
F: Fn(T::InitError) -> E + Clone,
|
||||||
|
|
42
ntex/examples/basic.rs
Normal file
42
ntex/examples/basic.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
use ntex::http;
|
||||||
|
use ntex::web::{self, middleware, App, HttpRequest, HttpResponse, HttpServer};
|
||||||
|
|
||||||
|
#[web::get("/resource1/{name}/index.html")]
|
||||||
|
async fn index(req: HttpRequest, name: web::types::Path<String>) -> String {
|
||||||
|
println!("REQ: {:?}", req);
|
||||||
|
format!("Hello: {}!\r\n", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index_async(req: HttpRequest) -> &'static str {
|
||||||
|
println!("REQ: {:?}", req);
|
||||||
|
"Hello world!\r\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[web::get("/")]
|
||||||
|
async fn no_params() -> &'static str {
|
||||||
|
"Hello world!\r\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ntex::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
std::env::set_var("RUST_LOG", "ntex=trace");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
HttpServer::new(|| {
|
||||||
|
App::new()
|
||||||
|
.wrap(middleware::Logger::default())
|
||||||
|
.service((index, no_params))
|
||||||
|
.service(
|
||||||
|
web::resource("/resource2/index.html")
|
||||||
|
.wrap(middleware::DefaultHeaders::new().header("X-Version-R2", "0.3"))
|
||||||
|
.default(|| async { HttpResponse::MethodNotAllowed() })
|
||||||
|
.route(web::get().to(index_async)),
|
||||||
|
)
|
||||||
|
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))
|
||||||
|
})
|
||||||
|
.bind("0.0.0.0:8081")?
|
||||||
|
.workers(4)
|
||||||
|
.keep_alive(http::KeepAlive::Disabled)
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
25
ntex/examples/client.rs
Normal file
25
ntex/examples/client.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
use ntex::http::client::{error::SendRequestError, Client};
|
||||||
|
|
||||||
|
#[ntex::main]
|
||||||
|
async fn main() -> Result<(), SendRequestError> {
|
||||||
|
std::env::set_var("RUST_LOG", "ntex=trace");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let client = Client::new();
|
||||||
|
|
||||||
|
// Create request builder, configure request and send
|
||||||
|
let mut response = client
|
||||||
|
.get("https://www.rust-lang.org/")
|
||||||
|
.header("User-Agent", "ntex")
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// server http response
|
||||||
|
println!("Response: {:?}", response);
|
||||||
|
|
||||||
|
// read response body
|
||||||
|
let body = response.body().await.unwrap();
|
||||||
|
println!("Downloaded: {:?} bytes", body.len());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
35
ntex/examples/echo.rs
Normal file
35
ntex/examples/echo.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
use std::{env, io};
|
||||||
|
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use log::info;
|
||||||
|
use ntex::http::header::HeaderValue;
|
||||||
|
use ntex::http::{HttpService, Request, Response};
|
||||||
|
use ntex::{server::Server, time::Seconds, util::BytesMut};
|
||||||
|
|
||||||
|
#[ntex::main]
|
||||||
|
async fn main() -> io::Result<()> {
|
||||||
|
env::set_var("RUST_LOG", "echo=info");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
Server::build()
|
||||||
|
.bind("echo", "127.0.0.1:8080", |_| {
|
||||||
|
HttpService::build()
|
||||||
|
.client_timeout(Seconds(1))
|
||||||
|
.disconnect_timeout(Seconds(1))
|
||||||
|
.finish(|mut req: Request| async move {
|
||||||
|
let mut body = BytesMut::new();
|
||||||
|
while let Some(item) = req.payload().next().await {
|
||||||
|
body.extend_from_slice(&item.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("request body: {:?}", body);
|
||||||
|
Ok::<_, io::Error>(
|
||||||
|
Response::Ok()
|
||||||
|
.header("x-head", HeaderValue::from_static("dummy value!"))
|
||||||
|
.body(body),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
31
ntex/examples/echo2.rs
Normal file
31
ntex/examples/echo2.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use std::{env, io};
|
||||||
|
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use log::info;
|
||||||
|
use ntex::http::{header::HeaderValue, HttpService, Request, Response};
|
||||||
|
use ntex::{server::Server, util::BytesMut};
|
||||||
|
|
||||||
|
async fn handle_request(mut req: Request) -> Result<Response, io::Error> {
|
||||||
|
let mut body = BytesMut::new();
|
||||||
|
while let Some(item) = req.payload().next().await {
|
||||||
|
body.extend_from_slice(&item.unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("request body: {:?}", body);
|
||||||
|
Ok(Response::Ok()
|
||||||
|
.header("x-head", HeaderValue::from_static("dummy value!"))
|
||||||
|
.body(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ntex::main]
|
||||||
|
async fn main() -> io::Result<()> {
|
||||||
|
env::set_var("RUST_LOG", "echo=info");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
Server::build()
|
||||||
|
.bind("echo", "127.0.0.1:8080", |_| {
|
||||||
|
HttpService::build().finish(handle_request)
|
||||||
|
})?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
27
ntex/examples/hello-world.rs
Normal file
27
ntex/examples/hello-world.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
use std::{env, io};
|
||||||
|
|
||||||
|
use log::info;
|
||||||
|
use ntex::http::header::HeaderValue;
|
||||||
|
use ntex::http::{HttpService, Response};
|
||||||
|
use ntex::{server::Server, time::Seconds, util::Ready};
|
||||||
|
|
||||||
|
#[ntex::main]
|
||||||
|
async fn main() -> io::Result<()> {
|
||||||
|
env::set_var("RUST_LOG", "ntex=trace,hello_world=info");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
Server::build()
|
||||||
|
.bind("hello-world", "127.0.0.1:8080", |_| {
|
||||||
|
HttpService::build()
|
||||||
|
.client_timeout(Seconds(1))
|
||||||
|
.disconnect_timeout(Seconds(1))
|
||||||
|
.finish(|_req| {
|
||||||
|
info!("{:?}", _req);
|
||||||
|
let mut res = Response::Ok();
|
||||||
|
res.header("x-head", HeaderValue::from_static("dummy value!"));
|
||||||
|
Ready::Ok::<_, io::Error>(res.body("Hello world!"))
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
47
ntex/examples/uds.rs
Normal file
47
ntex/examples/uds.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use ntex::web::{self, middleware, App, HttpRequest, HttpResponse, HttpServer};
|
||||||
|
|
||||||
|
#[web::get("/resource1/{name}/index.html")]
|
||||||
|
async fn index(req: HttpRequest, name: web::types::Path<String>) -> String {
|
||||||
|
println!("REQ: {:?}", req);
|
||||||
|
format!("Hello: {}!\r\n", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index_async(req: HttpRequest) -> Result<&'static str, std::io::Error> {
|
||||||
|
println!("REQ: {:?}", req);
|
||||||
|
Ok("Hello world!\r\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[web::get("/")]
|
||||||
|
async fn no_params() -> &'static str {
|
||||||
|
"Hello world!\r\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[ntex::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
std::env::set_var("RUST_LOG", "ntex=info");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
HttpServer::new(|| {
|
||||||
|
App::new()
|
||||||
|
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
|
||||||
|
.wrap(middleware::Logger::default())
|
||||||
|
.service((index, no_params))
|
||||||
|
.service(
|
||||||
|
web::resource("/resource2/index.html")
|
||||||
|
.wrap(middleware::DefaultHeaders::new().header("X-Version-R2", "0.3"))
|
||||||
|
.default_service(
|
||||||
|
web::route().to(|| async { HttpResponse::MethodNotAllowed() }),
|
||||||
|
)
|
||||||
|
.route(web::get().to(index_async)),
|
||||||
|
)
|
||||||
|
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))
|
||||||
|
})
|
||||||
|
.bind_uds("/tmp/uds-test")?
|
||||||
|
.workers(1)
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
fn main() {}
|
|
@ -28,6 +28,8 @@ pub trait ResponseError: fmt::Display + fmt::Debug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ResponseError for std::convert::Infallible {}
|
||||||
|
|
||||||
impl<'a, T: ResponseError> ResponseError for &'a T {
|
impl<'a, T: ResponseError> ResponseError for &'a T {
|
||||||
fn error_response(&self) -> Response {
|
fn error_response(&self) -> Response {
|
||||||
(*self).error_response()
|
(*self).error_response()
|
||||||
|
|
|
@ -6,11 +6,13 @@ use crate::service::{map_config, pipeline_factory, PipelineFactory};
|
||||||
use crate::service::{Identity, IntoServiceFactory, Service, ServiceFactory, Transform};
|
use crate::service::{Identity, IntoServiceFactory, Service, ServiceFactory, Transform};
|
||||||
use crate::util::Extensions;
|
use crate::util::Extensions;
|
||||||
|
|
||||||
use super::app_service::{AppFactory, AppService};
|
use super::app_service::{
|
||||||
|
AppFactory, AppFactoryInner, AppRouting, AppService, DefaultService,
|
||||||
|
};
|
||||||
use super::boxed::{self, BoxServiceFactory};
|
use super::boxed::{self, BoxServiceFactory};
|
||||||
use super::config::{AppConfig, ServiceConfig};
|
use super::config::{AppConfig, ServiceConfig};
|
||||||
use super::service::{AppServiceFactory, ServiceFactoryWrapper, WebServiceFactory};
|
use super::service::{create_web_service, WebService, WebServiceWrapper};
|
||||||
use super::stack::{Filter, Next, Stack};
|
use super::stack::{Filter, Filters, FiltersFactory, Next, Stack};
|
||||||
use super::types::state::{State, StateFactory};
|
use super::types::state::{State, StateFactory};
|
||||||
use super::{DefaultError, ErrorRenderer, Resource, Route, WebRequest, WebResponse};
|
use super::{DefaultError, ErrorRenderer, Resource, Route, WebRequest, WebResponse};
|
||||||
|
|
||||||
|
@ -21,9 +23,9 @@ type FnStateFactory =
|
||||||
/// for building application instances.
|
/// for building application instances.
|
||||||
pub struct App<'a, M, F, Err: ErrorRenderer = DefaultError> {
|
pub struct App<'a, M, F, Err: ErrorRenderer = DefaultError> {
|
||||||
middleware: M,
|
middleware: M,
|
||||||
filter: PipelineFactory<F, &'a mut WebRequest<Err>>,
|
filter: F,
|
||||||
services: Vec<Box<dyn AppServiceFactory<'a, Err>>>,
|
services: Vec<Box<dyn WebServiceWrapper<'a, Err>>>,
|
||||||
default: Option<Rc<BoxServiceFactory<'a, Err>>>,
|
default: BoxServiceFactory<'a, Err>,
|
||||||
state: Vec<Box<dyn StateFactory>>,
|
state: Vec<Box<dyn StateFactory>>,
|
||||||
state_factories: Vec<FnStateFactory>,
|
state_factories: Vec<FnStateFactory>,
|
||||||
external: Vec<ResourceDef>,
|
external: Vec<ResourceDef>,
|
||||||
|
@ -32,53 +34,44 @@ pub struct App<'a, M, F, Err: ErrorRenderer = DefaultError> {
|
||||||
case_insensitive: bool,
|
case_insensitive: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> App<'a, Identity, Filter<DefaultError>, DefaultError> {
|
impl<'a> App<'a, Identity, Filter, DefaultError> {
|
||||||
/// Create application builder. Application can be configured with a builder-like pattern.
|
/// Create application builder. Application can be configured with a builder-like pattern.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
// App {
|
App {
|
||||||
// middleware: Identity,
|
filter: Filter,
|
||||||
// filter: pipeline_factory(Filter::new()),
|
middleware: Identity,
|
||||||
// state: Vec::new(),
|
state: Vec::new(),
|
||||||
// state_factories: Vec::new(),
|
state_factories: Vec::new(),
|
||||||
// services: Vec::new(),
|
services: Vec::new(),
|
||||||
// default: None,
|
default: boxed::factory(DefaultService::default()),
|
||||||
// external: Vec::new(),
|
external: Vec::new(),
|
||||||
// extensions: Extensions::new(),
|
extensions: Extensions::new(),
|
||||||
// error_renderer: DefaultError,
|
error_renderer: DefaultError,
|
||||||
// case_insensitive: false,
|
case_insensitive: false,
|
||||||
// }
|
}
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> App<'a, Identity, Filter<Err>, Err> {
|
impl<'a, Err: ErrorRenderer> App<'a, Identity, Filter, Err> {
|
||||||
/// Create application builder with custom error renderer.
|
/// Create application builder with custom error renderer.
|
||||||
pub fn with(err: Err) -> Self {
|
pub fn with(err: Err) -> Self {
|
||||||
// App {
|
App {
|
||||||
// middleware: Identity,
|
filter: Filter,
|
||||||
// filter: pipeline_factory(Filter::new()),
|
middleware: Identity,
|
||||||
// state: Vec::new(),
|
state: Vec::new(),
|
||||||
// state_factories: Vec::new(),
|
state_factories: Vec::new(),
|
||||||
// services: Vec::new(),
|
services: Vec::new(),
|
||||||
// default: None,
|
default: boxed::factory(DefaultService::default()),
|
||||||
// external: Vec::new(),
|
external: Vec::new(),
|
||||||
// extensions: Extensions::new(),
|
extensions: Extensions::new(),
|
||||||
// error_renderer: err,
|
error_renderer: err,
|
||||||
// case_insensitive: false,
|
case_insensitive: false,
|
||||||
// }
|
}
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, T, Err> App<'a, M, T, Err>
|
impl<'a, M, F, Err> App<'a, M, F, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<
|
|
||||||
&'a mut WebRequest<Err>,
|
|
||||||
Response = &'a mut WebRequest<Err>,
|
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
>,
|
|
||||||
T::Future: 'static,
|
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
/// Set application state. Application state could be accessed
|
/// Set application state. Application state could be accessed
|
||||||
|
@ -119,9 +112,9 @@ where
|
||||||
/// Set application state factory. This function is
|
/// Set application state factory. This function is
|
||||||
/// similar to `.state()` but it accepts state factory. State object get
|
/// similar to `.state()` but it accepts state factory. State object get
|
||||||
/// constructed asynchronously during application initialization.
|
/// constructed asynchronously during application initialization.
|
||||||
pub fn state_factory<F, Out, D, E>(mut self, state: F) -> Self
|
pub fn state_factory<T, Out, D, E>(mut self, state: T) -> Self
|
||||||
where
|
where
|
||||||
F: Fn() -> Out + 'static,
|
T: Fn() -> Out + 'static,
|
||||||
Out: Future<Output = Result<D, E>> + 'static,
|
Out: Future<Output = Result<D, E>> + 'static,
|
||||||
D: 'static,
|
D: 'static,
|
||||||
E: fmt::Debug,
|
E: fmt::Debug,
|
||||||
|
@ -181,9 +174,9 @@ where
|
||||||
/// .route("/index.html", web::get().to(|| async { HttpResponse::Ok() }));
|
/// .route("/index.html", web::get().to(|| async { HttpResponse::Ok() }));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn configure<F>(mut self, f: F) -> Self
|
pub fn configure<U>(mut self, f: U) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut ServiceConfig<'a, Err>),
|
U: FnOnce(&mut ServiceConfig<'a, Err>),
|
||||||
{
|
{
|
||||||
let mut cfg = ServiceConfig::new();
|
let mut cfg = ServiceConfig::new();
|
||||||
f(&mut cfg);
|
f(&mut cfg);
|
||||||
|
@ -213,12 +206,11 @@ where
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn route(self, path: &str, mut route: Route<Err>) -> Self {
|
pub fn route(self, path: &str, mut route: Route<Err>) -> Self {
|
||||||
// self.service(
|
self.service(
|
||||||
// Resource::new(path)
|
Resource::new(path)
|
||||||
// .add_guards(route.take_guards())
|
.add_guards(route.take_guards())
|
||||||
// .route(route),
|
.route(route),
|
||||||
// )
|
)
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register http service.
|
/// Register http service.
|
||||||
|
@ -230,12 +222,11 @@ where
|
||||||
/// * *Resource* is an entry in resource table which corresponds to requested URL.
|
/// * *Resource* is an entry in resource table which corresponds to requested URL.
|
||||||
/// * *Scope* is a set of resources with common root path.
|
/// * *Scope* is a set of resources with common root path.
|
||||||
/// * "StaticFiles" is a service for static files support
|
/// * "StaticFiles" is a service for static files support
|
||||||
pub fn service<F>(mut self, factory: F) -> Self
|
pub fn service<U>(mut self, factory: U) -> Self
|
||||||
where
|
where
|
||||||
F: WebServiceFactory<'a, Err> + 'static,
|
U: WebService<'a, Err> + 'static,
|
||||||
{
|
{
|
||||||
self.services
|
self.services.push(create_web_service(factory));
|
||||||
.push(Box::new(ServiceFactoryWrapper::new(factory)));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,25 +259,28 @@ where
|
||||||
/// let app = App::new()
|
/// let app = App::new()
|
||||||
/// .service(
|
/// .service(
|
||||||
/// web::resource("/index.html").to(|| async { HttpResponse::Ok() }))
|
/// web::resource("/index.html").to(|| async { HttpResponse::Ok() }))
|
||||||
/// .default_service(
|
/// .default(
|
||||||
/// web::to(|| async { HttpResponse::NotFound() })
|
/// web::to(|| async { HttpResponse::NotFound() })
|
||||||
/// );
|
/// );
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn default_service<F, U>(mut self, f: F) -> Self
|
pub fn default<T, U>(mut self, f: T) -> Self
|
||||||
where
|
where
|
||||||
F: IntoServiceFactory<U, &'a mut WebRequest<Err>>,
|
T: IntoServiceFactory<U, &'a mut WebRequest<'a, Err>>,
|
||||||
U: ServiceFactory<
|
U: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
Response = WebResponse,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
> + 'static,
|
> + 'static,
|
||||||
U::InitError: fmt::Debug,
|
U::Service: 'static,
|
||||||
|
U::Future: 'static,
|
||||||
|
U::InitError: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
// // create and configure default resource
|
// create and configure default resource
|
||||||
// self.default = Some(Rc::new(boxed::factory(f.into_factory().map_init_err(
|
self.default =
|
||||||
// |e| log::error!("Cannot construct default service: {:?}", e),
|
boxed::factory::<'a, _, _>(f.into_factory().map_init_err(|e| {
|
||||||
// ))));
|
log::error!("Cannot construct default service: {:?}", e)
|
||||||
|
}));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -349,31 +343,9 @@ where
|
||||||
/// .route("/index.html", web::get().to(index));
|
/// .route("/index.html", web::get().to(index));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn filter<S, U>(
|
pub fn filter<U>(self, filter: U) -> App<'a, M, Filters<F, U>, Err> {
|
||||||
self,
|
|
||||||
filter: U,
|
|
||||||
) -> App<
|
|
||||||
'a,
|
|
||||||
M,
|
|
||||||
impl ServiceFactory<
|
|
||||||
&'a mut WebRequest<Err>,
|
|
||||||
Response = &'a mut WebRequest<Err>,
|
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
>,
|
|
||||||
Err,
|
|
||||||
>
|
|
||||||
where
|
|
||||||
S: ServiceFactory<
|
|
||||||
&'a mut WebRequest<Err>,
|
|
||||||
Response = &'a mut WebRequest<Err>,
|
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
>,
|
|
||||||
U: IntoServiceFactory<S, &'a mut WebRequest<Err>>,
|
|
||||||
{
|
|
||||||
App {
|
App {
|
||||||
filter: self.filter.and_then(filter.into_factory()),
|
filter: Filters::new(self.filter, filter),
|
||||||
middleware: self.middleware,
|
middleware: self.middleware,
|
||||||
state: self.state,
|
state: self.state,
|
||||||
state_factories: self.state_factories,
|
state_factories: self.state_factories,
|
||||||
|
@ -412,7 +384,7 @@ where
|
||||||
/// .route("/index.html", web::get().to(index));
|
/// .route("/index.html", web::get().to(index));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn wrap<U>(self, mw: U) -> App<'a, Stack<M, U, Err>, T, Err> {
|
pub fn wrap<U>(self, mw: U) -> App<'a, Stack<M, U>, F, Err> {
|
||||||
App {
|
App {
|
||||||
middleware: Stack::new(self.middleware, mw),
|
middleware: Stack::new(self.middleware, mw),
|
||||||
filter: self.filter,
|
filter: self.filter,
|
||||||
|
@ -438,15 +410,18 @@ where
|
||||||
|
|
||||||
impl<'a, M, F, Err> App<'a, M, F, Err>
|
impl<'a, M, F, Err> App<'a, M, F, Err>
|
||||||
where
|
where
|
||||||
M: Transform<Next<AppService<'a, F::Service, Err>, Err>> + 'static,
|
M: Transform<
|
||||||
M::Service:
|
AppRouting<
|
||||||
Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
'a,
|
||||||
F: ServiceFactory<
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
&'a mut WebRequest<Err>,
|
Err,
|
||||||
Response = &'a mut WebRequest<Err>,
|
>,
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
> + 'static,
|
> + 'static,
|
||||||
|
M::Service:
|
||||||
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
|
F: FiltersFactory<'a, Err> + 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
/// Construct service factory with default `AppConfig`, suitable for `http::HttpService`.
|
/// Construct service factory with default `AppConfig`, suitable for `http::HttpService`.
|
||||||
|
@ -469,13 +444,9 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
pub fn finish(
|
pub fn finish(
|
||||||
self,
|
self,
|
||||||
) -> impl ServiceFactory<
|
) -> impl ServiceFactory<Request, Response = WebResponse, Error = Infallible, InitError = ()>
|
||||||
Request,
|
{
|
||||||
Response = WebResponse,
|
IntoServiceFactory::<AppFactory, Request, ()>::into_factory(self)
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
> + 'a {
|
|
||||||
IntoServiceFactory::<AppFactory<'a, M, F, Err>, Request, ()>::into_factory(self)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct service factory suitable for `http::HttpService`.
|
/// Construct service factory suitable for `http::HttpService`.
|
||||||
|
@ -499,82 +470,85 @@ where
|
||||||
pub fn with_config(
|
pub fn with_config(
|
||||||
self,
|
self,
|
||||||
cfg: AppConfig,
|
cfg: AppConfig,
|
||||||
) -> impl ServiceFactory<
|
) -> impl ServiceFactory<Request, Response = WebResponse, Error = Infallible, InitError = ()>
|
||||||
Request,
|
{
|
||||||
Response = WebResponse,
|
let app = AppFactoryInner {
|
||||||
Error = Err::Container,
|
filter: Some(self.filter),
|
||||||
InitError = (),
|
|
||||||
> + 'a {
|
|
||||||
let app = AppFactory {
|
|
||||||
filter: self.filter,
|
|
||||||
middleware: Rc::new(self.middleware),
|
middleware: Rc::new(self.middleware),
|
||||||
state: Rc::new(self.state),
|
state: Rc::new(self.state),
|
||||||
state_factories: Rc::new(self.state_factories),
|
state_factories: Rc::new(self.state_factories),
|
||||||
services: Rc::new(RefCell::new(self.services)),
|
services: Rc::new(RefCell::new(self.services)),
|
||||||
external: RefCell::new(self.external),
|
external: RefCell::new(self.external),
|
||||||
default: self.default,
|
default: Some(self.default),
|
||||||
extensions: RefCell::new(Some(self.extensions)),
|
extensions: RefCell::new(Some(self.extensions)),
|
||||||
case_insensitive: self.case_insensitive,
|
case_insensitive: self.case_insensitive,
|
||||||
};
|
};
|
||||||
map_config(app, move |_| cfg.clone())
|
map_config(AppFactory::new(app), move |_| cfg.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, F, Err> IntoServiceFactory<AppFactory<'a, M, F, Err>, Request, AppConfig>
|
impl<'a, M, F, Err> IntoServiceFactory<AppFactory, Request, AppConfig>
|
||||||
for App<'a, M, F, Err>
|
for App<'a, M, F, Err>
|
||||||
where
|
where
|
||||||
M: Transform<Next<AppService<'a, F::Service, Err>, Err>> + 'static,
|
M: 'static,
|
||||||
|
M: Transform<
|
||||||
|
AppRouting<
|
||||||
|
'a,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
|
Err,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
M::Service:
|
M::Service:
|
||||||
Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
F: ServiceFactory<
|
F: FiltersFactory<'a, Err> + 'static,
|
||||||
&'a mut WebRequest<Err>,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
Response = &'a mut WebRequest<Err>,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
> + 'static,
|
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
fn into_factory(self) -> AppFactory<'a, M, F, Err> {
|
fn into_factory(self) -> AppFactory {
|
||||||
AppFactory {
|
AppFactory::new(AppFactoryInner {
|
||||||
filter: self.filter,
|
filter: Some(self.filter),
|
||||||
middleware: Rc::new(self.middleware),
|
middleware: Rc::new(self.middleware),
|
||||||
state: Rc::new(self.state),
|
state: Rc::new(self.state),
|
||||||
state_factories: Rc::new(self.state_factories),
|
state_factories: Rc::new(self.state_factories),
|
||||||
services: Rc::new(RefCell::new(self.services)),
|
services: Rc::new(RefCell::new(self.services)),
|
||||||
external: RefCell::new(self.external),
|
external: RefCell::new(self.external),
|
||||||
default: self.default,
|
default: Some(self.default),
|
||||||
extensions: RefCell::new(Some(self.extensions)),
|
extensions: RefCell::new(Some(self.extensions)),
|
||||||
case_insensitive: self.case_insensitive,
|
case_insensitive: self.case_insensitive,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, F, Err> IntoServiceFactory<AppFactory<'a, M, F, Err>, Request, ()>
|
impl<'a, M, F, Err> IntoServiceFactory<AppFactory, Request, ()> for App<'a, M, F, Err>
|
||||||
for App<'a, M, F, Err>
|
|
||||||
where
|
where
|
||||||
M: Transform<Next<AppService<'a, F::Service, Err>, Err>> + 'static,
|
M: 'static,
|
||||||
|
M: Transform<
|
||||||
|
AppRouting<
|
||||||
|
'a,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
|
Err,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
M::Service:
|
M::Service:
|
||||||
Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
F: ServiceFactory<
|
F: FiltersFactory<'a, Err> + 'static,
|
||||||
&'a mut WebRequest<Err>,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
Response = &'a mut WebRequest<Err>,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
> + 'static,
|
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
fn into_factory(self) -> AppFactory<'a, M, F, Err> {
|
fn into_factory(self) -> AppFactory {
|
||||||
AppFactory {
|
AppFactory::new(AppFactoryInner {
|
||||||
filter: self.filter,
|
filter: Some(self.filter),
|
||||||
middleware: Rc::new(self.middleware),
|
middleware: Rc::new(self.middleware),
|
||||||
state: Rc::new(self.state),
|
state: Rc::new(self.state),
|
||||||
state_factories: Rc::new(self.state_factories),
|
state_factories: Rc::new(self.state_factories),
|
||||||
services: Rc::new(RefCell::new(self.services)),
|
services: Rc::new(RefCell::new(self.services)),
|
||||||
external: RefCell::new(self.external),
|
external: RefCell::new(self.external),
|
||||||
default: self.default,
|
default: Some(self.default),
|
||||||
extensions: RefCell::new(Some(self.extensions)),
|
extensions: RefCell::new(Some(self.extensions)),
|
||||||
case_insensitive: self.case_insensitive,
|
case_insensitive: self.case_insensitive,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,12 +585,10 @@ mod tests {
|
||||||
.service(web::resource("/test").to(|| async { HttpResponse::Ok() }))
|
.service(web::resource("/test").to(|| async { HttpResponse::Ok() }))
|
||||||
.service(
|
.service(
|
||||||
web::resource("/test2")
|
web::resource("/test2")
|
||||||
.default_service(|r: WebRequest<DefaultError>| async move {
|
.default(|| async move { HttpResponse::Created() })
|
||||||
Ok(r.into_response(HttpResponse::Created()))
|
|
||||||
})
|
|
||||||
.route(web::get().to(|| async { HttpResponse::Ok() })),
|
.route(web::get().to(|| async { HttpResponse::Ok() })),
|
||||||
)
|
)
|
||||||
.default_service(|r: WebRequest<DefaultError>| async move {
|
.default(|r: WebRequest<'_, DefaultError>| async move {
|
||||||
Ok(r.into_response(HttpResponse::MethodNotAllowed()))
|
Ok(r.into_response(HttpResponse::MethodNotAllowed()))
|
||||||
})
|
})
|
||||||
.with_config(Default::default())
|
.with_config(Default::default())
|
||||||
|
|
|
@ -7,106 +7,198 @@ use crate::router::{Path, ResourceDef, Router};
|
||||||
use crate::service::{
|
use crate::service::{
|
||||||
fn_service, into_service, PipelineFactory, Service, ServiceFactory, Transform,
|
fn_service, into_service, PipelineFactory, Service, ServiceFactory, Transform,
|
||||||
};
|
};
|
||||||
use crate::util::{ready, Extensions};
|
use crate::util::{ready, Extensions, Ready};
|
||||||
|
|
||||||
use super::boxed::{self, BoxService, BoxServiceFactory};
|
use super::boxed::{self, BoxService, BoxServiceFactory};
|
||||||
use super::config::AppConfig;
|
use super::config::AppConfig;
|
||||||
use super::guard::Guard;
|
use super::guard::Guard;
|
||||||
use super::httprequest::{HttpRequest, HttpRequestPool};
|
use super::httprequest::{HttpRequest, HttpRequestPool};
|
||||||
use super::rmap::ResourceMap;
|
use super::rmap::ResourceMap;
|
||||||
use super::service::{AppServiceFactory, WebServiceConfig};
|
use super::service::{WebService, WebServiceConfig, WebServiceWrapper};
|
||||||
use super::stack::Next;
|
use super::stack::{Filter, FiltersFactory, Next};
|
||||||
use super::types::state::StateFactory;
|
use super::types::state::StateFactory;
|
||||||
use super::{ErrorRenderer, WebRequest, WebResponse};
|
use super::{ErrorContainer, ErrorRenderer, WebRequest, WebResponse};
|
||||||
|
|
||||||
type Guards = Vec<Box<dyn Guard>>;
|
type Guards = Vec<Box<dyn Guard>>;
|
||||||
type BoxResponse<'a, Err: ErrorRenderer> =
|
type BoxResponse<'a> = Pin<Box<dyn Future<Output = Result<WebResponse, Infallible>> + 'a>>;
|
||||||
Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>> + 'a>>;
|
|
||||||
type FnStateFactory =
|
type FnStateFactory =
|
||||||
Box<dyn Fn() -> Pin<Box<dyn Future<Output = Result<Box<dyn StateFactory>, ()>>>>>;
|
Box<dyn Fn() -> Pin<Box<dyn Future<Output = Result<Box<dyn StateFactory>, ()>>>>>;
|
||||||
|
|
||||||
/// Service factory to convert `Request` to a `WebRequest<S>`.
|
/// Service factory for converting `Request` to a `WebResponse>`.
|
||||||
|
///
|
||||||
/// It also executes state factories.
|
/// It also executes state factories.
|
||||||
pub struct AppFactory<'a, T, F, Err: ErrorRenderer>
|
pub struct AppFactory(WebAppFactory);
|
||||||
|
|
||||||
|
pub struct AppService(WebAppHandler);
|
||||||
|
|
||||||
|
type WebAppFactory =
|
||||||
|
Box<dyn Fn(AppConfig) -> Pin<Box<dyn Future<Output = Result<AppService, ()>>>>>;
|
||||||
|
type WebAppHandler =
|
||||||
|
Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Result<WebResponse, Infallible>>>>>;
|
||||||
|
type WebAppHandler2<'a> = Box<
|
||||||
|
dyn Fn(Request) -> Pin<Box<dyn Future<Output = Result<WebResponse, Infallible>> + 'a>>
|
||||||
|
+ 'a,
|
||||||
|
>;
|
||||||
|
|
||||||
|
impl AppFactory {
|
||||||
|
pub(super) fn new<'a, M, F, Err: ErrorRenderer>(
|
||||||
|
app: AppFactoryInner<'a, M, F, Err>,
|
||||||
|
) -> Self
|
||||||
where
|
where
|
||||||
F: ServiceFactory<
|
M: Transform<
|
||||||
&'a mut WebRequest<Err>,
|
AppRouting<
|
||||||
Response = &'a mut WebRequest<Err>,
|
'a,
|
||||||
Error = Err::Container,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
InitError = (),
|
Err,
|
||||||
|
>,
|
||||||
> + 'static,
|
> + 'static,
|
||||||
|
M::Service: Service<
|
||||||
|
&'a mut WebRequest<'a, Err>,
|
||||||
|
Response = WebResponse,
|
||||||
|
Error = Infallible,
|
||||||
|
>,
|
||||||
|
F: FiltersFactory<'a, Err> + 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
pub(super) middleware: Rc<T>,
|
let app = RefCell::new(app);
|
||||||
pub(super) filter: PipelineFactory<F, &'a mut WebRequest<Err>>,
|
let b: Box<
|
||||||
pub(super) extensions: RefCell<Option<Extensions>>,
|
dyn Fn(AppConfig) -> Pin<Box<dyn Future<Output = Result<AppService, ()>>>> + 'a,
|
||||||
pub(super) state: Rc<Vec<Box<dyn StateFactory>>>,
|
> = Box::new(move |cfg| {
|
||||||
pub(super) state_factories: Rc<Vec<FnStateFactory>>,
|
let fut = app.borrow_mut().create(cfg);
|
||||||
pub(super) services: Rc<RefCell<Vec<Box<dyn AppServiceFactory<'a, Err>>>>>,
|
Box::pin(async move { Ok(AppService(fut.await?)) })
|
||||||
pub(super) default: Option<Rc<BoxServiceFactory<'a, Err>>>,
|
});
|
||||||
pub(super) external: RefCell<Vec<ResourceDef>>,
|
AppFactory(unsafe { std::mem::transmute(b) })
|
||||||
pub(super) case_insensitive: bool,
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, F, Err> ServiceFactory<Request> for AppFactory<'a, T, F, Err>
|
impl ServiceFactory<Request> for AppFactory {
|
||||||
where
|
|
||||||
T: Transform<Next<AppService<'a, F::Service, Err>, Err>> + 'static,
|
|
||||||
T::Service:
|
|
||||||
Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
|
||||||
F: ServiceFactory<
|
|
||||||
&'a mut WebRequest<Err>,
|
|
||||||
Response = &'a mut WebRequest<Err>,
|
|
||||||
Error = Err::Container,
|
|
||||||
InitError = (),
|
|
||||||
> + 'static,
|
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Infallible;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = AppFactoryService<'a, T::Service, Err>;
|
type Service = AppService;
|
||||||
type Future =
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Service, Self::InitError>>>>;
|
||||||
Pin<Box<dyn Future<Output = Result<Self::Service, Self::InitError>> + 'a>>;
|
|
||||||
|
|
||||||
fn new_service(&self, _: ()) -> Self::Future {
|
fn new_service(&self, _: ()) -> Self::Future {
|
||||||
ServiceFactory::<Request, AppConfig>::new_service(self, AppConfig::default())
|
ServiceFactory::<Request, AppConfig>::new_service(self, AppConfig::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, F, Err> ServiceFactory<Request, AppConfig> for AppFactory<'a, T, F, Err>
|
impl ServiceFactory<Request, AppConfig> for AppFactory {
|
||||||
|
type Response = WebResponse;
|
||||||
|
type Error = Infallible;
|
||||||
|
type InitError = ();
|
||||||
|
type Service = AppService;
|
||||||
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Service, Self::InitError>>>>;
|
||||||
|
|
||||||
|
fn new_service(&self, cfg: AppConfig) -> Self::Future {
|
||||||
|
(&*self.0)(cfg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Service<Request> for AppService {
|
||||||
|
type Response = WebResponse;
|
||||||
|
type Error = Infallible;
|
||||||
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||||
|
|
||||||
|
fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&self, req: Request) -> Self::Future {
|
||||||
|
(&*self.0)(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Service factory to convert `Request` to a `WebRequest<S>`.
|
||||||
|
/// It also executes state factories.
|
||||||
|
pub(super) struct AppFactoryInner<'a, M, F, Err: ErrorRenderer>
|
||||||
where
|
where
|
||||||
T: Transform<Next<AppService<'a, F::Service, Err>, Err>> + 'static,
|
M: Transform<
|
||||||
T::Service:
|
AppRouting<
|
||||||
Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
'a,
|
||||||
F: ServiceFactory<
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
&'a mut WebRequest<Err>,
|
Err,
|
||||||
Response = &'a mut WebRequest<Err>,
|
>,
|
||||||
Error = Err::Container,
|
>,
|
||||||
InitError = (),
|
M::Service:
|
||||||
> + 'static,
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
|
F: FiltersFactory<'a, Err>,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
|
{
|
||||||
|
pub(super) middleware: Rc<M>,
|
||||||
|
pub(super) filter: Option<F>,
|
||||||
|
pub(super) extensions: RefCell<Option<Extensions>>,
|
||||||
|
pub(super) state: Rc<Vec<Box<dyn StateFactory>>>,
|
||||||
|
pub(super) state_factories: Rc<Vec<FnStateFactory>>,
|
||||||
|
pub(super) services: Rc<RefCell<Vec<Box<dyn WebServiceWrapper<'a, Err>>>>>,
|
||||||
|
pub(super) default: Option<BoxServiceFactory<'a, Err>>,
|
||||||
|
pub(super) external: RefCell<Vec<ResourceDef>>,
|
||||||
|
pub(super) case_insensitive: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub(super) struct DefaultService<Err>(PhantomData<Err>);
|
||||||
|
|
||||||
|
impl<Err> Default for DefaultService<Err> {
|
||||||
|
fn default() -> Self {
|
||||||
|
DefaultService(PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<'a, Err>>
|
||||||
|
for DefaultService<Err>
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = AppFactoryService<'a, T::Service, Err>;
|
type Service = Self;
|
||||||
type Future =
|
type Future = Ready<Self::Service, Self::InitError>;
|
||||||
Pin<Box<dyn Future<Output = Result<Self::Service, Self::InitError>> + 'a>>;
|
|
||||||
|
|
||||||
fn new_service(&self, config: AppConfig) -> Self::Future {
|
fn new_service(&self, cfg: ()) -> Self::Future {
|
||||||
|
Ready::Ok(DefaultService(PhantomData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<'a, Err>> for DefaultService<Err> {
|
||||||
|
type Response = WebResponse;
|
||||||
|
type Error = Err::Container;
|
||||||
|
type Future = Ready<Self::Response, Self::Error>;
|
||||||
|
|
||||||
|
fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&self, _: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
|
Ready::Ok(Response::NotFound().finish().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T, F, Err> AppFactoryInner<'a, T, F, Err>
|
||||||
|
where
|
||||||
|
T: Transform<
|
||||||
|
AppRouting<
|
||||||
|
'a,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
|
Err,
|
||||||
|
>,
|
||||||
|
> + 'static,
|
||||||
|
T::Service:
|
||||||
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
|
F: FiltersFactory<'a, Err> + 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
|
Err: ErrorRenderer + 'static,
|
||||||
|
{
|
||||||
|
pub(super) fn create(
|
||||||
|
&mut self,
|
||||||
|
config: AppConfig,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<WebAppHandler, ()>>>> {
|
||||||
// update resource default service
|
// update resource default service
|
||||||
let default = self.default.clone().unwrap_or_else(|| panic!());
|
let default = Rc::new(self.default.take().unwrap());
|
||||||
|
|
||||||
// .unwrap_or_else(|| {
|
|
||||||
// Rc::new(boxed::factory(into_service(
|
|
||||||
// |req: &'a mut WebRequest<Err>| {
|
|
||||||
// let res = req.into_response(Response::NotFound().finish());
|
|
||||||
// async move {
|
|
||||||
// Ok(res)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// )))
|
|
||||||
// });
|
|
||||||
|
|
||||||
// App config
|
// App config
|
||||||
let mut config = WebServiceConfig::new(config, default.clone(), self.state.clone());
|
let mut config = WebServiceConfig::new(config, default.clone(), self.state.clone());
|
||||||
|
@ -142,7 +234,7 @@ where
|
||||||
let rmap = Rc::new(rmap);
|
let rmap = Rc::new(rmap);
|
||||||
rmap.finish(rmap.clone());
|
rmap.finish(rmap.clone());
|
||||||
|
|
||||||
let filter_fut = self.filter.new_service(());
|
let filter_fut = self.filter.take().unwrap().create().new_service(());
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
let state_factories = self.state_factories.clone();
|
let state_factories = self.state_factories.clone();
|
||||||
let mut extensions = self
|
let mut extensions = self
|
||||||
|
@ -152,6 +244,7 @@ where
|
||||||
.unwrap_or_else(Extensions::new);
|
.unwrap_or_else(Extensions::new);
|
||||||
let middleware = self.middleware.clone();
|
let middleware = self.middleware.clone();
|
||||||
|
|
||||||
|
let f: Pin<Box<dyn Future<Output = Result<WebAppHandler, ()>> + 'a>> =
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
// create http services
|
// create http services
|
||||||
for (path, factory, guards) in &mut services.iter() {
|
for (path, factory, guards) in &mut services.iter() {
|
||||||
|
@ -159,15 +252,13 @@ where
|
||||||
router.rdef(path.clone(), service).2 = guards.borrow_mut().take();
|
router.rdef(path.clone(), service).2 = guards.borrow_mut().take();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// router
|
||||||
let routing = AppRouting {
|
let routing = AppRouting {
|
||||||
|
filter: filter_fut.await?,
|
||||||
|
router: Rc::new(AppRouter {
|
||||||
router: router.finish(),
|
router: router.finish(),
|
||||||
default: Some(default_fut.await?),
|
default: Some(default_fut.await?),
|
||||||
};
|
}),
|
||||||
|
|
||||||
// main service
|
|
||||||
let service = AppService {
|
|
||||||
filter: filter_fut.await?,
|
|
||||||
routing: Rc::new(routing),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// create app state container
|
// create app state container
|
||||||
|
@ -182,127 +273,97 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(AppFactoryService {
|
let service = middleware.new_transform(routing);
|
||||||
rmap,
|
let state = Rc::new(extensions);
|
||||||
config,
|
let pool = HttpRequestPool::create();
|
||||||
service: middleware.new_transform(Next::new(service)),
|
|
||||||
state: Rc::new(extensions),
|
|
||||||
pool: HttpRequestPool::create(),
|
|
||||||
_t: PhantomData,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Service to convert `Request` to a `WebRequest<Err>`
|
let hnd: WebAppHandler2<'a> = Box::new(move |req: Request| {
|
||||||
pub struct AppFactoryService<'a, T, Err>
|
|
||||||
where
|
|
||||||
T: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
service: T,
|
|
||||||
rmap: Rc<ResourceMap>,
|
|
||||||
config: AppConfig,
|
|
||||||
state: Rc<Extensions>,
|
|
||||||
pool: &'static HttpRequestPool,
|
|
||||||
_t: PhantomData<&'a Err>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, Err> Service<Request> for AppFactoryService<'a, T, Err>
|
|
||||||
where
|
|
||||||
T: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
type Response = WebResponse;
|
|
||||||
type Error = Err::Container;
|
|
||||||
type Future = AppFactoryServiceResponse<'a, T, Err>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
let _ = ready!(self.service.poll_ready(cx));
|
|
||||||
Poll::Ready(Ok(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll_shutdown(&self, cx: &mut Context<'_>, is_error: bool) -> Poll<()> {
|
|
||||||
self.service.poll_shutdown(cx, is_error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&self, req: Request) -> Self::Future {
|
|
||||||
let (head, payload) = req.into_parts();
|
let (head, payload) = req.into_parts();
|
||||||
|
|
||||||
let req = if let Some(mut req) = self.pool.get_request() {
|
let mut req = if let Some(mut req) = pool.get_request() {
|
||||||
let inner = Rc::get_mut(&mut req.0).unwrap();
|
let inner = Rc::get_mut(&mut req.0).unwrap();
|
||||||
inner.path.set(head.uri.clone());
|
inner.path.set(head.uri.clone());
|
||||||
inner.head = head;
|
inner.head = head;
|
||||||
inner.payload = payload;
|
inner.payload = payload;
|
||||||
inner.app_state = self.state.clone();
|
inner.app_state = state.clone();
|
||||||
req
|
req
|
||||||
} else {
|
} else {
|
||||||
HttpRequest::new(
|
HttpRequest::new(
|
||||||
Path::new(head.uri.clone()),
|
Path::new(head.uri.clone()),
|
||||||
head,
|
head,
|
||||||
payload,
|
payload,
|
||||||
self.rmap.clone(),
|
rmap.clone(),
|
||||||
self.config.clone(),
|
config.clone(),
|
||||||
self.state.clone(),
|
state.clone(),
|
||||||
self.pool,
|
pool,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let mut req = WebRequest::new(req);
|
let mut wreq =
|
||||||
let fut = self.service.call(&mut req);
|
WebRequest::<Err>::new(unsafe { std::mem::transmute(&mut req) });
|
||||||
|
let fut = service.call(unsafe { std::mem::transmute(&mut wreq) });
|
||||||
|
Box::pin(async move {
|
||||||
|
let mut res = fut.await.unwrap();
|
||||||
|
|
||||||
AppFactoryServiceResponse { fut, req }
|
let head = req.head();
|
||||||
|
if head.upgrade() {
|
||||||
|
res.response.head_mut().set_io(head);
|
||||||
|
}
|
||||||
|
drop(wreq);
|
||||||
|
drop(req);
|
||||||
|
Ok(res)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
Ok(unsafe { std::mem::transmute(hnd) })
|
||||||
|
});
|
||||||
|
unsafe { std::mem::transmute(f) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Err> Drop for AppFactoryService<'a, T, Err>
|
pub struct AppRouting<'a, F, Err: ErrorRenderer> {
|
||||||
where
|
filter: F,
|
||||||
T: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
router: Rc<AppRouter<'a, Err>>,
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.pool.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
struct AppRouter<'a, Err: ErrorRenderer> {
|
||||||
pub struct AppFactoryServiceResponse<'a, T: Service<&'a mut WebRequest<Err>>, Err>{
|
|
||||||
#[pin]
|
|
||||||
fut: T::Future,
|
|
||||||
req: WebRequest<Err>,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, Err> Future for AppFactoryServiceResponse<'a, T, Err>
|
|
||||||
where
|
|
||||||
T: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
type Output = Result<WebResponse, Err::Container>;
|
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
Poll::Ready(Ok(ready!(self.project().fut.poll(cx)).unwrap()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AppRouting<'a, Err: ErrorRenderer> {
|
|
||||||
router: Router<BoxService<'a, Err>, Guards>,
|
router: Router<BoxService<'a, Err>, Guards>,
|
||||||
default: Option<BoxService<'a, Err>>,
|
default: Option<BoxService<'a, Err>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for AppRouting<'a, Err> {
|
impl<'a, F, Err: ErrorRenderer> Service<&'a mut WebRequest<'a, Err>>
|
||||||
|
for AppRouting<'a, F, Err>
|
||||||
|
where
|
||||||
|
F: Service<
|
||||||
|
&'a mut WebRequest<'a, Err>,
|
||||||
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
|
Error = Err::Container,
|
||||||
|
>,
|
||||||
|
F::Future: 'a,
|
||||||
|
Err: ErrorRenderer,
|
||||||
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Infallible;
|
||||||
type Future = BoxResponse<'a, Err>;
|
type Future = BoxResponse<'a>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
let _ = ready!(self.filter.poll_ready(cx));
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, mut req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, mut req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
let res = self.router.recognize_checked(req, |req, guards| {
|
let r1 = unsafe { (req as *mut WebRequest<'a, Err>).as_mut().unwrap() };
|
||||||
|
let r2 = unsafe { (req as *mut WebRequest<'a, Err>).as_mut().unwrap() };
|
||||||
|
|
||||||
|
let fut = self.filter.call(r1);
|
||||||
|
let router = self.router.clone();
|
||||||
|
|
||||||
|
Box::pin(async move {
|
||||||
|
match fut.await {
|
||||||
|
Ok(res) => (),
|
||||||
|
Err(err) => return Ok(WebResponse::new(err.error_response(&req.req))),
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = router.router.recognize_checked(req, |req, guards| {
|
||||||
if let Some(guards) = guards {
|
if let Some(guards) = guards {
|
||||||
for f in guards {
|
for f in guards {
|
||||||
if !f.check(req.head()) {
|
if !f.check(req.head()) {
|
||||||
|
@ -314,89 +375,19 @@ impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for AppRouting<'a,
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((srv, _info)) = res {
|
if let Some((srv, _info)) = res {
|
||||||
srv.call(req)
|
match srv.call(r2).await {
|
||||||
} else if let Some(ref default) = self.default {
|
Ok(res) => Ok(res),
|
||||||
default.call(req)
|
Err(err) => Ok(WebResponse::new(err.error_response(&req.req))),
|
||||||
|
}
|
||||||
|
} else if let Some(ref default) = router.default {
|
||||||
|
match default.call(r2).await {
|
||||||
|
Ok(res) => Ok(res),
|
||||||
|
Err(err) => Ok(WebResponse::new(err.error_response(&req.req))),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let req = req.into_parts().0;
|
Ok(WebResponse::new(Response::NotFound().finish()))
|
||||||
Box::pin(async { Ok(WebResponse::new(Response::NotFound().finish())) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Web app service
|
|
||||||
pub struct AppService<'a, F, Err: ErrorRenderer> {
|
|
||||||
filter: F,
|
|
||||||
routing: Rc<AppRouting<'a, Err>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, F, Err> Service<&'a mut WebRequest<Err>> for AppService<'a, F, Err>
|
|
||||||
where
|
|
||||||
F: Service<
|
|
||||||
&'a mut WebRequest<Err>,
|
|
||||||
Response = &'a mut WebRequest<Err>,
|
|
||||||
Error = Err::Container,
|
|
||||||
>,
|
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
type Response = WebResponse;
|
|
||||||
type Error = Err::Container;
|
|
||||||
type Future = AppServiceResponse<'a, F, Err>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
let ready1 = self.filter.poll_ready(cx)?.is_ready();
|
|
||||||
let ready2 = self.routing.poll_ready(cx)?.is_ready();
|
|
||||||
if ready1 && ready2 {
|
|
||||||
Poll::Ready(Ok(()))
|
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&self, req: &'a mut WebRequest<Err>) -> Self::Future {
|
|
||||||
AppServiceResponse {
|
|
||||||
filter: self.filter.call(req),
|
|
||||||
routing: self.routing.clone(),
|
|
||||||
endpoint: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
|
||||||
pub struct AppServiceResponse<'a, F: Service<&'a mut WebRequest<Err>>, Err: ErrorRenderer> {
|
|
||||||
#[pin]
|
|
||||||
filter: F::Future,
|
|
||||||
routing: Rc<AppRouting<'a, Err>>,
|
|
||||||
endpoint: Option<BoxResponse<'a, Err>>,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, F, Err> Future for AppServiceResponse<'a, F, Err>
|
|
||||||
where
|
|
||||||
F: Service<
|
|
||||||
&'a mut WebRequest<Err>,
|
|
||||||
Response = &'a mut WebRequest<Err>,
|
|
||||||
Error = Err::Container,
|
|
||||||
>,
|
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
type Output = Result<WebResponse, Err::Container>;
|
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
let this = self.as_mut().project();
|
|
||||||
|
|
||||||
if let Some(fut) = this.endpoint.as_mut() {
|
|
||||||
Pin::new(fut).poll(cx)
|
|
||||||
} else {
|
|
||||||
let res = if let Poll::Ready(res) = this.filter.poll(cx) {
|
|
||||||
res?
|
|
||||||
} else {
|
|
||||||
return Poll::Pending;
|
|
||||||
};
|
|
||||||
*this.endpoint = Some(this.routing.call(res));
|
|
||||||
self.poll(cx)
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub type BoxFactoryFuture<'a, Err: ErrorRenderer> =
|
||||||
|
|
||||||
pub type BoxService<'a, Err: ErrorRenderer> = Box<
|
pub type BoxService<'a, Err: ErrorRenderer> = Box<
|
||||||
dyn Service<
|
dyn Service<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
Response = WebResponse,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
Future = BoxFuture<'a, Err>,
|
Future = BoxFuture<'a, Err>,
|
||||||
|
@ -27,21 +27,21 @@ pub fn factory<'a, T, Err>(factory: T) -> BoxServiceFactory<'a, Err>
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
T: ServiceFactory<
|
T: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
Response = WebResponse,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
T::Service: 'static,
|
T::Service: 'static,
|
||||||
<T::Service as Service<&'a mut WebRequest<Err>>>::Future: 'a,
|
<T::Service as Service<&'a mut WebRequest<'a, Err>>>::Future: 'a,
|
||||||
{
|
{
|
||||||
BoxServiceFactory(FactoryWrapper::boxed(factory))
|
BoxServiceFactory(FactoryWrapper::boxed(factory))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Inner<'a, Err: ErrorRenderer + 'static> = Box<
|
type Inner<'a, Err: ErrorRenderer + 'static> = Box<
|
||||||
dyn ServiceFactory<
|
dyn ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
Response = WebResponse,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
|
@ -50,7 +50,7 @@ type Inner<'a, Err: ErrorRenderer + 'static> = Box<
|
||||||
> + 'static,
|
> + 'static,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<Err>>
|
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<'a, Err>>
|
||||||
for BoxServiceFactory<'a, Err>
|
for BoxServiceFactory<'a, Err>
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
|
@ -73,14 +73,14 @@ impl<'a, T, Err> FactoryWrapper<T, Err>
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer + 'static,
|
Err: ErrorRenderer + 'static,
|
||||||
T: ServiceFactory<
|
T: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
Response = WebResponse,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
T::Service: 'static,
|
T::Service: 'static,
|
||||||
<T::Service as Service<&'a mut WebRequest<Err>>>::Future: 'a,
|
<T::Service as Service<&'a mut WebRequest<'a, Err>>>::Future: 'a,
|
||||||
{
|
{
|
||||||
fn boxed(factory: T) -> Inner<'a, Err> {
|
fn boxed(factory: T) -> Inner<'a, Err> {
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
|
@ -90,18 +90,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Err> ServiceFactory<&'a mut WebRequest<Err>> for FactoryWrapper<T, Err>
|
impl<'a, T, Err> ServiceFactory<&'a mut WebRequest<'a, Err>> for FactoryWrapper<T, Err>
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer + 'static,
|
Err: ErrorRenderer + 'static,
|
||||||
T: ServiceFactory<
|
T: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
Response = WebResponse,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
T::Service: 'static,
|
T::Service: 'static,
|
||||||
<T::Service as Service<&'a mut WebRequest<Err>>>::Future: 'a,
|
<T::Service as Service<&'a mut WebRequest<'a, Err>>>::Future: 'a,
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
|
@ -123,7 +123,7 @@ struct ServiceWrapper<T, Err>(T, PhantomData<Err>);
|
||||||
impl<'a, T, Err> ServiceWrapper<T, Err>
|
impl<'a, T, Err> ServiceWrapper<T, Err>
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
T: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Err::Container>
|
T: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Err::Container>
|
||||||
+ 'static,
|
+ 'static,
|
||||||
T::Future: 'a,
|
T::Future: 'a,
|
||||||
{
|
{
|
||||||
|
@ -132,10 +132,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Err> Service<&'a mut WebRequest<Err>> for ServiceWrapper<T, Err>
|
impl<'a, T, Err> Service<&'a mut WebRequest<'a, Err>> for ServiceWrapper<T, Err>
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
T: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Err::Container>
|
T: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Err::Container>
|
||||||
+ 'static,
|
+ 'static,
|
||||||
T::Future: 'a,
|
T::Future: 'a,
|
||||||
{
|
{
|
||||||
|
@ -154,7 +154,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&self, req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
Box::pin(self.0.call(req))
|
Box::pin(self.0.call(req))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::router::ResourceDef;
|
||||||
|
|
||||||
use super::resource::Resource;
|
use super::resource::Resource;
|
||||||
use super::route::Route;
|
use super::route::Route;
|
||||||
use super::service::{AppServiceFactory, ServiceFactoryWrapper, WebServiceFactory};
|
use super::service::{create_web_service, WebService, WebServiceWrapper};
|
||||||
use super::types::state::{State, StateFactory};
|
use super::types::state::{State, StateFactory};
|
||||||
use super::{DefaultError, ErrorRenderer};
|
use super::{DefaultError, ErrorRenderer};
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ impl Default for AppConfig {
|
||||||
/// to set of external methods. This could help with
|
/// to set of external methods. This could help with
|
||||||
/// modularization of big application configuration.
|
/// modularization of big application configuration.
|
||||||
pub struct ServiceConfig<'a, Err = DefaultError> {
|
pub struct ServiceConfig<'a, Err = DefaultError> {
|
||||||
pub(super) services: Vec<Box<dyn AppServiceFactory<'a, Err>>>,
|
pub(super) services: Vec<Box<dyn WebServiceWrapper<'a, Err>>>,
|
||||||
pub(super) state: Vec<Box<dyn StateFactory>>,
|
pub(super) state: Vec<Box<dyn StateFactory>>,
|
||||||
pub(super) external: Vec<ResourceDef>,
|
pub(super) external: Vec<ResourceDef>,
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,9 @@ impl<'a, Err: ErrorRenderer> ServiceConfig<'a, Err> {
|
||||||
/// This is same as `App::service()` method.
|
/// This is same as `App::service()` method.
|
||||||
pub fn service<F>(&mut self, factory: F) -> &mut Self
|
pub fn service<F>(&mut self, factory: F) -> &mut Self
|
||||||
where
|
where
|
||||||
F: WebServiceFactory<'a, Err> + 'static,
|
F: WebService<'a, Err> + 'static,
|
||||||
{
|
{
|
||||||
self.services
|
self.services.push(create_web_service(factory));
|
||||||
.push(Box::new(ServiceFactoryWrapper::new(factory)));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +135,7 @@ mod tests {
|
||||||
|
|
||||||
#[crate::rt_test]
|
#[crate::rt_test]
|
||||||
async fn test_configure_state() {
|
async fn test_configure_state() {
|
||||||
let cfg = |cfg: &mut ServiceConfig<_>| {
|
let cfg = |cfg: &mut ServiceConfig<'_, _>| {
|
||||||
cfg.state(10usize);
|
cfg.state(10usize);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,20 +8,20 @@ use crate::{http::Payload, util::Ready};
|
||||||
/// Trait implemented by types that can be extracted from request.
|
/// Trait implemented by types that can be extracted from request.
|
||||||
///
|
///
|
||||||
/// Types that implement this trait can be used with `Route` handlers.
|
/// Types that implement this trait can be used with `Route` handlers.
|
||||||
pub trait FromRequest<Err>: Sized {
|
pub trait FromRequest<'a, Err>: Sized {
|
||||||
/// The associated error which can be returned.
|
/// The associated error which can be returned.
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
/// Future that resolves to a Self
|
/// Future that resolves to a Self
|
||||||
type Future: Future<Output = Result<Self, Self::Error>>;
|
type Future: Future<Output = Result<Self, Self::Error>> + 'a;
|
||||||
|
|
||||||
/// Convert request to a Self
|
/// Convert request to a Self
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future;
|
fn from_request(req: &'a HttpRequest, payload: &'a mut Payload) -> Self::Future;
|
||||||
|
|
||||||
/// Convert request to a Self
|
/// Convert request to a Self
|
||||||
///
|
///
|
||||||
/// This method uses `Payload::None` as payload stream.
|
/// This method uses `Payload::None` as payload stream.
|
||||||
fn extract(req: &HttpRequest) -> Self::Future {
|
fn extract(req: &'a HttpRequest) -> Self::Future {
|
||||||
Self::from_request(req, &mut Payload::None)
|
Self::from_request(req, &mut Payload::None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,18 +71,18 @@ pub trait FromRequest<Err>: Sized {
|
||||||
/// );
|
/// );
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
impl<T, Err> FromRequest<Err> for Option<T>
|
impl<'a, T, Err> FromRequest<'a, Err> for Option<T>
|
||||||
where
|
where
|
||||||
T: FromRequest<Err> + 'static,
|
T: FromRequest<'a, Err> + 'static,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
<T as FromRequest<Err>>::Error: Into<Err::Container>,
|
<T as FromRequest<'a, Err>>::Error: Into<Err::Container>,
|
||||||
{
|
{
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type Future = Pin<Box<dyn Future<Output = Result<Option<T>, Self::Error>>>>;
|
type Future = Pin<Box<dyn Future<Output = Result<Option<T>, Self::Error>> + 'a>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &'a HttpRequest, payload: &'a mut Payload) -> Self::Future {
|
||||||
let fut = T::from_request(req, payload);
|
let fut = T::from_request(req, payload);
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
match fut.await {
|
match fut.await {
|
||||||
|
@ -139,18 +139,17 @@ where
|
||||||
/// );
|
/// );
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
impl<T, E> FromRequest<E> for Result<T, T::Error>
|
impl<'a, T, E> FromRequest<'a, E> for Result<T, T::Error>
|
||||||
where
|
where
|
||||||
T: FromRequest<E> + 'static,
|
T: FromRequest<'a, E> + 'static,
|
||||||
T::Error: 'static,
|
|
||||||
T::Future: 'static,
|
|
||||||
E: ErrorRenderer,
|
E: ErrorRenderer,
|
||||||
{
|
{
|
||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
type Future = Pin<Box<dyn Future<Output = Result<Result<T, T::Error>, Self::Error>>>>;
|
type Future =
|
||||||
|
Pin<Box<dyn Future<Output = Result<Result<T, T::Error>, Self::Error>> + 'a>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &'a HttpRequest, payload: &'a mut Payload) -> Self::Future {
|
||||||
let fut = T::from_request(req, payload);
|
let fut = T::from_request(req, payload);
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
match fut.await {
|
match fut.await {
|
||||||
|
@ -162,7 +161,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl<E: ErrorRenderer> FromRequest<E> for () {
|
impl<'a, E: ErrorRenderer> FromRequest<'a, E> for () {
|
||||||
type Error = E::Container;
|
type Error = E::Container;
|
||||||
type Future = Ready<(), E::Container>;
|
type Future = Ready<(), E::Container>;
|
||||||
|
|
||||||
|
@ -175,14 +174,14 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
|
|
||||||
/// FromRequest implementation for a tuple
|
/// FromRequest implementation for a tuple
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
impl<Err: ErrorRenderer, $($T: FromRequest<Err> + 'static),+> FromRequest<Err> for ($($T,)+)
|
impl<'a, Err: ErrorRenderer, $($T: FromRequest<'a, Err> + 'static),+> FromRequest<'a, Err> for ($($T,)+)
|
||||||
where
|
where
|
||||||
$(<$T as $crate::web::FromRequest<Err>>::Error: Into<Err::Container>),+
|
$(<$T as $crate::web::FromRequest<'a, Err>>::Error: Into<Err::Container>),+
|
||||||
{
|
{
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type Future = $fut_type<Err, $($T),+>;
|
type Future = $fut_type<'a, Err, $($T),+>;
|
||||||
|
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &'a HttpRequest, payload: &'a mut Payload) -> Self::Future {
|
||||||
$fut_type {
|
$fut_type {
|
||||||
items: <($(Option<$T>,)+)>::default(),
|
items: <($(Option<$T>,)+)>::default(),
|
||||||
$($T: $T::from_request(req, payload),)+
|
$($T: $T::from_request(req, payload),)+
|
||||||
|
@ -192,16 +191,16 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct $fut_type<Err: ErrorRenderer, $($T: FromRequest<Err>),+>
|
pub struct $fut_type<'a, Err: ErrorRenderer, $($T: FromRequest<'a, Err>),+>
|
||||||
{
|
{
|
||||||
items: ($(Option<$T>,)+),
|
items: ($(Option<$T>,)+),
|
||||||
$(#[pin] $T: $T::Future),+
|
$(#[pin] $T: $T::Future),+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err: ErrorRenderer, $($T: FromRequest<Err>),+> Future for $fut_type<Err, $($T),+>
|
impl<'a, Err: ErrorRenderer, $($T: FromRequest<'a, Err>),+> Future for $fut_type<'a, Err, $($T),+>
|
||||||
where
|
where
|
||||||
$(<$T as $crate::web::FromRequest<Err>>::Error: Into<Err::Container>),+
|
$(<$T as $crate::web::FromRequest<'a, Err>>::Error: Into<Err::Container>),+
|
||||||
{
|
{
|
||||||
type Output = Result<($($T,)+), Err::Container>;
|
type Output = Result<($($T,)+), Err::Container>;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ where
|
||||||
pub(super) trait HandlerFn<Err: ErrorRenderer> {
|
pub(super) trait HandlerFn<Err: ErrorRenderer> {
|
||||||
fn call<'b>(
|
fn call<'b>(
|
||||||
&self,
|
&self,
|
||||||
_: &'b mut WebRequest<Err>,
|
_: &'b mut WebRequest<'b, Err>,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>> + 'b>>;
|
) -> Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>> + 'b>>;
|
||||||
|
|
||||||
fn clone_handler(&self) -> Box<dyn HandlerFn<Err>>;
|
fn clone_handler(&self) -> Box<dyn HandlerFn<Err>>;
|
||||||
|
@ -58,16 +58,16 @@ impl<F, T, Err> HandlerWrapper<F, T, Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, T, Err> HandlerFn<Err> for HandlerWrapper<F, T, Err>
|
impl<'a, F, T, Err> HandlerFn<Err> for HandlerWrapper<F, T, Err>
|
||||||
where
|
where
|
||||||
F: Handler<T, Err>,
|
F: Handler<T, Err>,
|
||||||
T: FromRequest<Err> + 'static,
|
T: FromRequest<'a, Err> + 'static,
|
||||||
T::Error: Into<Err::Container>,
|
T::Error: Into<Err::Container>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
fn call<'b>(
|
fn call<'b>(
|
||||||
&self,
|
&self,
|
||||||
req: &'b mut WebRequest<Err>,
|
req: &'b mut WebRequest<'b, Err>,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>> + 'b>> {
|
) -> Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>> + 'b>> {
|
||||||
let mut pl = Rc::get_mut(&mut (req.req).0).unwrap().payload.take();
|
let mut pl = Rc::get_mut(&mut (req.req).0).unwrap().payload.take();
|
||||||
let hnd = self.hnd.clone();
|
let hnd = self.hnd.clone();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{cell::Ref, cell::RefCell, cell::RefMut, fmt, net, rc::Rc, rc::Weak};
|
use std::{cell::Ref, cell::RefCell, cell::RefMut, fmt, net, rc::Rc};
|
||||||
|
|
||||||
use crate::http::{
|
use crate::http::{
|
||||||
HeaderMap, HttpMessage, Message, Method, Payload, RequestHead, Uri, Version,
|
HeaderMap, HttpMessage, Message, Method, Payload, RequestHead, Uri, Version,
|
||||||
|
@ -17,8 +17,6 @@ use super::rmap::ResourceMap;
|
||||||
/// An HTTP Request
|
/// An HTTP Request
|
||||||
pub struct HttpRequest(pub(crate) Rc<HttpRequestInner>);
|
pub struct HttpRequest(pub(crate) Rc<HttpRequestInner>);
|
||||||
|
|
||||||
pub(super) struct WeakHttpRequest(pub(super) Weak<HttpRequestInner>);
|
|
||||||
|
|
||||||
pub(crate) struct HttpRequestInner {
|
pub(crate) struct HttpRequestInner {
|
||||||
pub(crate) head: Message<RequestHead>,
|
pub(crate) head: Message<RequestHead>,
|
||||||
pub(crate) path: Path<Uri>,
|
pub(crate) path: Path<Uri>,
|
||||||
|
@ -50,10 +48,6 @@ impl HttpRequest {
|
||||||
pool,
|
pool,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn downgrade(&self) -> WeakHttpRequest {
|
|
||||||
WeakHttpRequest(Rc::downgrade(&self.0))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HttpRequest {
|
impl HttpRequest {
|
||||||
|
|
|
@ -59,14 +59,14 @@ pub struct CompressMiddleware<S> {
|
||||||
encoding: ContentEncoding,
|
encoding: ContentEncoding,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E> Service<WebRequest<E>> for CompressMiddleware<S>
|
impl<'a, S, E> Service<WebRequest<E>> for CompressMiddleware<S>
|
||||||
where
|
where
|
||||||
S: Service<WebRequest<E>, Response = WebResponse>,
|
S: Service<WebRequest<E>, Response = WebResponse>,
|
||||||
E: ErrorRenderer,
|
E: ErrorRenderer,
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Future = CompressResponse<S, E>;
|
type Future = CompressResponse<'a, S, E>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
@ -100,7 +100,7 @@ where
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct CompressResponse<S: Service<WebRequest<E>>, E>
|
pub struct CompressResponse<'a, S: Service<WebRequest<E>>, E>
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: S::Future,
|
fut: S::Future,
|
||||||
|
@ -109,7 +109,7 @@ pin_project_lite::pin_project! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E> Future for CompressResponse<S, E>
|
impl<'a, S, E> Future for CompressResponse<'a, S, E>
|
||||||
where
|
where
|
||||||
S: Service<WebRequest<E>, Response = WebResponse>,
|
S: Service<WebRequest<E>, Response = WebResponse>,
|
||||||
E: ErrorRenderer,
|
E: ErrorRenderer,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{convert::Infallible, convert::TryFrom, future::Future, pin::Pin, rc::R
|
||||||
use crate::http::error::HttpError;
|
use crate::http::error::HttpError;
|
||||||
use crate::http::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
|
use crate::http::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
|
||||||
use crate::service::{Service, Transform};
|
use crate::service::{Service, Transform};
|
||||||
use crate::web::{WebRequest, WebResponse};
|
use crate::web::{WebRequest, WebResponse, ErrorRenderer};
|
||||||
|
|
||||||
/// `Middleware` for setting default response headers.
|
/// `Middleware` for setting default response headers.
|
||||||
///
|
///
|
||||||
|
@ -102,14 +102,15 @@ pub struct DefaultHeadersMiddleware<S> {
|
||||||
inner: Rc<Inner>,
|
inner: Rc<Inner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E> Service<WebRequest<E>> for DefaultHeadersMiddleware<S>
|
impl<'a, S, E> Service<WebRequest<E>> for DefaultHeadersMiddleware<S>
|
||||||
where
|
where
|
||||||
S: Service<WebRequest<E>, Response = WebResponse, Error = Infallible>,
|
S: Service<WebRequest<E>, Response = WebResponse, Error = Infallible>,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
|
E: ErrorRenderer,
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + 'a>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
|
|
@ -130,13 +130,14 @@ pub struct LoggerMiddleware<S> {
|
||||||
service: S,
|
service: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E> Service<WebRequest<E>> for LoggerMiddleware<S>
|
impl<'a, S, E> Service<WebRequest<E>> for LoggerMiddleware<S>
|
||||||
where
|
where
|
||||||
S: Service<WebRequest<E>, Response = WebResponse>,
|
S: Service<WebRequest<E>, Response = WebResponse>,
|
||||||
|
E: 'static,
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Future = Either<LoggerResponse<S, E>, S::Future>;
|
type Future = Either<LoggerResponse<'a, S, E>, S::Future>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
@ -171,7 +172,7 @@ where
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct LoggerResponse<S: Service<WebRequest<E>>, E>
|
pub struct LoggerResponse<'a, S: Service<WebRequest<E>>, E>
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: S::Future,
|
fut: S::Future,
|
||||||
|
@ -181,7 +182,7 @@ pin_project_lite::pin_project! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E> Future for LoggerResponse<S, E>
|
impl<'a, S, E> Future for LoggerResponse<'a, S, E>
|
||||||
where
|
where
|
||||||
S: Service<WebRequest<E>, Response = WebResponse>,
|
S: Service<WebRequest<E>, Response = WebResponse>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub mod guard;
|
||||||
mod handler;
|
mod handler;
|
||||||
mod httprequest;
|
mod httprequest;
|
||||||
mod info;
|
mod info;
|
||||||
pub mod middleware;
|
//pub mod middleware;
|
||||||
mod request;
|
mod request;
|
||||||
mod resource;
|
mod resource;
|
||||||
mod responder;
|
mod responder;
|
||||||
|
@ -91,7 +91,7 @@ mod boxed;
|
||||||
mod server;
|
mod server;
|
||||||
mod service;
|
mod service;
|
||||||
mod stack;
|
mod stack;
|
||||||
pub mod test;
|
//pub mod test;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
mod util;
|
mod util;
|
||||||
pub mod ws;
|
pub mod ws;
|
||||||
|
@ -125,7 +125,7 @@ pub use self::response::WebResponse;
|
||||||
pub use self::route::Route;
|
pub use self::route::Route;
|
||||||
// pub use self::scope::Scope;
|
// pub use self::scope::Scope;
|
||||||
pub use self::server::HttpServer;
|
pub use self::server::HttpServer;
|
||||||
pub use self::service::WebServiceFactory;
|
pub use self::service::{WebService, WebServiceConfig};
|
||||||
pub use self::util::*;
|
pub use self::util::*;
|
||||||
|
|
||||||
pub mod dev {
|
pub mod dev {
|
||||||
|
@ -139,7 +139,7 @@ pub mod dev {
|
||||||
pub use crate::web::info::ConnectionInfo;
|
pub use crate::web::info::ConnectionInfo;
|
||||||
pub use crate::web::rmap::ResourceMap;
|
pub use crate::web::rmap::ResourceMap;
|
||||||
pub use crate::web::route::IntoRoutes;
|
pub use crate::web::route::IntoRoutes;
|
||||||
pub use crate::web::service::{WebServiceAdapter, WebServiceConfig, WebServiceFactory};
|
pub use crate::web::service::{WebService, WebServiceAdapter, WebServiceConfig};
|
||||||
pub use crate::web::stack::Stack;
|
pub use crate::web::stack::Stack;
|
||||||
|
|
||||||
pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
|
pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
|
||||||
|
@ -151,55 +151,55 @@ pub mod dev {
|
||||||
patterns
|
patterns
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[doc(hidden)]
|
#[doc(hidden)]
|
||||||
// #[inline(always)]
|
#[inline(always)]
|
||||||
// pub fn __assert_extractor<'a, Err, T>()
|
pub fn __assert_extractor<'a, Err, T>()
|
||||||
// where
|
where
|
||||||
// T: super::FromRequest<'a, Err>,
|
T: super::FromRequest<'a, Err>,
|
||||||
// Err: super::ErrorRenderer,
|
Err: super::ErrorRenderer,
|
||||||
// <T as super::FromRequest<'a, Err>>::Error: Into<Err::Container>,
|
<T as super::FromRequest<'a, Err>>::Error: Into<Err::Container>,
|
||||||
// {
|
{
|
||||||
// }
|
}
|
||||||
|
|
||||||
// #[doc(hidden)]
|
#[doc(hidden)]
|
||||||
// #[inline(always)]
|
#[inline(always)]
|
||||||
// pub fn __assert_handler<Err, Fun, Fut>(
|
pub fn __assert_handler<Err, Fun, Fut>(
|
||||||
// f: Fun,
|
f: Fun,
|
||||||
// ) -> impl Handler<(), Err, Future = Fut, Output = Fut::Output>
|
) -> impl Handler<(), Err, Future = Fut, Output = Fut::Output>
|
||||||
// where
|
where
|
||||||
// Err: super::ErrorRenderer,
|
Err: super::ErrorRenderer,
|
||||||
// Fun: Fn() -> Fut + Clone + 'static,
|
Fun: Fn() -> Fut + Clone + 'static,
|
||||||
// Fut: std::future::Future + 'static,
|
Fut: std::future::Future + 'static,
|
||||||
// Fut::Output: super::Responder<Err>,
|
Fut::Output: super::Responder<Err>,
|
||||||
// {
|
{
|
||||||
// f
|
f
|
||||||
// }
|
}
|
||||||
|
|
||||||
// macro_rules! assert_handler ({ $name:ident, $($T:ident),+} => {
|
macro_rules! assert_handler ({ $name:ident, $($T:ident),+} => {
|
||||||
// #[doc(hidden)]
|
#[doc(hidden)]
|
||||||
// #[inline(always)]
|
#[inline(always)]
|
||||||
// pub fn $name<'a, Err, Fun, Fut, $($T,)+>(
|
pub fn $name<'a, Err, Fun, Fut, $($T,)+>(
|
||||||
// f: Fun,
|
f: Fun,
|
||||||
// ) -> impl Handler<($($T,)+), Err, Future = Fut, Output = Fut::Output>
|
) -> impl Handler<($($T,)+), Err, Future = Fut, Output = Fut::Output>
|
||||||
// where
|
where
|
||||||
// Err: $crate::web::ErrorRenderer,
|
Err: $crate::web::ErrorRenderer,
|
||||||
// Fun: Fn($($T,)+) -> Fut + Clone + 'static,
|
Fun: Fn($($T,)+) -> Fut + Clone + 'static,
|
||||||
// Fut: std::future::Future + 'static,
|
Fut: std::future::Future + 'static,
|
||||||
// Fut::Output: $crate::web::Responder<Err>,
|
Fut::Output: $crate::web::Responder<Err>,
|
||||||
// $($T: $crate::web::FromRequest<'a, Err>),+,
|
$($T: $crate::web::FromRequest<'a, Err>),+,
|
||||||
// {
|
{
|
||||||
// f
|
f
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
// assert_handler!(__assert_handler1, A);
|
assert_handler!(__assert_handler1, A);
|
||||||
// assert_handler!(__assert_handler2, A, B);
|
assert_handler!(__assert_handler2, A, B);
|
||||||
// assert_handler!(__assert_handler3, A, B, C);
|
assert_handler!(__assert_handler3, A, B, C);
|
||||||
// assert_handler!(__assert_handler4, A, B, C, D);
|
assert_handler!(__assert_handler4, A, B, C, D);
|
||||||
// assert_handler!(__assert_handler5, A, B, C, D, E);
|
assert_handler!(__assert_handler5, A, B, C, D, E);
|
||||||
// assert_handler!(__assert_handler6, A, B, C, D, E, F);
|
assert_handler!(__assert_handler6, A, B, C, D, E, F);
|
||||||
// assert_handler!(__assert_handler7, A, B, C, D, E, F, G);
|
assert_handler!(__assert_handler7, A, B, C, D, E, F, G);
|
||||||
// assert_handler!(__assert_handler8, A, B, C, D, E, F, G, H);
|
assert_handler!(__assert_handler8, A, B, C, D, E, F, G, H);
|
||||||
// assert_handler!(__assert_handler9, A, B, C, D, E, F, G, H, I);
|
assert_handler!(__assert_handler9, A, B, C, D, E, F, G, H, I);
|
||||||
// assert_handler!(__assert_handler10, A, B, C, D, E, F, G, H, I, J);
|
assert_handler!(__assert_handler10, A, B, C, D, E, F, G, H, I, J);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::util::Extensions;
|
||||||
|
|
||||||
use super::config::AppConfig;
|
use super::config::AppConfig;
|
||||||
use super::error::{ErrorRenderer, WebResponseError};
|
use super::error::{ErrorRenderer, WebResponseError};
|
||||||
use super::httprequest::{HttpRequest, WeakHttpRequest};
|
use super::httprequest::HttpRequest;
|
||||||
use super::info::ConnectionInfo;
|
use super::info::ConnectionInfo;
|
||||||
use super::response::WebResponse;
|
use super::response::WebResponse;
|
||||||
use super::rmap::ResourceMap;
|
use super::rmap::ResourceMap;
|
||||||
|
@ -17,12 +17,12 @@ use super::rmap::ResourceMap;
|
||||||
/// An service http request
|
/// An service http request
|
||||||
///
|
///
|
||||||
/// WebRequest allows mutable access to request's internal structures
|
/// WebRequest allows mutable access to request's internal structures
|
||||||
pub struct WebRequest<Err> {
|
pub struct WebRequest<'a, Err> {
|
||||||
pub(super) req: HttpRequest,
|
pub(super) req: &'a mut HttpRequest,
|
||||||
_t: PhantomData<Err>,
|
_marker: PhantomData<fn(&'a ()) -> &'a Err>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err: ErrorRenderer> WebRequest<Err> {
|
impl<'a, Err: ErrorRenderer> WebRequest<'a, Err> {
|
||||||
/// Create web response for error
|
/// Create web response for error
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn render_error<E: WebResponseError<Err>>(self, err: E) -> WebResponse {
|
pub fn render_error<E: WebResponseError<Err>>(self, err: E) -> WebResponse {
|
||||||
|
@ -36,52 +36,48 @@ impl<Err: ErrorRenderer> WebRequest<Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err> WebRequest<Err> {
|
impl<'a, Err> WebRequest<'a, Err> {
|
||||||
/// Construct web request
|
/// Construct web request
|
||||||
pub(crate) fn new(req: HttpRequest) -> Self {
|
pub(crate) fn new(req: &'a mut HttpRequest) -> Self {
|
||||||
WebRequest {
|
WebRequest {
|
||||||
req,
|
req,
|
||||||
_t: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn weak_request(&self) -> WeakHttpRequest {
|
// /// Deconstruct request into parts
|
||||||
self.req.downgrade()
|
// pub fn into_parts(mut self) -> (HttpRequest, Payload) {
|
||||||
}
|
// let pl = Rc::get_mut(&mut (self.req).0).unwrap().payload.take();
|
||||||
|
// (self.req, pl)
|
||||||
|
// }
|
||||||
|
|
||||||
/// Deconstruct request into parts
|
// /// Construct request from parts.
|
||||||
pub fn into_parts(mut self) -> (HttpRequest, Payload) {
|
// ///
|
||||||
let pl = Rc::get_mut(&mut (self.req).0).unwrap().payload.take();
|
// /// `WebRequest` can be re-constructed only if `req` hasnt been cloned.
|
||||||
(self.req, pl)
|
// pub fn from_parts(
|
||||||
}
|
// mut req: HttpRequest,
|
||||||
|
// pl: Payload,
|
||||||
|
// ) -> Result<Self, (HttpRequest, Payload)> {
|
||||||
|
// if Rc::strong_count(&req.0) == 1 {
|
||||||
|
// Rc::get_mut(&mut req.0).unwrap().payload = pl;
|
||||||
|
// Ok(WebRequest::new(req))
|
||||||
|
// } else {
|
||||||
|
// Err((req, pl))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/// Construct request from parts.
|
// /// Construct request from request.
|
||||||
///
|
// ///
|
||||||
/// `WebRequest` can be re-constructed only if `req` hasnt been cloned.
|
// /// `HttpRequest` implements `Clone` trait via `Rc` type. `WebRequest`
|
||||||
pub fn from_parts(
|
// /// can be re-constructed only if rc's strong pointers count eq 1 and
|
||||||
mut req: HttpRequest,
|
// /// weak pointers count is 0.
|
||||||
pl: Payload,
|
// pub fn from_request(req: HttpRequest) -> Result<Self, HttpRequest> {
|
||||||
) -> Result<Self, (HttpRequest, Payload)> {
|
// if Rc::strong_count(&req.0) == 1 {
|
||||||
if Rc::strong_count(&req.0) == 1 {
|
// Ok(WebRequest::new(req))
|
||||||
Rc::get_mut(&mut req.0).unwrap().payload = pl;
|
// } else {
|
||||||
Ok(WebRequest::new(req))
|
// Err(req)
|
||||||
} else {
|
// }
|
||||||
Err((req, pl))
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct request from request.
|
|
||||||
///
|
|
||||||
/// `HttpRequest` implements `Clone` trait via `Rc` type. `WebRequest`
|
|
||||||
/// can be re-constructed only if rc's strong pointers count eq 1 and
|
|
||||||
/// weak pointers count is 0.
|
|
||||||
pub fn from_request(req: HttpRequest) -> Result<Self, HttpRequest> {
|
|
||||||
if Rc::strong_count(&req.0) == 1 {
|
|
||||||
Ok(WebRequest::new(req))
|
|
||||||
} else {
|
|
||||||
Err(req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create web response
|
/// Create web response
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -245,7 +241,7 @@ impl<Err> WebRequest<Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err> Resource<Uri> for WebRequest<Err> {
|
impl<'a, Err> Resource<Uri> for WebRequest<'a, Err> {
|
||||||
fn path(&self) -> &str {
|
fn path(&self) -> &str {
|
||||||
self.match_info().path()
|
self.match_info().path()
|
||||||
}
|
}
|
||||||
|
@ -255,7 +251,7 @@ impl<Err> Resource<Uri> for WebRequest<Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err> HttpMessage for WebRequest<Err> {
|
impl<'a, Err> HttpMessage for WebRequest<'a, Err> {
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Returns Request's headers.
|
/// Returns Request's headers.
|
||||||
fn message_headers(&self) -> &HeaderMap {
|
fn message_headers(&self) -> &HeaderMap {
|
||||||
|
@ -275,7 +271,7 @@ impl<Err> HttpMessage for WebRequest<Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err: ErrorRenderer> fmt::Debug for WebRequest<Err> {
|
impl<'a, Err: ErrorRenderer> fmt::Debug for WebRequest<'a, Err> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
writeln!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::service::{Identity, IntoServiceFactory, Service, ServiceFactory, Tran
|
||||||
use crate::util::{Either, Extensions, Ready};
|
use crate::util::{Either, Extensions, Ready};
|
||||||
|
|
||||||
use super::boxed::{self, BoxService, BoxServiceFactory};
|
use super::boxed::{self, BoxService, BoxServiceFactory};
|
||||||
use super::dev::{insert_slash, WebServiceConfig, WebServiceFactory};
|
use super::dev::{insert_slash, WebService, WebServiceConfig};
|
||||||
use super::extract::FromRequest;
|
use super::extract::FromRequest;
|
||||||
use super::route::{IntoRoutes, Route, RouteService};
|
use super::route::{IntoRoutes, Route, RouteService};
|
||||||
use super::stack::{
|
use super::stack::{
|
||||||
|
@ -39,9 +39,9 @@ use super::{guard::Guard, types::State, ErrorRenderer, Handler, WebRequest, WebR
|
||||||
///
|
///
|
||||||
/// If no matching route could be found, *405* response code get returned.
|
/// If no matching route could be found, *405* response code get returned.
|
||||||
/// Default behavior could be overriden with `default_resource()` method.
|
/// Default behavior could be overriden with `default_resource()` method.
|
||||||
pub struct Resource<Err: ErrorRenderer, M = Identity, F = Filter<Err>> {
|
pub struct Resource<Err: ErrorRenderer, M = Identity, F = Filter> {
|
||||||
middleware: M,
|
|
||||||
filter: F,
|
filter: F,
|
||||||
|
middleware: M,
|
||||||
rdef: Vec<String>,
|
rdef: Vec<String>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
routes: Vec<Route<Err>>,
|
routes: Vec<Route<Err>>,
|
||||||
|
@ -56,8 +56,8 @@ impl<'a, Err: ErrorRenderer> Resource<Err> {
|
||||||
routes: Vec::new(),
|
routes: Vec::new(),
|
||||||
rdef: path.patterns(),
|
rdef: path.patterns(),
|
||||||
name: None,
|
name: None,
|
||||||
|
filter: Filter,
|
||||||
middleware: Identity,
|
middleware: Identity,
|
||||||
filter: Filter::new(),
|
|
||||||
guards: Vec::new(),
|
guards: Vec::new(),
|
||||||
state: None,
|
state: None,
|
||||||
default: Route::new().to(|| async { Response::MethodNotAllowed().finish() }),
|
default: Route::new().to(|| async { Response::MethodNotAllowed().finish() }),
|
||||||
|
@ -228,7 +228,7 @@ where
|
||||||
/// Register request filter.
|
/// Register request filter.
|
||||||
///
|
///
|
||||||
/// This is similar to `App's` filters, but filter get invoked on resource level.
|
/// This is similar to `App's` filters, but filter get invoked on resource level.
|
||||||
pub fn filter<U>(self, filter: U) -> Resource<Err, M, Filters<F, U, Err>> {
|
pub fn filter<U>(self, filter: U) -> Resource<Err, M, Filters<F, U>> {
|
||||||
Resource {
|
Resource {
|
||||||
filter: Filters::new(self.filter, filter),
|
filter: Filters::new(self.filter, filter),
|
||||||
middleware: self.middleware,
|
middleware: self.middleware,
|
||||||
|
@ -248,7 +248,7 @@ where
|
||||||
/// type (i.e modify response's body).
|
/// type (i.e modify response's body).
|
||||||
///
|
///
|
||||||
/// **Note**: middlewares get called in opposite order of middlewares registration.
|
/// **Note**: middlewares get called in opposite order of middlewares registration.
|
||||||
pub fn wrap<U>(self, mw: U) -> Resource<Err, Stack<M, U, Err>, F> {
|
pub fn wrap<U>(self, mw: U) -> Resource<Err, Stack<M, U>, F> {
|
||||||
Resource {
|
Resource {
|
||||||
middleware: Stack::new(self.middleware, mw),
|
middleware: Stack::new(self.middleware, mw),
|
||||||
filter: self.filter,
|
filter: self.filter,
|
||||||
|
@ -275,22 +275,21 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err, M, F> WebServiceFactory<'a, Err> for Resource<Err, M, F>
|
impl<'a, Err, M, F> WebService<'a, Err> for Resource<Err, M, F>
|
||||||
where
|
where
|
||||||
M: Transform<
|
M: Transform<
|
||||||
Next<
|
Next<
|
||||||
ResourceService<
|
ResourceService<
|
||||||
<F::Service as ServiceFactory<&'a mut WebRequest<Err>>>::Service,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
Err,
|
Err,
|
||||||
>,
|
>,
|
||||||
Err,
|
|
||||||
>,
|
>,
|
||||||
> + 'static,
|
> + 'static,
|
||||||
M::Service:
|
M::Service:
|
||||||
Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
F: FiltersFactory<'a, Err>,
|
F: FiltersFactory<'a, Err> + 'static,
|
||||||
<F::Service as ServiceFactory<&'a mut WebRequest<Err>>>::Service: 'static,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
<F::Service as ServiceFactory<&'a mut WebRequest<Err>>>::Future: 'static,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
fn register(mut self, config: &mut WebServiceConfig<'a, Err>) {
|
fn register(mut self, config: &mut WebServiceConfig<'a, Err>) {
|
||||||
|
@ -331,50 +330,41 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl<'a, Err, M, F> Resource<Err, M, F>
|
impl<'a, Err, M, F>
|
||||||
// where
|
IntoServiceFactory<
|
||||||
// F: FiltersFactory<'a, Err>,
|
ResourceServiceFactory<Err, M, F::Service>,
|
||||||
// M: Transform<Next<ResourceService<'a, <F::Service as ServiceFactory<&'a mut WebRequest<Err>>>::Service, Err>, Err>> + 'static,
|
&'a mut WebRequest<'a, Err>,
|
||||||
// M::Service: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
> for Resource<Err, M, F>
|
||||||
// Err: ErrorRenderer,
|
where
|
||||||
// {
|
M: Transform<
|
||||||
// pub fn finish(self) -> impl ServiceFactory<&'a mut WebRequest<Err>, Response = WebResponse, Error = Err::Container, InitError = ()> {
|
Next<
|
||||||
// let router_factory = ResourceRouterFactory {
|
ResourceService<
|
||||||
// routes: self.routes,
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service,
|
||||||
// state: self.state.map(Rc::new),
|
Err,
|
||||||
// default: self.default,
|
>,
|
||||||
// };
|
>,
|
||||||
|
> + 'static,
|
||||||
|
M::Service:
|
||||||
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
|
F: FiltersFactory<'a, Err> + 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
|
<F::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
|
Err: ErrorRenderer,
|
||||||
|
{
|
||||||
|
fn into_factory(self) -> ResourceServiceFactory<Err, M, F::Service> {
|
||||||
|
let router_factory = ResourceRouterFactory {
|
||||||
|
routes: self.routes,
|
||||||
|
state: self.state.map(Rc::new),
|
||||||
|
default: self.default,
|
||||||
|
};
|
||||||
|
|
||||||
// ResourceServiceFactory::<'a, Err, _, _> {
|
ResourceServiceFactory {
|
||||||
// middleware: Rc::new(MiddlewareStack::new(self.middleware)),
|
middleware: Rc::new(MiddlewareStack::new(self.middleware)),
|
||||||
// filter: self.filter.create(),
|
filter: self.filter.create(),
|
||||||
// routing: router_factory,
|
routing: router_factory,
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// impl<'a, Err, M, F>
|
|
||||||
// IntoServiceFactory<ResourceServiceFactory<'a, Err, M, F::Service>, &'a mut WebRequest<Err>> for Resource<Err, M, F>
|
|
||||||
// where
|
|
||||||
// F: FiltersFactory<'a, Err>,
|
|
||||||
// M: Transform<Next<ResourceService<'a, <F::Service as ServiceFactory<&'a mut WebRequest<Err>>>::Service, Err>, Err>> + 'static,
|
|
||||||
// M::Service: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
|
||||||
// Err: ErrorRenderer,
|
|
||||||
// {
|
|
||||||
// fn into_factory(self) -> ResourceServiceFactory<'a, Err, M, F::Service> {
|
|
||||||
// let router_factory = ResourceRouterFactory {
|
|
||||||
// routes: self.routes,
|
|
||||||
// state: self.state.map(Rc::new),
|
|
||||||
// default: self.default,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// ResourceServiceFactory {
|
|
||||||
// middleware: Rc::new(MiddlewareStack::new(self.middleware)),
|
|
||||||
// filter: self.filter.create(),
|
|
||||||
// routing: router_factory,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Resource service
|
/// Resource service
|
||||||
pub struct ResourceServiceFactory<Err: ErrorRenderer, M, F> {
|
pub struct ResourceServiceFactory<Err: ErrorRenderer, M, F> {
|
||||||
|
@ -383,15 +373,15 @@ pub struct ResourceServiceFactory<Err: ErrorRenderer, M, F> {
|
||||||
routing: ResourceRouterFactory<Err>,
|
routing: ResourceRouterFactory<Err>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err, M, F> ServiceFactory<&'a mut WebRequest<Err>>
|
impl<'a, Err, M, F> ServiceFactory<&'a mut WebRequest<'a, Err>>
|
||||||
for ResourceServiceFactory<Err, M, F>
|
for ResourceServiceFactory<Err, M, F>
|
||||||
where
|
where
|
||||||
M: Transform<Next<ResourceService<F::Service, Err>, Err>> + 'static,
|
M: Transform<Next<ResourceService<F::Service, Err>>> + 'static,
|
||||||
M::Service:
|
M::Service:
|
||||||
Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
F: ServiceFactory<
|
F: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = &'a mut WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
|
@ -423,11 +413,11 @@ pub struct ResourceService<F, Err: ErrorRenderer> {
|
||||||
routing: Rc<ResourceRouter<Err>>,
|
routing: Rc<ResourceRouter<Err>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, F, Err> Service<&'a mut WebRequest<Err>> for ResourceService<F, Err>
|
impl<'a, F, Err> Service<&'a mut WebRequest<'a, Err>> for ResourceService<F, Err>
|
||||||
where
|
where
|
||||||
F: Service<
|
F: Service<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = &'a mut WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
>,
|
>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
|
@ -447,7 +437,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
ResourceServiceResponse {
|
ResourceServiceResponse {
|
||||||
filter: self.filter.call(req),
|
filter: self.filter.call(req),
|
||||||
routing: self.routing.clone(),
|
routing: self.routing.clone(),
|
||||||
|
@ -457,19 +447,19 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
pub struct ResourceServiceResponse<'a, F: Service<&'a mut WebRequest<Err>>, Err: ErrorRenderer> {
|
pub struct ResourceServiceResponse<'a, F: Service<&'a mut WebRequest<'a, Err>>, Err: ErrorRenderer> {
|
||||||
#[pin]
|
#[pin]
|
||||||
filter: F::Future,
|
filter: F::Future,
|
||||||
routing: Rc<ResourceRouter<Err>>,
|
routing: Rc<ResourceRouter<Err>>,
|
||||||
endpoint: Option<<ResourceRouter<Err> as Service<&'a mut WebRequest<Err>>>::Future>,
|
endpoint: Option<<ResourceRouter<Err> as Service<&'a mut WebRequest<'a, Err>>>::Future>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, F, Err> Future for ResourceServiceResponse<'a, F, Err>
|
impl<'a, F, Err> Future for ResourceServiceResponse<'a, F, Err>
|
||||||
where
|
where
|
||||||
F: Service<
|
F: Service<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = &'a mut WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
>,
|
>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
|
@ -499,7 +489,7 @@ struct ResourceRouterFactory<Err: ErrorRenderer> {
|
||||||
default: Route<Err>,
|
default: Route<Err>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<Err>>
|
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<'a, Err>>
|
||||||
for ResourceRouterFactory<Err>
|
for ResourceRouterFactory<Err>
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
|
@ -527,7 +517,7 @@ struct ResourceRouter<Err: ErrorRenderer> {
|
||||||
default: RouteService<Err>,
|
default: RouteService<Err>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for ResourceRouter<Err> {
|
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<'a, Err>> for ResourceRouter<Err> {
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type Future = Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>> + 'a>>;
|
type Future = Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>> + 'a>>;
|
||||||
|
@ -537,7 +527,7 @@ impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for ResourceRouter
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, mut req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, mut req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
for route in self.routes.iter() {
|
for route in self.routes.iter() {
|
||||||
if route.check(req) {
|
if route.check(req) {
|
||||||
if let Some(ref state) = self.state {
|
if let Some(ref state) = self.state {
|
||||||
|
|
|
@ -8,8 +8,7 @@ use super::httprequest::HttpRequest;
|
||||||
|
|
||||||
/// An service http response
|
/// An service http response
|
||||||
pub struct WebResponse {
|
pub struct WebResponse {
|
||||||
// request: HttpRequest,
|
pub(super) response: Response<Body>,
|
||||||
response: Response<Body>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebResponse {
|
impl WebResponse {
|
||||||
|
@ -21,10 +20,10 @@ impl WebResponse {
|
||||||
/// Create web response from the error
|
/// Create web response from the error
|
||||||
pub fn from_err<Err: ErrorRenderer, E: Into<Err::Container>>(
|
pub fn from_err<Err: ErrorRenderer, E: Into<Err::Container>>(
|
||||||
err: E,
|
err: E,
|
||||||
request: HttpRequest,
|
request: &HttpRequest,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let err = err.into();
|
let err = err.into();
|
||||||
let res: Response = err.error_response(&request);
|
let res: Response = err.error_response(request);
|
||||||
|
|
||||||
if res.head().status == StatusCode::INTERNAL_SERVER_ERROR {
|
if res.head().status == StatusCode::INTERNAL_SERVER_ERROR {
|
||||||
log::error!("Internal Server Error: {:?}", err);
|
log::error!("Internal Server Error: {:?}", err);
|
||||||
|
@ -37,29 +36,12 @@ impl WebResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create web response for error
|
|
||||||
#[inline]
|
|
||||||
pub fn error_response<Err: ErrorRenderer, E: Into<Err::Container>>(
|
|
||||||
self,
|
|
||||||
err: E,
|
|
||||||
) -> Self {
|
|
||||||
// Self::from_err::<Err, E>(err) //, self.request)
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create web response
|
/// Create web response
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_response(self, response: Response) -> WebResponse {
|
pub fn into_response(self, response: Response) -> WebResponse {
|
||||||
WebResponse::new(response)
|
WebResponse::new(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get reference to original request
|
|
||||||
#[inline]
|
|
||||||
pub fn request(&self) -> &HttpRequest {
|
|
||||||
//&self.request
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get reference to response
|
/// Get reference to response
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn response(&self) -> &Response<Body> {
|
pub fn response(&self) -> &Response<Body> {
|
||||||
|
@ -90,21 +72,6 @@ impl WebResponse {
|
||||||
self.response.headers_mut()
|
self.response.headers_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute closure and in case of error convert it to response.
|
|
||||||
pub fn checked_expr<Err, F, E>(mut self, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: FnOnce(&mut Self) -> Result<(), E>,
|
|
||||||
E: Into<Err::Container>,
|
|
||||||
Err: ErrorRenderer,
|
|
||||||
{
|
|
||||||
if let Err(err) = f(&mut self) {
|
|
||||||
let res: Response = err.into().into();
|
|
||||||
WebResponse::new(res) //, self.request)
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extract response body
|
/// Extract response body
|
||||||
pub fn take_body(&mut self) -> ResponseBody<Body> {
|
pub fn take_body(&mut self) -> ResponseBody<Body> {
|
||||||
self.response.take_body()
|
self.response.take_body()
|
||||||
|
@ -115,21 +82,22 @@ impl WebResponse {
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut ResponseHead, ResponseBody<Body>) -> ResponseBody<Body>,
|
F: FnOnce(&mut ResponseHead, ResponseBody<Body>) -> ResponseBody<Body>,
|
||||||
{
|
{
|
||||||
let response = self.response.map_body(f);
|
|
||||||
|
|
||||||
WebResponse {
|
WebResponse {
|
||||||
response,
|
response: self.response.map_body(f),
|
||||||
// request: self.request,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Response<Body>> for WebResponse {
|
||||||
|
#[inline]
|
||||||
|
fn from(response: Response<Body>) -> WebResponse {
|
||||||
|
WebResponse { response }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<WebResponse> for Response<Body> {
|
impl From<WebResponse> for Response<Body> {
|
||||||
fn from(mut res: WebResponse) -> Response<Body> {
|
#[inline]
|
||||||
let head = res.response.head_mut();
|
fn from(res: WebResponse) -> Response<Body> {
|
||||||
// if res.request.head().upgrade() {
|
|
||||||
// head.set_io(res.request.head());
|
|
||||||
// }
|
|
||||||
res.response
|
res.response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ impl<'a, Err: ErrorRenderer> Route<Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<Err>> for Route<Err> {
|
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<'a, Err>> for Route<Err> {
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
|
@ -65,7 +65,7 @@ pub struct RouteService<Err: ErrorRenderer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err: ErrorRenderer> RouteService<Err> {
|
impl<Err: ErrorRenderer> RouteService<Err> {
|
||||||
pub fn check(&self, req: &mut WebRequest<Err>) -> bool {
|
pub fn check(&self, req: &'_ mut WebRequest<'_, Err>) -> bool {
|
||||||
if !self.methods.is_empty() && !self.methods.contains(&req.head().method) {
|
if !self.methods.is_empty() && !self.methods.contains(&req.head().method) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ impl<Err: ErrorRenderer> RouteService<Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for RouteService<Err> {
|
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<'a, Err>> for RouteService<Err> {
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + 'a>>;
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + 'a>>;
|
||||||
|
@ -90,7 +90,7 @@ impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for RouteService<E
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&self, req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
self.handler.call(req)
|
self.handler.call(req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ impl<Err: ErrorRenderer> Route<Err> {
|
||||||
pub fn to<F, Args>(mut self, handler: F) -> Self
|
pub fn to<F, Args>(mut self, handler: F) -> Self
|
||||||
where
|
where
|
||||||
F: Handler<Args, Err>,
|
F: Handler<Args, Err>,
|
||||||
Args: FromRequest<Err> + 'static,
|
Args: FromRequest<'a, Err> + 'static,
|
||||||
Args::Error: Into<Err::Container>,
|
Args::Error: Into<Err::Container>,
|
||||||
{
|
{
|
||||||
self.handler = Box::new(HandlerWrapper::new(handler));
|
self.handler = Box::new(HandlerWrapper::new(handler));
|
||||||
|
|
|
@ -19,9 +19,9 @@ use super::{ErrorRenderer, Resource, Route, WebRequest, WebResponse};
|
||||||
|
|
||||||
type Guards = Vec<Box<dyn Guard>>;
|
type Guards = Vec<Box<dyn Guard>>;
|
||||||
type HttpService<Err: ErrorRenderer> =
|
type HttpService<Err: ErrorRenderer> =
|
||||||
BoxService<WebRequest<Err>, WebResponse, Err::Container>;
|
BoxService<&'a mut WebRequest<'a, Err>, WebResponse, Err::Container>;
|
||||||
type HttpNewService<Err: ErrorRenderer> =
|
type HttpNewService<Err: ErrorRenderer> =
|
||||||
BoxServiceFactory<(), WebRequest<Err>, WebResponse, Err::Container, ()>;
|
BoxServiceFactory<(), &'a mut WebRequest<'a, Err>, WebResponse, Err::Container, ()>;
|
||||||
type BoxResponse<Err: ErrorRenderer> =
|
type BoxResponse<Err: ErrorRenderer> =
|
||||||
Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>>>>;
|
Pin<Box<dyn Future<Output = Result<WebResponse, Err::Container>>>>;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ type BoxResponse<Err: ErrorRenderer> =
|
||||||
///
|
///
|
||||||
pub struct Scope<Err: ErrorRenderer, M = Identity, T = Filter<Err>> {
|
pub struct Scope<Err: ErrorRenderer, M = Identity, T = Filter<Err>> {
|
||||||
middleware: M,
|
middleware: M,
|
||||||
filter: PipelineFactory<T, WebRequest<Err>>,
|
filter: PipelineFactory<T, &'a mut WebRequest<'a, Err>>,
|
||||||
rdef: Vec<String>,
|
rdef: Vec<String>,
|
||||||
state: Option<Extensions>,
|
state: Option<Extensions>,
|
||||||
services: Vec<Box<dyn AppServiceFactory<Err>>>,
|
services: Vec<Box<dyn AppServiceFactory<Err>>>,
|
||||||
|
@ -86,8 +86,8 @@ impl<Err: ErrorRenderer> Scope<Err> {
|
||||||
impl<Err, M, T> Scope<Err, M, T>
|
impl<Err, M, T> Scope<Err, M, T>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<
|
T: ServiceFactory<
|
||||||
WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
|
@ -286,8 +286,8 @@ where
|
||||||
/// If default resource is not registered, app's default resource is being used.
|
/// If default resource is not registered, app's default resource is being used.
|
||||||
pub fn default_service<F, S>(mut self, f: F) -> Self
|
pub fn default_service<F, S>(mut self, f: F) -> Self
|
||||||
where
|
where
|
||||||
F: IntoServiceFactory<S, WebRequest<Err>>,
|
F: IntoServiceFactory<S, &'a mut WebRequest<'a, Err>>,
|
||||||
S: ServiceFactory<WebRequest<Err>, Response = WebResponse, Error = Err::Container>
|
S: ServiceFactory<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Err::Container>
|
||||||
+ 'static,
|
+ 'static,
|
||||||
S::InitError: fmt::Debug,
|
S::InitError: fmt::Debug,
|
||||||
{
|
{
|
||||||
|
@ -314,20 +314,20 @@ where
|
||||||
Err,
|
Err,
|
||||||
M,
|
M,
|
||||||
impl ServiceFactory<
|
impl ServiceFactory<
|
||||||
WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
U: ServiceFactory<
|
U: ServiceFactory<
|
||||||
WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
F: IntoServiceFactory<U, WebRequest<Err>>,
|
F: IntoServiceFactory<U, &'a mut WebRequest<'a, Err>>,
|
||||||
{
|
{
|
||||||
Scope {
|
Scope {
|
||||||
filter: self.filter.and_then(filter.into_factory()),
|
filter: self.filter.and_then(filter.into_factory()),
|
||||||
|
@ -370,13 +370,13 @@ where
|
||||||
impl<Err, M, T> WebServiceFactory<Err> for Scope<Err, M, T>
|
impl<Err, M, T> WebServiceFactory<Err> for Scope<Err, M, T>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<
|
T: ServiceFactory<
|
||||||
WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
M: Transform<Next<ScopeService<T::Service, Err>, Err>> + 'static,
|
M: Transform<Next<ScopeService<T::Service, Err>, Err>> + 'static,
|
||||||
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
M::Service: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
fn register(mut self, config: &mut WebServiceConfig<Err>) {
|
fn register(mut self, config: &mut WebServiceConfig<Err>) {
|
||||||
|
@ -456,13 +456,13 @@ struct ScopeServiceFactory<M, F, Err: ErrorRenderer> {
|
||||||
routing: ScopeRouterFactory<Err>,
|
routing: ScopeRouterFactory<Err>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, F, Err> ServiceFactory<WebRequest<Err>> for ScopeServiceFactory<M, F, Err>
|
impl<M, F, Err> ServiceFactory<&'a mut WebRequest<'a, Err>> for ScopeServiceFactory<M, F, Err>
|
||||||
where
|
where
|
||||||
M: Transform<Next<ScopeService<F::Service, Err>, Err>> + 'static,
|
M: Transform<Next<ScopeService<F::Service, Err>, Err>> + 'static,
|
||||||
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
M::Service: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
F: ServiceFactory<
|
F: ServiceFactory<
|
||||||
WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
|
@ -492,9 +492,9 @@ pub struct ScopeService<F, Err: ErrorRenderer> {
|
||||||
routing: Rc<ScopeRouter<Err>>,
|
routing: Rc<ScopeRouter<Err>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Err> Service<WebRequest<Err>> for ScopeService<F, Err>
|
impl<F, Err> Service<&'a mut WebRequest<'a, Err>> for ScopeService<F, Err>
|
||||||
where
|
where
|
||||||
F: Service<WebRequest<Err>, Response = WebRequest<Err>, Error = Err::Container>,
|
F: Service<&'a mut WebRequest<'a, Err>, Response = &'a mut WebRequest<'a, Err>, Error = Err::Container>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
|
@ -512,7 +512,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, req: WebRequest<Err>) -> Self::Future {
|
fn call(&self, req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
ScopeServiceResponse {
|
ScopeServiceResponse {
|
||||||
filter: self.filter.call(req),
|
filter: self.filter.call(req),
|
||||||
routing: self.routing.clone(),
|
routing: self.routing.clone(),
|
||||||
|
@ -522,17 +522,17 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
pub struct ScopeServiceResponse<F: Service<WebRequest<Err>>, Err: ErrorRenderer> {
|
pub struct ScopeServiceResponse<F: Service<&'a mut WebRequest<'a, Err>>, Err: ErrorRenderer> {
|
||||||
#[pin]
|
#[pin]
|
||||||
filter: F::Future,
|
filter: F::Future,
|
||||||
routing: Rc<ScopeRouter<Err>>,
|
routing: Rc<ScopeRouter<Err>>,
|
||||||
endpoint: Option<<ScopeRouter<Err> as Service<WebRequest<Err>>>::Future>,
|
endpoint: Option<<ScopeRouter<Err> as Service<&'a mut WebRequest<'a, Err>>>::Future>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Err> Future for ScopeServiceResponse<F, Err>
|
impl<F, Err> Future for ScopeServiceResponse<F, Err>
|
||||||
where
|
where
|
||||||
F: Service<WebRequest<Err>, Response = WebRequest<Err>, Error = Err::Container>,
|
F: Service<&'a mut WebRequest<'a, Err>, Response = &'a mut WebRequest<'a, Err>, Error = Err::Container>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
type Output = Result<WebResponse, Err::Container>;
|
type Output = Result<WebResponse, Err::Container>;
|
||||||
|
@ -561,7 +561,7 @@ struct ScopeRouterFactory<Err: ErrorRenderer> {
|
||||||
case_insensitive: bool,
|
case_insensitive: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err: ErrorRenderer> ServiceFactory<WebRequest<Err>> for ScopeRouterFactory<Err> {
|
impl<Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<'a, Err>> for ScopeRouterFactory<Err> {
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
|
@ -610,7 +610,7 @@ struct ScopeRouter<Err: ErrorRenderer> {
|
||||||
default: Option<HttpService<Err>>,
|
default: Option<HttpService<Err>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Err: ErrorRenderer> Service<WebRequest<Err>> for ScopeRouter<Err> {
|
impl<Err: ErrorRenderer> Service<&'a mut WebRequest<'a, Err>> for ScopeRouter<Err> {
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type Future = Either<BoxResponse<Err>, Ready<Self::Response, Self::Error>>;
|
type Future = Either<BoxResponse<Err>, Ready<Self::Response, Self::Error>>;
|
||||||
|
@ -620,7 +620,7 @@ impl<Err: ErrorRenderer> Service<WebRequest<Err>> for ScopeRouter<Err> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, mut req: WebRequest<Err>) -> Self::Future {
|
fn call(&self, mut req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
let res = self.router.recognize_checked(&mut req, |req, guards| {
|
let res = self.router.recognize_checked(&mut req, |req, guards| {
|
||||||
if let Some(guards) = guards {
|
if let Some(guards) = guards {
|
||||||
for f in guards {
|
for f in guards {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use std::{marker::PhantomData, rc::Rc};
|
use std::task::{Context, Poll};
|
||||||
|
use std::{convert::Infallible, future::Future, marker::PhantomData, pin::Pin, rc::Rc};
|
||||||
|
|
||||||
use crate::router::{IntoPattern, ResourceDef};
|
use crate::router::{IntoPattern, ResourceDef};
|
||||||
use crate::service::{IntoServiceFactory, ServiceFactory};
|
use crate::service::{IntoServiceFactory, Service, ServiceFactory};
|
||||||
use crate::util::Extensions;
|
use crate::util::Extensions;
|
||||||
|
|
||||||
use super::boxed::{self, BoxServiceFactory};
|
use super::boxed::{self, BoxServiceFactory};
|
||||||
|
@ -11,33 +12,31 @@ use super::rmap::ResourceMap;
|
||||||
use super::types::state::StateFactory;
|
use super::types::state::StateFactory;
|
||||||
use super::{guard::Guard, ErrorRenderer, WebRequest, WebResponse};
|
use super::{guard::Guard, ErrorRenderer, WebRequest, WebResponse};
|
||||||
|
|
||||||
pub trait WebServiceFactory<'a, Err: ErrorRenderer> {
|
pub trait WebService<'a, Err: ErrorRenderer>: 'static {
|
||||||
fn register(self, config: &mut WebServiceConfig<'a, Err>);
|
fn register(self, config: &mut WebServiceConfig<'a, Err>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) trait AppServiceFactory<'a, Err: ErrorRenderer> {
|
pub(super) trait WebServiceWrapper<'a, Err: ErrorRenderer> {
|
||||||
fn register(&mut self, config: &mut WebServiceConfig<'a, Err>);
|
fn register(&mut self, config: &mut WebServiceConfig<'a, Err>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct ServiceFactoryWrapper<T> {
|
pub(super) fn create_web_service<'a, T, Err>(svc: T) -> Box<dyn WebServiceWrapper<'a, Err>>
|
||||||
factory: Option<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ServiceFactoryWrapper<T> {
|
|
||||||
pub(super) fn new(factory: T) -> Self {
|
|
||||||
Self {
|
|
||||||
factory: Some(factory),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, Err> AppServiceFactory<'a, Err> for ServiceFactoryWrapper<T>
|
|
||||||
where
|
where
|
||||||
|
T: WebService<'a, Err> + 'static,
|
||||||
|
Err: ErrorRenderer,
|
||||||
|
{
|
||||||
|
Box::new(WebServiceWrapperInner(Some(svc)))
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WebServiceWrapperInner<T>(Option<T>);
|
||||||
|
|
||||||
|
impl<'a, T, Err> WebServiceWrapper<'a, Err> for WebServiceWrapperInner<T>
|
||||||
|
where
|
||||||
|
T: WebService<'a, Err> + 'static,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
T: WebServiceFactory<'a, Err>,
|
|
||||||
{
|
{
|
||||||
fn register(&mut self, config: &mut WebServiceConfig<'a, Err>) {
|
fn register(&mut self, config: &mut WebServiceConfig<'a, Err>) {
|
||||||
if let Some(item) = self.factory.take() {
|
if let Some(item) = self.0.take() {
|
||||||
item.register(config)
|
item.register(config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +130,7 @@ impl<'a, Err: ErrorRenderer> WebServiceConfig<'a, Err> {
|
||||||
nested: Option<Rc<ResourceMap>>,
|
nested: Option<Rc<ResourceMap>>,
|
||||||
) where
|
) where
|
||||||
S: ServiceFactory<
|
S: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
Response = WebResponse,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
|
@ -209,9 +208,9 @@ impl WebServiceAdapter {
|
||||||
// /// Set a service factory implementation and generate web service.
|
// /// Set a service factory implementation and generate web service.
|
||||||
// pub fn finish<'a, T, F, Err>(self, service: F) -> impl WebServiceFactory<'a, Err>
|
// pub fn finish<'a, T, F, Err>(self, service: F) -> impl WebServiceFactory<'a, Err>
|
||||||
// where
|
// where
|
||||||
// F: IntoServiceFactory<T, &'a mut WebRequest<Err>>,
|
// F: IntoServiceFactory<T, &'a mut WebRequest<'a, Err>>,
|
||||||
// T: ServiceFactory<
|
// T: ServiceFactory<
|
||||||
// &'a mut WebRequest<Err>,
|
// &'a mut WebRequest<'a, Err>,
|
||||||
// Response = WebResponse,
|
// Response = WebResponse,
|
||||||
// Error = Err::Container,
|
// Error = Err::Container,
|
||||||
// InitError = (),
|
// InitError = (),
|
||||||
|
@ -228,62 +227,62 @@ impl WebServiceAdapter {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WebServiceImpl<T> {
|
// struct WebServiceImpl<T> {
|
||||||
srv: T,
|
// srv: T,
|
||||||
rdef: Vec<String>,
|
// rdef: Vec<String>,
|
||||||
name: Option<String>,
|
// name: Option<String>,
|
||||||
guards: Vec<Box<dyn Guard>>,
|
// guards: Vec<Box<dyn Guard>>,
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl<'a, T, Err> WebServiceFactory<'a, Err> for WebServiceImpl<T>
|
// impl<'a, T, Err> WebServiceFactory<'a, Err> for WebServiceImpl<T>
|
||||||
where
|
// where
|
||||||
T: ServiceFactory<
|
// T: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
// &'a mut WebRequest<'a, Err>,
|
||||||
Response = WebResponse,
|
// Response = WebResponse,
|
||||||
Error = Err::Container,
|
// Error = Err::Container,
|
||||||
InitError = (),
|
// InitError = (),
|
||||||
> + 'static,
|
// > + 'static,
|
||||||
T::Future: 'static,
|
// T::Future: 'static,
|
||||||
T::Service: 'static,
|
// T::Service: 'static,
|
||||||
Err: ErrorRenderer,
|
// Err: ErrorRenderer,
|
||||||
{
|
// {
|
||||||
fn register(mut self, config: &mut WebServiceConfig<'a, Err>) {
|
// fn register(mut self, config: &mut WebServiceConfig<'a, Err>) {
|
||||||
let guards = if self.guards.is_empty() {
|
// let guards = if self.guards.is_empty() {
|
||||||
None
|
// None
|
||||||
} else {
|
// } else {
|
||||||
Some(std::mem::take(&mut self.guards))
|
// Some(std::mem::take(&mut self.guards))
|
||||||
};
|
// };
|
||||||
|
|
||||||
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
|
// let mut rdef = if config.is_root() || !self.rdef.is_empty() {
|
||||||
ResourceDef::new(insert_slash(self.rdef))
|
// ResourceDef::new(insert_slash(self.rdef))
|
||||||
} else {
|
// } else {
|
||||||
ResourceDef::new(self.rdef)
|
// ResourceDef::new(self.rdef)
|
||||||
};
|
// };
|
||||||
if let Some(ref name) = self.name {
|
// if let Some(ref name) = self.name {
|
||||||
*rdef.name_mut() = name.clone();
|
// *rdef.name_mut() = name.clone();
|
||||||
}
|
// }
|
||||||
config.register_service(rdef, guards, self.srv, None)
|
// config.register_service(rdef, guards, self.srv, None)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// WebServiceFactory implementation for a Vec<T>
|
// /// WebServiceFactory implementation for a Vec<T>
|
||||||
#[allow(unused_parens)]
|
// #[allow(unused_parens)]
|
||||||
impl<'a, Err, T> WebServiceFactory<'a, Err> for Vec<T>
|
// impl<'a, Err, T> WebServiceFactory<'a, Err> for Vec<T>
|
||||||
where
|
// where
|
||||||
Err: ErrorRenderer,
|
// Err: ErrorRenderer,
|
||||||
T: WebServiceFactory<'a, Err> + 'static,
|
// T: WebServiceFactory<'a, Err> + 'static,
|
||||||
{
|
// {
|
||||||
fn register(mut self, config: &mut WebServiceConfig<'a, Err>) {
|
// fn register(mut self, config: &mut WebServiceConfig<'a, Err>) {
|
||||||
for service in self.drain(..) {
|
// for service in self.drain(..) {
|
||||||
service.register(config);
|
// service.register(config);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
macro_rules! tuple_web_service({$(($n:tt, $T:ident)),+} => {
|
macro_rules! tuple_web_service({$(($n:tt, $T:ident)),+} => {
|
||||||
/// WebServiceFactory implementation for a tuple
|
/// WebServiceFactory implementation for a tuple
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
impl<'a, Err: ErrorRenderer, $($T: WebServiceFactory<'a, Err> + 'static),+> WebServiceFactory<'a, Err> for ($($T,)+) {
|
impl<'a, Err: ErrorRenderer, $($T: WebService<'a, Err> + 'static),+> WebService<'a, Err> for ($($T,)+) {
|
||||||
fn register(self, config: &mut WebServiceConfig<'a, Err>) {
|
fn register(self, config: &mut WebServiceConfig<'a, Err>) {
|
||||||
$(
|
$(
|
||||||
self.$n.register(config);
|
self.$n.register(config);
|
||||||
|
@ -295,10 +294,10 @@ macro_rules! tuple_web_service({$(($n:tt, $T:ident)),+} => {
|
||||||
macro_rules! array_web_service({$num:tt, $($T:ident),+} => {
|
macro_rules! array_web_service({$num:tt, $($T:ident),+} => {
|
||||||
/// WebServiceFactory implementation for an array
|
/// WebServiceFactory implementation for an array
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
impl<'a, Err, T> WebServiceFactory<'a, Err> for [T; $num]
|
impl<'a, Err, T> WebService<'a, Err> for [T; $num]
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
T: WebServiceFactory<'a, Err> + 'static,
|
T: WebService<'a, Err> + 'static,
|
||||||
{
|
{
|
||||||
fn register(self, config: &mut WebServiceConfig<'a, Err>) {
|
fn register(self, config: &mut WebServiceConfig<'a, Err>) {
|
||||||
let [$($T,)+] = self;
|
let [$($T,)+] = self;
|
||||||
|
|
|
@ -9,32 +9,24 @@ use crate::service::{
|
||||||
};
|
};
|
||||||
use crate::util::{ready, Ready};
|
use crate::util::{ready, Ready};
|
||||||
|
|
||||||
use super::httprequest::{HttpRequest, WeakHttpRequest};
|
use super::httprequest::HttpRequest;
|
||||||
use super::{ErrorContainer, ErrorRenderer, WebRequest, WebResponse};
|
use super::{ErrorContainer, ErrorRenderer, WebRequest, WebResponse};
|
||||||
|
|
||||||
pub struct Stack<Inner, Outer, Err> {
|
pub struct Stack<Inner, Outer> {
|
||||||
inner: Inner,
|
inner: Inner,
|
||||||
outer: Outer,
|
outer: Outer,
|
||||||
_t: PhantomData<Err>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Inner, Outer, Err> Stack<Inner, Outer, Err> {
|
impl<Inner, Outer> Stack<Inner, Outer> {
|
||||||
pub(super) fn new(inner: Inner, outer: Outer) -> Self {
|
pub(super) fn new(inner: Inner, outer: Outer) -> Self {
|
||||||
Stack {
|
Stack { inner, outer }
|
||||||
inner,
|
|
||||||
outer,
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, Inner, Outer, Err> Transform<S> for Stack<Inner, Outer, Err>
|
impl<S, Inner, Outer> Transform<S> for Stack<Inner, Outer>
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer,
|
|
||||||
Inner: Transform<S>,
|
Inner: Transform<S>,
|
||||||
Inner::Service: Service<WebRequest<Err>, Response = WebResponse>,
|
Outer: Transform<Next<Inner::Service>>,
|
||||||
<Inner::Service as Service<WebRequest<Err>>>::Error: Into<Err::Container>,
|
|
||||||
Outer: Transform<Next<Inner::Service, Err>>,
|
|
||||||
{
|
{
|
||||||
type Service = Outer::Service;
|
type Service = Outer::Service;
|
||||||
|
|
||||||
|
@ -77,9 +69,9 @@ pub struct Middleware<S, Err> {
|
||||||
_t: PhantomData<Err>,
|
_t: PhantomData<Err>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S, Err> Service<&'a mut WebRequest<Err>> for Middleware<S, Err>
|
impl<'a, S, Err> Service<&'a mut WebRequest<'a, Err>> for Middleware<S, Err>
|
||||||
where
|
where
|
||||||
S: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
S: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
type Response = WebResponse;
|
type Response = WebResponse;
|
||||||
|
@ -93,7 +85,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&self, req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
MiddlewareResponse {
|
MiddlewareResponse {
|
||||||
fut: self.md.call(req),
|
fut: self.md.call(req),
|
||||||
}
|
}
|
||||||
|
@ -101,7 +93,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
pub struct MiddlewareResponse<'a, S: Service<&'a mut WebRequest<Err>>, Err> {
|
pub struct MiddlewareResponse<'a, S: Service<&'a mut WebRequest<'a, Err>>, Err> {
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: S::Future,
|
fut: S::Future,
|
||||||
}
|
}
|
||||||
|
@ -109,7 +101,7 @@ pin_project_lite::pin_project! {
|
||||||
|
|
||||||
impl<'a, S, Err> Future for MiddlewareResponse<'a, S, Err>
|
impl<'a, S, Err> Future for MiddlewareResponse<'a, S, Err>
|
||||||
where
|
where
|
||||||
S: Service<&'a mut WebRequest<Err>, Response = WebResponse, Error = Infallible>,
|
S: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = Infallible>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
type Output = Result<WebResponse, Err::Container>;
|
type Output = Result<WebResponse, Err::Container>;
|
||||||
|
@ -119,23 +111,19 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Next<S, Err> {
|
pub struct Next<S> {
|
||||||
inner: Rc<S>,
|
next: S,
|
||||||
_t: PhantomData<Err>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, Err> Next<S, Err> {
|
impl<S> Next<S> {
|
||||||
pub(super) fn new(inner: S) -> Self {
|
pub(super) fn new(next: S) -> Self {
|
||||||
Next {
|
Next { next }
|
||||||
inner: Rc::new(inner),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S, Err> Service<&'a mut WebRequest<Err>> for Next<S, Err>
|
impl<'a, S, Err> Service<&'a mut WebRequest<'a, Err>> for Next<S>
|
||||||
where
|
where
|
||||||
S: Service<&'a mut WebRequest<Err>, Response = WebResponse> + 'static,
|
S: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse> + 'static,
|
||||||
S::Error: Into<Err::Container> + 'static,
|
S::Error: Into<Err::Container> + 'static,
|
||||||
S::Future: 'a,
|
S::Future: 'a,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
|
@ -146,16 +134,17 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
let _ = ready!(self.inner.poll_ready(cx));
|
let _ = ready!(self.next.poll_ready(cx));
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&self, req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
let next = self.inner.clone();
|
let r = unsafe { (req as *mut WebRequest<'a, Err>).as_mut().unwrap() };
|
||||||
|
|
||||||
|
let fut = self.next.call(r);
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let result = next.call(req).await;
|
match fut.await {
|
||||||
match result {
|
|
||||||
Ok(res) => Ok(res),
|
Ok(res) => Ok(res),
|
||||||
Err(err) => Ok(WebResponse::new(err.into().error_response(&req.req))),
|
Err(err) => Ok(WebResponse::new(err.into().error_response(&req.req))),
|
||||||
}
|
}
|
||||||
|
@ -164,16 +153,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project_lite::pin_project! {
|
||||||
pub struct NextResponse<'a, S: Service<&'a mut WebRequest<Err>>, Err> {
|
pub struct NextResponse<'a, S: Service<&'a mut WebRequest<'a, Err>>, Err> {
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: S::Future,
|
fut: S::Future,
|
||||||
req: &'a mut WebRequest<Err>,
|
req: &'a mut WebRequest<'a, Err>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S, Err> Future for NextResponse<'a, S, Err>
|
impl<'a, S, Err> Future for NextResponse<'a, S, Err>
|
||||||
where
|
where
|
||||||
S: Service<&'a mut WebRequest<Err>, Response = WebResponse>,
|
S: Service<&'a mut WebRequest<'a, Err>, Response = WebResponse>,
|
||||||
S::Error: Into<Err::Container>,
|
S::Error: Into<Err::Container>,
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
{
|
{
|
||||||
|
@ -191,37 +180,31 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Filter<Err>(PhantomData<Err>);
|
pub struct Filter;
|
||||||
|
|
||||||
impl<Err: ErrorRenderer> Filter<Err> {
|
impl<'a, Err: ErrorRenderer> FiltersFactory<'a, Err> for Filter {
|
||||||
pub(super) fn new() -> Self {
|
type Service = Filter;
|
||||||
Filter(PhantomData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> FiltersFactory<'a, Err> for Filter<Err> {
|
|
||||||
type Service = Filter<Err>;
|
|
||||||
|
|
||||||
fn create(self) -> Self::Service {
|
fn create(self) -> Self::Service {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<Err>> for Filter<Err> {
|
impl<'a, Err: ErrorRenderer> ServiceFactory<&'a mut WebRequest<'a, Err>> for Filter {
|
||||||
type Response = &'a mut WebRequest<Err>;
|
type Response = &'a mut WebRequest<'a, Err>;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = Filter<Err>;
|
type Service = Filter;
|
||||||
type Future = Ready<Filter<Err>, ()>;
|
type Future = Ready<Filter, ()>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new_service(&self, _: ()) -> Self::Future {
|
fn new_service(&self, _: ()) -> Self::Future {
|
||||||
Ready::Ok(Filter(PhantomData))
|
Ready::Ok(Filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for Filter<Err> {
|
impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<'a, Err>> for Filter {
|
||||||
type Response = &'a mut WebRequest<Err>;
|
type Response = &'a mut WebRequest<'a, Err>;
|
||||||
type Error = Err::Container;
|
type Error = Err::Container;
|
||||||
type Future = Ready<Self::Response, Self::Error>;
|
type Future = Ready<Self::Response, Self::Error>;
|
||||||
|
|
||||||
|
@ -231,33 +214,28 @@ impl<'a, Err: ErrorRenderer> Service<&'a mut WebRequest<Err>> for Filter<Err> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&self, req: &'a mut WebRequest<Err>) -> Self::Future {
|
fn call(&self, req: &'a mut WebRequest<'a, Err>) -> Self::Future {
|
||||||
Ready::Ok(req)
|
Ready::Ok(req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Filters<First, Second, Err> {
|
pub struct Filters<First, Second> {
|
||||||
first: First,
|
first: First,
|
||||||
second: Second,
|
second: Second,
|
||||||
_t: PhantomData<Err>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<First, Second, Err> Filters<First, Second, Err> {
|
impl<First, Second> Filters<First, Second> {
|
||||||
pub(super) fn new(first: First, second: Second) -> Self {
|
pub(super) fn new(first: First, second: Second) -> Self {
|
||||||
Filters {
|
Filters { first, second }
|
||||||
first,
|
|
||||||
second,
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, First, Second, Err> FiltersFactory<'a, Err> for Filters<First, Second, Err>
|
impl<'a, First, Second, Err> FiltersFactory<'a, Err> for Filters<First, Second>
|
||||||
where
|
where
|
||||||
Err: ErrorRenderer,
|
Err: ErrorRenderer,
|
||||||
First: ServiceFactory<
|
First: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = &'a mut WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static,
|
> + 'static,
|
||||||
|
@ -265,13 +243,13 @@ where
|
||||||
First::Future: 'static,
|
First::Future: 'static,
|
||||||
Second: FiltersFactory<'a, Err>,
|
Second: FiltersFactory<'a, Err>,
|
||||||
Second::Service: ServiceFactory<
|
Second::Service: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = &'a mut WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
<Second::Service as ServiceFactory<&'a mut WebRequest<Err>>>::Service: 'static,
|
<Second::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Service: 'static,
|
||||||
<Second::Service as ServiceFactory<&'a mut WebRequest<Err>>>::Future: 'static,
|
<Second::Service as ServiceFactory<&'a mut WebRequest<'a, Err>>>::Future: 'static,
|
||||||
{
|
{
|
||||||
type Service = AndThenFactory<First, Second::Service>;
|
type Service = AndThenFactory<First, Second::Service>;
|
||||||
|
|
||||||
|
@ -282,8 +260,8 @@ where
|
||||||
|
|
||||||
pub trait FiltersFactory<'a, Err: ErrorRenderer> {
|
pub trait FiltersFactory<'a, Err: ErrorRenderer> {
|
||||||
type Service: ServiceFactory<
|
type Service: ServiceFactory<
|
||||||
&'a mut WebRequest<Err>,
|
&'a mut WebRequest<'a, Err>,
|
||||||
Response = &'a mut WebRequest<Err>,
|
Response = &'a mut WebRequest<'a, Err>,
|
||||||
Error = Err::Container,
|
Error = Err::Container,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
> + 'static;
|
> + 'static;
|
||||||
|
|
|
@ -31,7 +31,7 @@ use crate::web::{FromRequest, HttpResponse, Responder, WebRequest, WebResponse};
|
||||||
|
|
||||||
/// Create service that always responds with `HttpResponse::Ok()`
|
/// Create service that always responds with `HttpResponse::Ok()`
|
||||||
pub fn ok_service<Err: ErrorRenderer>(
|
pub fn ok_service<Err: ErrorRenderer>(
|
||||||
) -> impl Service<WebRequest<Err>, Response = WebResponse, Error = std::convert::Infallible>
|
) -> impl Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = std::convert::Infallible>
|
||||||
{
|
{
|
||||||
default_service::<Err>(StatusCode::OK)
|
default_service::<Err>(StatusCode::OK)
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,9 @@ pub fn ok_service<Err: ErrorRenderer>(
|
||||||
/// Create service that responds with response with specified status code
|
/// Create service that responds with response with specified status code
|
||||||
pub fn default_service<Err: ErrorRenderer>(
|
pub fn default_service<Err: ErrorRenderer>(
|
||||||
status_code: StatusCode,
|
status_code: StatusCode,
|
||||||
) -> impl Service<WebRequest<Err>, Response = WebResponse, Error = std::convert::Infallible>
|
) -> impl Service<&'a mut WebRequest<'a, Err>, Response = WebResponse, Error = std::convert::Infallible>
|
||||||
{
|
{
|
||||||
(move |req: WebRequest<Err>| {
|
(move |req: &'a mut WebRequest<'a, Err>| {
|
||||||
Ready::Ok(req.into_response(HttpResponse::build(status_code).finish()))
|
Ready::Ok(req.into_response(HttpResponse::build(status_code).finish()))
|
||||||
})
|
})
|
||||||
.into_service()
|
.into_service()
|
||||||
|
@ -248,13 +248,13 @@ where
|
||||||
.unwrap_or_else(|_| panic!("read_response_json failed during deserialization"))
|
.unwrap_or_else(|_| panic!("read_response_json failed during deserialization"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// Helper method for extractors testing
|
/// Helper method for extractors testing
|
||||||
// pub async fn from_request<'a, T: FromRequest<'a, DefaultError>>(
|
pub async fn from_request<T: FromRequest<DefaultError>>(
|
||||||
// req: &'a HttpRequest,
|
req: &HttpRequest,
|
||||||
// payload: &'a mut Payload,
|
payload: &mut Payload,
|
||||||
// ) -> Result<T, T::Error> {
|
) -> Result<T, T::Error> {
|
||||||
// T::from_request(req, payload).await
|
T::from_request(req, payload).await
|
||||||
// }
|
}
|
||||||
|
|
||||||
/// Helper method for responders testing
|
/// Helper method for responders testing
|
||||||
pub async fn respond_to<T: Responder<DefaultError>>(
|
pub async fn respond_to<T: Responder<DefaultError>>(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue