stopping point

This commit is contained in:
Nikolay Kim 2022-02-07 14:00:10 +06:00
parent 050cb560c6
commit d1a5348e77
23 changed files with 225 additions and 519 deletions

View file

@ -1,44 +0,0 @@
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_service(
web::route().to(|| 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
}

View file

@ -1,25 +0,0 @@
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(())
}

View file

@ -1,35 +0,0 @@
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
}

View file

@ -1,31 +0,0 @@
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
}

View file

@ -1,27 +0,0 @@
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
}

View file

@ -1,47 +0,0 @@
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() {}

View file

@ -1,23 +1,18 @@
use std::{
cell::RefCell, fmt, future::Future, marker::PhantomData, pin::Pin, rc::Rc, task,
};
use std::{cell::RefCell, convert::Infallible, fmt, future::Future, pin::Pin, rc::Rc};
use crate::http::Request;
use crate::router::ResourceDef;
use crate::service::boxed::{self, BoxServiceFactory};
use crate::service::{map_config, pipeline_factory, PipelineFactory};
use crate::service::{Identity, IntoServiceFactory, Service, ServiceFactory, Transform};
use crate::util::{Extensions, Ready};
use crate::util::Extensions;
use super::app_service::{AppFactory, AppService};
use super::config::{AppConfig, ServiceConfig};
use super::request::WebRequest;
use super::resource::Resource;
use super::response::WebResponse;
use super::route::Route;
use super::service::{AppServiceFactory, ServiceFactoryWrapper, WebServiceFactory};
use super::stack::{Filter, Next, Stack};
use super::types::state::{State, StateFactory};
use super::{DefaultError, ErrorRenderer};
use super::{DefaultError, ErrorRenderer, Resource, Route, WebRequest, WebResponse};
type HttpNewService<Err: ErrorRenderer> =
BoxServiceFactory<(), WebRequest<Err>, WebResponse, Err::Container, ()>;
@ -412,7 +407,7 @@ where
/// .route("/index.html", web::get().to(index));
/// }
/// ```
pub fn wrap<U>(self, mw: U) -> App<Stack<M, U>, T, Err> {
pub fn wrap<U>(self, mw: U) -> App<Stack<M, U, Err>, T, Err> {
App {
middleware: Stack::new(self.middleware, mw),
filter: self.filter,
@ -438,15 +433,14 @@ where
impl<M, F, Err> App<M, F, Err>
where
M: Transform<AppService<F::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<AppService<F::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
>,
F::Future: 'static,
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
> + 'static,
Err: ErrorRenderer,
{
/// Construct service factory with default `AppConfig`, suitable for `http::HttpService`.
@ -523,15 +517,14 @@ where
impl<M, F, Err> IntoServiceFactory<AppFactory<M, F, Err>, Request, AppConfig>
for App<M, F, Err>
where
M: Transform<AppService<F::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<AppService<F::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
>,
F::Future: 'static,
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
> + 'static,
Err: ErrorRenderer,
{
fn into_factory(self) -> AppFactory<M, F, Err> {
@ -551,15 +544,14 @@ where
impl<M, F, Err> IntoServiceFactory<AppFactory<M, F, Err>, Request, ()> for App<M, F, Err>
where
M: Transform<AppService<F::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<AppService<F::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
>,
F::Future: 'static,
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
> + 'static,
Err: ErrorRenderer,
{
fn into_factory(self) -> AppFactory<M, F, Err> {
@ -577,66 +569,6 @@ where
}
}
pub struct Stack<Inner, Outer> {
inner: Inner,
outer: Outer,
}
impl<Inner, Outer> Stack<Inner, Outer> {
pub(super) fn new(inner: Inner, outer: Outer) -> Self {
Stack { inner, outer }
}
}
impl<S, Inner, Outer> Transform<S> for Stack<Inner, Outer>
where
Inner: Transform<S>,
Outer: Transform<Inner::Service>,
{
type Service = Outer::Service;
fn new_transform(&self, service: S) -> Self::Service {
self.outer.new_transform(self.inner.new_transform(service))
}
}
pub struct Filter<Err>(PhantomData<Err>);
impl<Err: ErrorRenderer> Filter<Err> {
pub(super) fn new() -> Self {
Filter(PhantomData)
}
}
impl<Err: ErrorRenderer> ServiceFactory<WebRequest<Err>> for Filter<Err> {
type Response = WebRequest<Err>;
type Error = Err::Container;
type InitError = ();
type Service = Filter<Err>;
type Future = Ready<Filter<Err>, ()>;
#[inline]
fn new_service(&self, _: ()) -> Self::Future {
Ready::Ok(Filter(PhantomData))
}
}
impl<Err: ErrorRenderer> Service<WebRequest<Err>> for Filter<Err> {
type Response = WebRequest<Err>;
type Error = Err::Container;
type Future = Ready<WebRequest<Err>, Err::Container>;
#[inline]
fn poll_ready(&self, _: &mut task::Context<'_>) -> task::Poll<Result<(), Self::Error>> {
task::Poll::Ready(Ok(()))
}
#[inline]
fn call(&self, req: WebRequest<Err>) -> Self::Future {
Ready::Ok(req)
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1,3 +1,4 @@
use std::convert::Infallible;
use std::task::{Context, Poll};
use std::{cell::RefCell, future::Future, marker::PhantomData, pin::Pin, rc::Rc};
@ -5,17 +6,16 @@ use crate::http::{Request, Response};
use crate::router::{Path, ResourceDef, Router};
use crate::service::boxed::{self, BoxService, BoxServiceFactory};
use crate::service::{fn_service, PipelineFactory, Service, ServiceFactory, Transform};
use crate::util::Extensions;
use crate::util::{ready, Extensions};
use super::config::AppConfig;
use super::error::ErrorRenderer;
use super::guard::Guard;
use super::httprequest::{HttpRequest, HttpRequestPool};
use super::request::WebRequest;
use super::response::WebResponse;
use super::rmap::ResourceMap;
use super::service::{AppServiceFactory, WebServiceConfig};
use super::stack::Next;
use super::types::state::StateFactory;
use super::{ErrorRenderer, WebRequest, WebResponse};
type Guards = Vec<Box<dyn Guard>>;
type HttpService<Err: ErrorRenderer> =
@ -32,12 +32,11 @@ type FnStateFactory =
pub struct AppFactory<T, F, Err: ErrorRenderer>
where
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
>,
F::Future: 'static,
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
> + 'static,
Err: ErrorRenderer,
{
pub(super) middleware: Rc<T>,
@ -53,15 +52,14 @@ where
impl<T, F, Err> ServiceFactory<Request> for AppFactory<T, F, Err>
where
T: Transform<AppService<F::Service, Err>> + 'static,
T::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
T: Transform<Next<AppService<F::Service, Err>, Err>> + 'static,
T::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
>,
F::Future: 'static,
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
> + 'static,
Err: ErrorRenderer,
{
type Response = WebResponse;
@ -77,15 +75,14 @@ where
impl<T, F, Err> ServiceFactory<Request, AppConfig> for AppFactory<T, F, Err>
where
T: Transform<AppService<F::Service, Err>> + 'static,
T::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
T: Transform<Next<AppService<F::Service, Err>, Err>> + 'static,
T::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
>,
F::Future: 'static,
WebRequest<Err>,
Response = WebRequest<Err>,
Error = Err::Container,
InitError = (),
> + 'static,
Err: ErrorRenderer,
{
type Response = WebResponse;
@ -181,7 +178,7 @@ where
Ok(AppFactoryService {
rmap,
config,
service: middleware.new_transform(service),
service: middleware.new_transform(Next::new(service)),
state: Rc::new(extensions),
pool: HttpRequestPool::create(),
_t: PhantomData,
@ -193,7 +190,7 @@ where
/// Service to convert `Request` to a `WebRequest<Err>`
pub struct AppFactoryService<T, Err>
where
T: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
T: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
Err: ErrorRenderer,
{
service: T,
@ -206,16 +203,17 @@ where
impl<T, Err> Service<Request> for AppFactoryService<T, Err>
where
T: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
T: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
Err: ErrorRenderer,
{
type Response = WebResponse;
type Error = T::Error;
type Future = T::Future;
type Error = Err::Container;
type Future = AppFactoryServiceResponse<T, Err>;
#[inline]
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.service.poll_ready(cx)
let _ = ready!(self.service.poll_ready(cx));
Poll::Ready(Ok(()))
}
#[inline]
@ -244,13 +242,15 @@ where
self.pool,
)
};
self.service.call(WebRequest::new(req))
AppFactoryServiceResponse {
fut: self.service.call(WebRequest::new(req)),
}
}
}
impl<T, Err> Drop for AppFactoryService<T, Err>
where
T: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
T: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
Err: ErrorRenderer,
{
fn drop(&mut self) {
@ -258,6 +258,25 @@ where
}
}
pin_project_lite::pin_project! {
pub struct AppFactoryServiceResponse<T: Service<WebRequest<Err>>, Err>{
#[pin]
fut: T::Future
}
}
impl<T, Err> Future for AppFactoryServiceResponse<T, Err>
where
T: Service<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<Err: ErrorRenderer> {
router: Router<HttpService<Err>, Guards>,
default: Option<HttpService<Err>>,

View file

@ -8,7 +8,7 @@ use crate::{http::Payload, util::Ready};
/// Trait implemented by types that can be extracted from request.
///
/// 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.
type Error;
@ -16,12 +16,12 @@ pub trait FromRequest<Err>: Sized {
type Future: Future<Output = Result<Self, Self::Error>>;
/// 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
///
/// 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)
}
}
@ -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
T: FromRequest<Err> + 'static,
T: FromRequest<'a, Err> + 'static,
T::Future: 'static,
Err: ErrorRenderer,
<T as FromRequest<Err>>::Error: Into<Err::Container>,
<T as FromRequest<'a, Err>>::Error: Into<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]
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);
Box::pin(async move {
match fut.await {
@ -139,18 +139,18 @@ where
/// );
/// }
/// ```
impl<T, E> FromRequest<E> for Result<T, T::Error>
impl<'a, T, E> FromRequest<'a, E> for Result<T, T::Error>
where
T: FromRequest<E> + 'static,
T: FromRequest<'a, E> + 'static,
T::Error: 'static,
T::Future: 'static,
E: ErrorRenderer,
{
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]
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);
Box::pin(async move {
match fut.await {
@ -175,14 +175,14 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
/// FromRequest implementation for a tuple
#[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
$(<$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 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 {
items: <($(Option<$T>,)+)>::default(),
$($T: $T::from_request(req, payload),)+
@ -192,16 +192,16 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
pin_project_lite::pin_project! {
#[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>,)+),
$(#[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
$(<$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>;
@ -238,15 +238,15 @@ mod m {
use super::*;
tuple_from_req!(TupleFromRequest1, (0, A));
tuple_from_req!(TupleFromRequest2, (0, A), (1, B));
tuple_from_req!(TupleFromRequest3, (0, A), (1, B), (2, C));
tuple_from_req!(TupleFromRequest4, (0, A), (1, B), (2, C), (3, D));
tuple_from_req!(TupleFromRequest5, (0, A), (1, B), (2, C), (3, D), (4, E));
tuple_from_req!(TupleFromRequest6, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
tuple_from_req!(TupleFromRequest7, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
tuple_from_req!(TupleFromRequest8, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
tuple_from_req!(TupleFromRequest9, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
tuple_from_req!(TupleFromRequest10, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
// tuple_from_req!(TupleFromRequest2, (0, A), (1, B));
// tuple_from_req!(TupleFromRequest3, (0, A), (1, B), (2, C));
// tuple_from_req!(TupleFromRequest4, (0, A), (1, B), (2, C), (3, D));
// tuple_from_req!(TupleFromRequest5, (0, A), (1, B), (2, C), (3, D), (4, E));
// tuple_from_req!(TupleFromRequest6, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
// tuple_from_req!(TupleFromRequest7, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
// tuple_from_req!(TupleFromRequest8, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
// tuple_from_req!(TupleFromRequest9, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
// tuple_from_req!(TupleFromRequest10, (0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
}
#[cfg(test)]

View file

@ -45,9 +45,8 @@ pub(super) trait HandlerFn<Err: ErrorRenderer> {
pub(super) struct HandlerWrapper<F, T, Err>
where
F: Handler<T, Err>,
T: FromRequest<Err>,
T: FromRequest<'_, Err>,
T::Error: Into<Err::Container>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
Err: ErrorRenderer,
{
hnd: F,
@ -57,9 +56,8 @@ where
impl<F, T, Err> HandlerWrapper<F, T, Err>
where
F: Handler<T, Err>,
T: FromRequest<Err>,
T: FromRequest<'_, Err>,
T::Error: Into<Err::Container>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
Err: ErrorRenderer,
{
pub(super) fn new(hnd: F) -> Self {
@ -73,9 +71,8 @@ where
impl<F, T, Err> HandlerFn<Err> for HandlerWrapper<F, T, Err>
where
F: Handler<T, Err>,
T: FromRequest<Err> + 'static,
T: FromRequest<'_, Err> + 'static,
T::Error: Into<Err::Container>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
Err: ErrorRenderer,
{
fn call(
@ -105,9 +102,8 @@ pin_project_lite::pin_project! {
pub(super) struct HandlerWrapperResponse<F, T, Err>
where
F: Handler<T, Err>,
T: FromRequest<Err>,
T: FromRequest<'_, Err>,
T::Error: Into<Err::Container>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
Err: ErrorRenderer,
{
hnd: F,
@ -124,9 +120,8 @@ pin_project_lite::pin_project! {
impl<F, T, Err> Future for HandlerWrapperResponse<F, T, Err>
where
F: Handler<T, Err>,
T: FromRequest<Err>,
T: FromRequest<'_, Err>,
T::Error: Into<Err::Container>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
Err: ErrorRenderer,
{
type Output = Result<WebResponse, Err::Container>;

View file

@ -1,4 +1,4 @@
use std::{cell::Ref, cell::RefCell, cell::RefMut, fmt, net, rc::Rc};
use std::{cell::Ref, cell::RefCell, cell::RefMut, fmt, net, rc::Rc, rc::Weak};
use crate::http::{
HeaderMap, HttpMessage, Message, Method, Payload, RequestHead, Uri, Version,
@ -17,6 +17,8 @@ use super::rmap::ResourceMap;
/// An HTTP Request
pub struct HttpRequest(pub(crate) Rc<HttpRequestInner>);
pub(super) struct WeakHttpRequest(pub(super) Weak<HttpRequestInner>);
pub(crate) struct HttpRequestInner {
pub(crate) head: Message<RequestHead>,
pub(crate) path: Path<Uri>,
@ -48,6 +50,10 @@ impl HttpRequest {
pool,
}))
}
pub(super) fn downgrade(&self) -> WeakHttpRequest {
WeakHttpRequest(Rc::downgrade(&self.0))
}
}
impl HttpRequest {

View file

@ -1,6 +1,6 @@
//! Middleware for setting default response headers
use std::task::{Context, Poll};
use std::{convert::TryFrom, future::Future, pin::Pin, rc::Rc};
use std::{convert::Infallible, convert::TryFrom, future::Future, pin::Pin, rc::Rc};
use crate::http::error::HttpError;
use crate::http::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
@ -104,11 +104,11 @@ pub struct DefaultHeadersMiddleware<S> {
impl<S, E> Service<WebRequest<E>> for DefaultHeadersMiddleware<S>
where
S: Service<WebRequest<E>, Response = WebResponse>,
S: Service<WebRequest<E>, Response = WebResponse, Error = Infallible>,
S::Future: 'static,
{
type Response = WebResponse;
type Error = S::Error;
type Error = Infallible;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
#[inline]
@ -154,7 +154,7 @@ mod tests {
use crate::util::lazy;
use crate::web::request::WebRequest;
use crate::web::test::{ok_service, TestRequest};
use crate::web::{DefaultError, Error, HttpResponse};
use crate::web::{DefaultError, HttpResponse};
#[crate::rt_test]
async fn test_default_headers() {
@ -171,7 +171,7 @@ mod tests {
let req = TestRequest::default().to_srv_request();
let srv = |req: WebRequest<DefaultError>| async move {
Ok::<_, Error>(
Ok::<_, Infallible>(
req.into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish()),
)
};
@ -185,7 +185,7 @@ mod tests {
#[crate::rt_test]
async fn test_content_type() {
let srv = |req: WebRequest<DefaultError>| async move {
Ok::<_, Error>(req.into_response(HttpResponse::Ok().finish()))
Ok::<_, Infallible>(req.into_response(HttpResponse::Ok().finish()))
};
let mw = DefaultHeaders::new()
.content_type()

View file

@ -82,6 +82,7 @@ mod route;
mod scope;
mod server;
mod service;
mod stack;
pub mod test;
pub mod types;
mod util;
@ -131,8 +132,9 @@ pub mod dev {
pub use crate::web::rmap::ResourceMap;
pub use crate::web::route::IntoRoutes;
pub use crate::web::service::{WebServiceAdapter, WebServiceConfig, WebServiceFactory};
pub use crate::web::stack::Stack;
pub(crate) fn insert_slesh(mut patterns: Vec<String>) -> Vec<String> {
pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
for path in &mut patterns {
if !path.is_empty() && !path.starts_with('/') {
path.insert(0, '/');
@ -141,55 +143,55 @@ pub mod dev {
patterns
}
#[doc(hidden)]
#[inline(always)]
pub fn __assert_extractor<Err, T>()
where
T: super::FromRequest<Err>,
Err: super::ErrorRenderer,
<T as super::FromRequest<Err>>::Error: Into<Err::Container>,
{
}
// #[doc(hidden)]
// #[inline(always)]
// pub fn __assert_extractor<'a, Err, T>()
// where
// T: super::FromRequest<'a, Err>,
// Err: super::ErrorRenderer,
// <T as super::FromRequest<'a, Err>>::Error: Into<Err::Container>,
// {
// }
#[doc(hidden)]
#[inline(always)]
pub fn __assert_handler<Err, Fun, Fut>(
f: Fun,
) -> impl Handler<(), Err, Future = Fut, Output = Fut::Output>
where
Err: super::ErrorRenderer,
Fun: Fn() -> Fut + Clone + 'static,
Fut: std::future::Future + 'static,
Fut::Output: super::Responder<Err>,
{
f
}
// #[doc(hidden)]
// #[inline(always)]
// pub fn __assert_handler<Err, Fun, Fut>(
// f: Fun,
// ) -> impl Handler<(), Err, Future = Fut, Output = Fut::Output>
// where
// Err: super::ErrorRenderer,
// Fun: Fn() -> Fut + Clone + 'static,
// Fut: std::future::Future + 'static,
// Fut::Output: super::Responder<Err>,
// {
// f
// }
macro_rules! assert_handler ({ $name:ident, $($T:ident),+} => {
#[doc(hidden)]
#[inline(always)]
pub fn $name<Err, Fun, Fut, $($T,)+>(
f: Fun,
) -> impl Handler<($($T,)+), Err, Future = Fut, Output = Fut::Output>
where
Err: $crate::web::ErrorRenderer,
Fun: Fn($($T,)+) -> Fut + Clone + 'static,
Fut: std::future::Future + 'static,
Fut::Output: $crate::web::Responder<Err>,
$($T: $crate::web::FromRequest<Err>),+,
{
f
}
});
// macro_rules! assert_handler ({ $name:ident, $($T:ident),+} => {
// #[doc(hidden)]
// #[inline(always)]
// pub fn $name<'a, Err, Fun, Fut, $($T,)+>(
// f: Fun,
// ) -> impl Handler<($($T,)+), Err, Future = Fut, Output = Fut::Output>
// where
// Err: $crate::web::ErrorRenderer,
// Fun: Fn($($T,)+) -> Fut + Clone + 'static,
// Fut: std::future::Future + 'static,
// Fut::Output: $crate::web::Responder<Err>,
// $($T: $crate::web::FromRequest<'a, Err>),+,
// {
// f
// }
// });
assert_handler!(__assert_handler1, A);
assert_handler!(__assert_handler2, A, B);
assert_handler!(__assert_handler3, A, B, C);
assert_handler!(__assert_handler4, A, B, C, D);
assert_handler!(__assert_handler5, A, B, C, D, E);
assert_handler!(__assert_handler6, A, B, C, D, E, F);
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_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_handler1, A);
// assert_handler!(__assert_handler2, A, B);
// assert_handler!(__assert_handler3, A, B, C);
// assert_handler!(__assert_handler4, A, B, C, D);
// assert_handler!(__assert_handler5, A, B, C, D, E);
// assert_handler!(__assert_handler6, A, B, C, D, E, F);
// 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_handler9, A, B, C, D, E, F, G, H, I);
// assert_handler!(__assert_handler10, A, B, C, D, E, F, G, H, I, J);
}

View file

@ -9,7 +9,7 @@ use crate::util::Extensions;
use super::config::AppConfig;
use super::error::{ErrorRenderer, WebResponseError};
use super::httprequest::HttpRequest;
use super::httprequest::{HttpRequest, WeakHttpRequest};
use super::info::ConnectionInfo;
use super::response::WebResponse;
use super::rmap::ResourceMap;
@ -45,6 +45,10 @@ impl<Err> WebRequest<Err> {
}
}
pub(super) fn weak_request(&self) -> WeakHttpRequest {
self.req.downgrade()
}
/// Deconstruct request into parts
pub fn into_parts(mut self) -> (HttpRequest, Payload) {
let pl = Rc::get_mut(&mut (self.req).0).unwrap().payload.take();

View file

@ -1,6 +1,6 @@
use std::{
cell::RefCell, fmt, future::Future, pin::Pin, rc::Rc, task::Context, task::Poll,
};
use std::convert::Infallible;
use std::task::{Context, Poll};
use std::{cell::RefCell, fmt, future::Future, pin::Pin, rc::Rc};
use crate::http::Response;
use crate::router::{IntoPattern, ResourceDef};
@ -9,15 +9,11 @@ use crate::service::{pipeline_factory, PipelineFactory};
use crate::service::{Identity, IntoServiceFactory, Service, ServiceFactory, Transform};
use crate::util::{Either, Extensions, Ready};
use super::dev::{insert_slesh, WebServiceConfig, WebServiceFactory};
use super::error::ErrorRenderer;
use super::dev::{insert_slash, WebServiceConfig, WebServiceFactory};
use super::extract::FromRequest;
use super::handler::Handler;
use super::request::WebRequest;
use super::responder::Responder;
use super::response::WebResponse;
use super::route::{IntoRoutes, Route, RouteService};
use super::{app::Filter, app::Stack, guard::Guard, types::State};
use super::stack::{Filter, Next, Stack, Middleware, MiddlewareStack};
use super::{guard::Guard, types::State, ErrorRenderer, Handler, WebRequest, WebResponse};
type HttpService<Err: ErrorRenderer> =
BoxService<WebRequest<Err>, WebResponse, Err::Container>;
@ -231,9 +227,8 @@ where
pub fn to<F, Args>(mut self, handler: F) -> Self
where
F: Handler<Args, Err>,
Args: FromRequest<Err> + 'static,
Args: FromRequest<'_, Err> + 'static,
Args::Error: Into<Err::Container>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
{
self.routes.push(Route::new().to(handler));
self
@ -283,7 +278,7 @@ where
/// type (i.e modify response's body).
///
/// **Note**: middlewares get called in opposite order of middlewares registration.
pub fn wrap<U>(self, mw: U) -> Resource<Err, Stack<M, U>, T> {
pub fn wrap<U>(self, mw: U) -> Resource<Err, Stack<M, U, Err>, T> {
Resource {
middleware: Stack::new(self.middleware, mw),
filter: self.filter,
@ -324,8 +319,8 @@ where
Error = Err::Container,
InitError = (),
> + 'static,
M: Transform<ResourceService<T::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<ResourceService<T::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
Err: ErrorRenderer,
{
fn register(mut self, config: &mut WebServiceConfig<Err>) {
@ -335,7 +330,7 @@ where
Some(std::mem::take(&mut self.guards))
};
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
ResourceDef::new(insert_slesh(self.rdef.clone()))
ResourceDef::new(insert_slash(self.rdef.clone()))
} else {
ResourceDef::new(self.rdef.clone())
};
@ -357,7 +352,7 @@ where
rdef,
guards,
ResourceServiceFactory {
middleware: Rc::new(self.middleware),
middleware: Rc::new(MiddlewareStack::new(self.middleware)),
filter: self.filter,
routing: router_factory,
},
@ -378,8 +373,8 @@ where
Error = Err::Container,
InitError = (),
> + 'static,
M: Transform<ResourceService<T::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<ResourceService<T::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
Err: ErrorRenderer,
{
fn into_factory(
@ -392,7 +387,7 @@ where
};
ResourceServiceFactory {
middleware: Rc::new(self.middleware),
middleware: Rc::new(MiddlewareStack::new(self.middleware)),
filter: self.filter,
routing: router_factory,
}
@ -401,15 +396,15 @@ where
/// Resource service
pub struct ResourceServiceFactory<Err: ErrorRenderer, M, T> {
middleware: Rc<M>,
middleware: Rc<MiddlewareStack<M, Err>>,
filter: T,
routing: ResourceRouterFactory<Err>,
}
impl<Err, M, F> ServiceFactory<WebRequest<Err>> for ResourceServiceFactory<Err, M, F>
where
M: Transform<ResourceService<F::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<ResourceService<F::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
@ -420,7 +415,7 @@ where
{
type Response = WebResponse;
type Error = Err::Container;
type Service = M::Service;
type Service = Middleware<M::Service, Err>;
type InitError = ();
type Future = Pin<Box<dyn Future<Output = Result<Self::Service, Self::InitError>>>>;

View file

@ -1,9 +1,8 @@
use std::task::{Context, Poll};
use std::{convert::TryFrom, future::Future, marker::PhantomData, pin::Pin};
use crate::http::error::HttpError;
use crate::http::header::{HeaderMap, HeaderName, HeaderValue};
use crate::http::{Response, ResponseBuilder, StatusCode};
use crate::http::{error::HttpError, Response, ResponseBuilder, StatusCode};
use crate::util::{Bytes, BytesMut, Either};
use super::error::{
@ -34,9 +33,6 @@ impl<T> Future for Ready<T> {
///
/// Types that implement this trait can be used as the return type of a handler.
pub trait Responder<Err = DefaultError> {
/// The associated error which can be returned.
type Error;
/// The future response value.
type Future: Future<Output = Response>;
@ -93,7 +89,6 @@ pub trait Responder<Err = DefaultError> {
}
impl<Err: ErrorRenderer> Responder<Err> for Response {
type Error = Err::Container;
type Future = Ready<Response>;
#[inline]
@ -103,7 +98,6 @@ impl<Err: ErrorRenderer> Responder<Err> for Response {
}
impl<Err: ErrorRenderer> Responder<Err> for ResponseBuilder {
type Error = Err::Container;
type Future = Ready<Response>;
#[inline]
@ -117,7 +111,6 @@ where
T: Responder<Err>,
Err: ErrorRenderer,
{
type Error = T::Error;
type Future = Either<T::Future, Ready<Response>>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {
@ -136,7 +129,6 @@ where
E: Into<Err::Container>,
Err: ErrorRenderer,
{
type Error = T::Error;
type Future = Either<T::Future, Ready<Response>>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {
@ -152,7 +144,6 @@ where
T: Responder<Err>,
Err: ErrorRenderer,
{
type Error = T::Error;
type Future = CustomResponderFut<T, Err>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {
@ -165,7 +156,6 @@ where
}
impl<Err: ErrorRenderer> Responder<Err> for &'static str {
type Error = Err::Container;
type Future = Ready<Response>;
fn respond_to(self, _: &HttpRequest) -> Self::Future {
@ -178,7 +168,6 @@ impl<Err: ErrorRenderer> Responder<Err> for &'static str {
}
impl<Err: ErrorRenderer> Responder<Err> for &'static [u8] {
type Error = Err::Container;
type Future = Ready<Response>;
fn respond_to(self, _: &HttpRequest) -> Self::Future {
@ -191,7 +180,6 @@ impl<Err: ErrorRenderer> Responder<Err> for &'static [u8] {
}
impl<Err: ErrorRenderer> Responder<Err> for String {
type Error = Err::Container;
type Future = Ready<Response>;
fn respond_to(self, _: &HttpRequest) -> Self::Future {
@ -204,7 +192,6 @@ impl<Err: ErrorRenderer> Responder<Err> for String {
}
impl<'a, Err: ErrorRenderer> Responder<Err> for &'a String {
type Error = Err::Container;
type Future = Ready<Response>;
fn respond_to(self, _: &HttpRequest) -> Self::Future {
@ -217,7 +204,6 @@ impl<'a, Err: ErrorRenderer> Responder<Err> for &'a String {
}
impl<Err: ErrorRenderer> Responder<Err> for Bytes {
type Error = Err::Container;
type Future = Ready<Response>;
fn respond_to(self, _: &HttpRequest) -> Self::Future {
@ -230,7 +216,6 @@ impl<Err: ErrorRenderer> Responder<Err> for Bytes {
}
impl<Err: ErrorRenderer> Responder<Err> for BytesMut {
type Error = Err::Container;
type Future = Ready<Response>;
fn respond_to(self, _: &HttpRequest) -> Self::Future {
@ -322,7 +307,6 @@ impl<T: Responder<Err>, Err> CustomResponder<T, Err> {
}
impl<T: Responder<Err>, Err: ErrorRenderer> Responder<Err> for CustomResponder<T, Err> {
type Error = T::Error;
type Future = CustomResponderFut<T, Err>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {
@ -390,7 +374,6 @@ where
B: Responder<Err>,
Err: ErrorRenderer,
{
type Error = Err::Container;
type Future = Either<A::Future, B::Future>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {
@ -406,7 +389,6 @@ where
T: std::fmt::Debug + std::fmt::Display + 'static,
Err: ErrorRenderer,
{
type Error = Err::Container;
type Future = Ready<Response>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {
@ -423,9 +405,7 @@ pub(crate) mod tests {
use crate::web::test::{init_service, TestRequest};
use crate::{service::Service, util::Bytes, util::BytesMut, web};
fn responder<T: Responder<DefaultError>>(
responder: T,
) -> impl Responder<DefaultError, Error = T::Error> {
fn responder<T: Responder<DefaultError>>(responder: T) -> impl Responder<DefaultError> {
responder
}

View file

@ -2,15 +2,10 @@ use std::{future::Future, mem, pin::Pin, rc::Rc, task::Context, task::Poll};
use crate::{http::Method, service::Service, service::ServiceFactory, util::Ready};
use super::error::ErrorRenderer;
use super::error_default::DefaultError;
use super::extract::FromRequest;
use super::guard::{self, Guard};
use super::handler::{Handler, HandlerFn, HandlerWrapper};
use super::request::WebRequest;
use super::responder::Responder;
use super::response::WebResponse;
use super::HttpResponse;
use super::{ErrorRenderer, FromRequest, HttpResponse, WebRequest, WebResponse};
/// Resource route definition
///
@ -186,9 +181,8 @@ impl<Err: ErrorRenderer> Route<Err> {
pub fn to<F, Args>(mut self, handler: F) -> Self
where
F: Handler<Args, Err>,
Args: FromRequest<Err> + 'static,
Args: FromRequest<'_, Err> + 'static,
Args::Error: Into<Err::Container>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
{
self.handler = Box::new(HandlerWrapper::new(handler));
self

View file

@ -1,6 +1,5 @@
use std::{
cell::RefCell, fmt, future::Future, pin::Pin, rc::Rc, task::Context, task::Poll,
};
use std::task::{Context, Poll};
use std::{cell::RefCell, fmt, future::Future, convert::Infallible, pin::Pin, rc::Rc};
use crate::http::Response;
use crate::router::{IntoPattern, ResourceDef, Router};
@ -9,18 +8,14 @@ use crate::service::{pipeline_factory, PipelineFactory};
use crate::service::{Identity, IntoServiceFactory, Service, ServiceFactory, Transform};
use crate::util::{Either, Extensions, Ready};
use super::app::{Filter, Stack};
use super::config::ServiceConfig;
use super::dev::{WebServiceConfig, WebServiceFactory};
use super::error::ErrorRenderer;
use super::guard::Guard;
use super::request::WebRequest;
use super::resource::Resource;
use super::response::WebResponse;
use super::rmap::ResourceMap;
use super::route::Route;
use super::service::{AppServiceFactory, ServiceFactoryWrapper};
use super::stack::{Filter, Next, Stack, MiddlewareStack, Middleware};
use super::types::State;
use super::{ErrorRenderer, Resource, Route, WebRequest, WebResponse};
type Guards = Vec<Box<dyn Guard>>;
type HttpService<Err: ErrorRenderer> =
@ -357,7 +352,7 @@ where
/// WebResponse.
///
/// Use middleware when you need to read or modify *every* request in some way.
pub fn wrap<U>(self, mw: U) -> Scope<Err, Stack<M, U>, T> {
pub fn wrap<U>(self, mw: U) -> Scope<Err, Stack<M, U, Err>, T> {
Scope {
middleware: Stack::new(self.middleware, mw),
filter: self.filter,
@ -380,8 +375,8 @@ where
Error = Err::Container,
InitError = (),
> + 'static,
M: Transform<ScopeService<T::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<ScopeService<T::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
Err: ErrorRenderer,
{
fn register(mut self, config: &mut WebServiceConfig<Err>) {
@ -445,7 +440,7 @@ where
ResourceDef::root_prefix(self.rdef),
guards,
ScopeServiceFactory {
middleware: Rc::new(self.middleware),
middleware: Rc::new(MiddlewareStack::new(self.middleware)),
filter: self.filter,
routing: router_factory,
},
@ -456,15 +451,15 @@ where
/// Scope service
struct ScopeServiceFactory<M, F, Err: ErrorRenderer> {
middleware: Rc<M>,
middleware: Rc<MiddlewareStack<M, Err>>,
filter: F,
routing: ScopeRouterFactory<Err>,
}
impl<M, F, Err> ServiceFactory<WebRequest<Err>> for ScopeServiceFactory<M, F, Err>
where
M: Transform<ScopeService<F::Service, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Err::Container>,
M: Transform<Next<ScopeService<F::Service, Err>, Err>> + 'static,
M::Service: Service<WebRequest<Err>, Response = WebResponse, Error = Infallible>,
F: ServiceFactory<
WebRequest<Err>,
Response = WebRequest<Err>,
@ -475,7 +470,7 @@ where
{
type Response = WebResponse;
type Error = Err::Container;
type Service = M::Service;
type Service = Middleware<M::Service, Err>;
type InitError = ();
type Future = Pin<Box<dyn Future<Output = Result<Self::Service, Self::InitError>>>>;

View file

@ -5,13 +5,10 @@ use crate::service::{boxed, IntoServiceFactory, ServiceFactory};
use crate::util::Extensions;
use super::config::AppConfig;
use super::dev::insert_slesh;
use super::error::ErrorRenderer;
use super::guard::Guard;
use super::request::WebRequest;
use super::response::WebResponse;
use super::dev::insert_slash;
use super::rmap::ResourceMap;
use super::types::state::StateFactory;
use super::{guard::Guard, ErrorRenderer, WebRequest, WebResponse};
pub trait WebServiceFactory<Err: ErrorRenderer> {
fn register(self, config: &mut WebServiceConfig<Err>);
@ -255,7 +252,7 @@ where
};
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
ResourceDef::new(insert_slesh(self.rdef))
ResourceDef::new(insert_slash(self.rdef))
} else {
ResourceDef::new(self.rdef)
};

View file

@ -249,10 +249,10 @@ where
}
/// Helper method for extractors testing
pub async fn from_request<T: FromRequest<DefaultError>>(
req: &HttpRequest,
payload: &mut Payload,
) -> Result<T, T::Error> {
pub async fn from_request<'a, T: FromRequest<'a, DefaultError>>(
req: &'a HttpRequest,
payload: &'a mut Payload,
) -> Result<T, T::Error> + 'a {
T::from_request(req, payload).await
}

View file

@ -136,7 +136,6 @@ impl<T: Serialize, Err: ErrorRenderer> Responder<Err> for Form<T>
where
Err::Container: From<serde_urlencoded::ser::Error>,
{
type Error = serde_urlencoded::ser::Error;
type Future = Ready<Response>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {

View file

@ -112,7 +112,6 @@ impl<T: Serialize, Err: ErrorRenderer> Responder<Err> for Json<T>
where
Err::Container: From<JsonError>,
{
type Error = JsonError;
type Future = Ready<Response>;
fn respond_to(self, req: &HttpRequest) -> Self::Future {

View file

@ -14,7 +14,6 @@ use super::error::ErrorRenderer;
use super::extract::FromRequest;
use super::handler::Handler;
use super::resource::Resource;
use super::responder::Responder;
use super::route::Route;
use super::scope::Scope;
use super::server::HttpServer;
@ -223,13 +222,12 @@ pub fn method<Err: ErrorRenderer>(method: Method) -> Route<Err> {
/// web::resource("/").route(web::to(index))
/// );
/// ```
pub fn to<F, Args, Err>(handler: F) -> Route<Err>
pub fn to<'a, F, Args, Err>(handler: F) -> Route<Err>
where
F: Handler<Args, Err>,
Args: FromRequest<Err> + 'static,
Args: FromRequest<'a, Err> + 'static,
Err: ErrorRenderer,
Err::Container: From<Args::Error>,
<F::Output as Responder<Err>>::Error: Into<Err::Container>,
{
Route::new().to(handler)
}