mirror of
https://github.com/actix/actix-web.git
synced 2024-11-26 19:41:12 +00:00
use custom request for FromRequest trait
This commit is contained in:
parent
e4198a037a
commit
8103d33270
12 changed files with 342 additions and 216 deletions
|
@ -2,7 +2,7 @@ use futures::IntoFuture;
|
||||||
|
|
||||||
use actix_http::{h1, http::Method, Response};
|
use actix_http::{h1, http::Method, Response};
|
||||||
use actix_server::Server;
|
use actix_server::Server;
|
||||||
use actix_web::{middleware, App, Error, HttpRequest, Resource};
|
use actix_web::{middleware, web, App, Error, HttpRequest, Resource, Route};
|
||||||
|
|
||||||
fn index(req: HttpRequest) -> &'static str {
|
fn index(req: HttpRequest) -> &'static str {
|
||||||
println!("REQ: {:?}", req);
|
println!("REQ: {:?}", req);
|
||||||
|
@ -31,7 +31,7 @@ fn main() {
|
||||||
middleware::DefaultHeaders::new().header("X-Version", "0.2"),
|
middleware::DefaultHeaders::new().header("X-Version", "0.2"),
|
||||||
)
|
)
|
||||||
.middleware(middleware::Compress::default())
|
.middleware(middleware::Compress::default())
|
||||||
.resource("/resource1/index.html", |r| r.get(index))
|
.resource("/resource1/index.html", |r| r.route(web::get().to(index)))
|
||||||
.service(
|
.service(
|
||||||
"/resource2/index.html",
|
"/resource2/index.html",
|
||||||
Resource::new()
|
Resource::new()
|
||||||
|
@ -39,8 +39,10 @@ fn main() {
|
||||||
middleware::DefaultHeaders::new()
|
middleware::DefaultHeaders::new()
|
||||||
.header("X-Version-R2", "0.3"),
|
.header("X-Version-R2", "0.3"),
|
||||||
)
|
)
|
||||||
.default_resource(|r| r.to(|| Response::MethodNotAllowed()))
|
.default_resource(|r| {
|
||||||
.method(Method::GET, |r| r.to_async(index_async)),
|
r.route(Route::new().to(|| Response::MethodNotAllowed()))
|
||||||
|
})
|
||||||
|
.route(web::method(Method::GET).to_async(index_async)),
|
||||||
)
|
)
|
||||||
.service("/test1.html", Resource::new().to(|| "Test\r\n"))
|
.service("/test1.html", Resource::new().to(|| "Test\r\n"))
|
||||||
.service("/", Resource::new().to(no_params)),
|
.service("/", Resource::new().to(no_params)),
|
||||||
|
|
|
@ -159,16 +159,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a middleware.
|
/// Register a middleware.
|
||||||
pub fn middleware<M, F>(
|
pub fn middleware<M, B, F>(
|
||||||
self,
|
self,
|
||||||
mw: F,
|
mw: F,
|
||||||
) -> AppRouter<
|
) -> AppRouter<
|
||||||
T,
|
T,
|
||||||
P,
|
P,
|
||||||
Body,
|
B,
|
||||||
impl NewService<
|
impl NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = (),
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
|
@ -177,7 +177,7 @@ where
|
||||||
M: NewTransform<
|
M: NewTransform<
|
||||||
AppService<P>,
|
AppService<P>,
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse<B>,
|
||||||
Error = (),
|
Error = (),
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
|
|
|
@ -26,7 +26,7 @@ use actix_router::PathDeserializer;
|
||||||
use crate::handler::FromRequest;
|
use crate::handler::FromRequest;
|
||||||
use crate::request::HttpRequest;
|
use crate::request::HttpRequest;
|
||||||
use crate::responder::Responder;
|
use crate::responder::Responder;
|
||||||
use crate::service::ServiceRequest;
|
use crate::service::ServiceFromRequest;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||||
/// Extract typed information from the request's path.
|
/// Extract typed information from the request's path.
|
||||||
|
@ -112,7 +112,7 @@ impl<T> Path<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract path information from a request
|
/// Extract path information from a request
|
||||||
pub fn extract<P>(req: &ServiceRequest<P>) -> Result<Path<T>, de::value::Error>
|
pub fn extract<P>(req: &ServiceFromRequest<P>) -> Result<Path<T>, de::value::Error>
|
||||||
where
|
where
|
||||||
T: DeserializeOwned,
|
T: DeserializeOwned,
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ where
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = FutureResult<Self, Error>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
Self::extract(req).map_err(ErrorNotFound).into_future()
|
Self::extract(req).map_err(ErrorNotFound).into_future()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ where
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = FutureResult<Self, Error>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
serde_urlencoded::from_str::<T>(req.query_string())
|
serde_urlencoded::from_str::<T>(req.query_string())
|
||||||
.map(|val| ok(Query(val)))
|
.map(|val| ok(Query(val)))
|
||||||
.unwrap_or_else(|e| err(e.into()))
|
.unwrap_or_else(|e| err(e.into()))
|
||||||
|
@ -301,7 +301,7 @@ where
|
||||||
type Future = Box<Future<Item = Self, Error = Error>>;
|
type Future = Box<Future<Item = Self, Error = Error>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
let cfg = FormConfig::default();
|
let cfg = FormConfig::default();
|
||||||
|
|
||||||
let req2 = req.clone();
|
let req2 = req.clone();
|
||||||
|
@ -511,7 +511,7 @@ where
|
||||||
type Future = Box<Future<Item = Self, Error = Error>>;
|
type Future = Box<Future<Item = Self, Error = Error>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
let cfg = JsonConfig::default();
|
let cfg = JsonConfig::default();
|
||||||
|
|
||||||
let req2 = req.clone();
|
let req2 = req.clone();
|
||||||
|
@ -619,7 +619,7 @@ where
|
||||||
Either<Box<Future<Item = Bytes, Error = Error>>, FutureResult<Bytes, Error>>;
|
Either<Box<Future<Item = Bytes, Error = Error>>, FutureResult<Bytes, Error>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
let cfg = PayloadConfig::default();
|
let cfg = PayloadConfig::default();
|
||||||
|
|
||||||
if let Err(e) = cfg.check_mimetype(req) {
|
if let Err(e) = cfg.check_mimetype(req) {
|
||||||
|
@ -666,7 +666,7 @@ where
|
||||||
Either<Box<Future<Item = String, Error = Error>>, FutureResult<String, Error>>;
|
Either<Box<Future<Item = String, Error = Error>>, FutureResult<String, Error>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
let cfg = PayloadConfig::default();
|
let cfg = PayloadConfig::default();
|
||||||
|
|
||||||
// check content-type
|
// check content-type
|
||||||
|
@ -755,7 +755,7 @@ where
|
||||||
type Future = Box<Future<Item = Option<T>, Error = Error>>;
|
type Future = Box<Future<Item = Option<T>, Error = Error>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
Box::new(T::from_request(req).then(|r| match r {
|
Box::new(T::from_request(req).then(|r| match r {
|
||||||
Ok(v) => future::ok(Some(v)),
|
Ok(v) => future::ok(Some(v)),
|
||||||
Err(_) => future::ok(None),
|
Err(_) => future::ok(None),
|
||||||
|
@ -818,7 +818,7 @@ where
|
||||||
type Future = Box<Future<Item = Result<T, T::Error>, Error = Error>>;
|
type Future = Box<Future<Item = Result<T, T::Error>, Error = Error>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
Box::new(T::from_request(req).then(|res| match res {
|
Box::new(T::from_request(req).then(|res| match res {
|
||||||
Ok(v) => ok(Ok(v)),
|
Ok(v) => ok(Ok(v)),
|
||||||
Err(e) => ok(Err(e)),
|
Err(e) => ok(Err(e)),
|
||||||
|
@ -846,7 +846,7 @@ impl PayloadConfig {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_mimetype<P>(&self, req: &ServiceRequest<P>) -> Result<(), Error> {
|
fn check_mimetype<P>(&self, req: &ServiceFromRequest<P>) -> Result<(), Error> {
|
||||||
// check content-type
|
// check content-type
|
||||||
if let Some(ref mt) = self.mimetype {
|
if let Some(ref mt) = self.mimetype {
|
||||||
match req.mime_type() {
|
match req.mime_type() {
|
||||||
|
@ -884,7 +884,7 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = $fut_type<P, $($T),+>;
|
type Future = $fut_type<P, $($T),+>;
|
||||||
|
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
$fut_type {
|
$fut_type {
|
||||||
items: <($(Option<$T>,)+)>::default(),
|
items: <($(Option<$T>,)+)>::default(),
|
||||||
futs: ($($T::from_request(req),)+),
|
futs: ($($T::from_request(req),)+),
|
||||||
|
@ -933,7 +933,7 @@ impl<P> FromRequest<P> for () {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = FutureResult<(), Error>;
|
type Future = FutureResult<(), Error>;
|
||||||
|
|
||||||
fn from_request(_req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(_req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
ok(())
|
ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
//! Route match predicates
|
//! Route match predicates
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
use actix_http::http::{self, header, HttpTryFrom};
|
use actix_http::http::{self, header, HttpTryFrom};
|
||||||
|
use actix_http::RequestHead;
|
||||||
use crate::request::HttpRequest;
|
|
||||||
|
|
||||||
/// Trait defines resource predicate.
|
/// Trait defines resource predicate.
|
||||||
/// Predicate can modify request object. It is also possible to
|
/// Predicate can modify request object. It is also possible to
|
||||||
|
@ -10,20 +9,21 @@ use crate::request::HttpRequest;
|
||||||
/// Extensions container available via `HttpRequest::extensions()` method.
|
/// Extensions container available via `HttpRequest::extensions()` method.
|
||||||
pub trait Filter {
|
pub trait Filter {
|
||||||
/// Check if request matches predicate
|
/// Check if request matches predicate
|
||||||
fn check(&self, request: &HttpRequest) -> bool;
|
fn check(&self, request: &RequestHead) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return filter that matches if any of supplied filters.
|
/// Return filter that matches if any of supplied filters.
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust
|
||||||
/// use actix_web::{filter, App, HttpResponse};
|
/// use actix_web::{web, filter, App, HttpResponse};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// App::new().resource("/index.html", |r| {
|
/// App::new().resource("/index.html", |r|
|
||||||
/// r.route()
|
/// r.route(
|
||||||
/// .filter(pred::Any(pred::Get()).or(pred::Post()))
|
/// web::route()
|
||||||
/// .to(|| HttpResponse::MethodNotAllowed())
|
/// .filter(filter::Any(filter::Get()).or(filter::Post()))
|
||||||
/// });
|
/// .to(|| HttpResponse::MethodNotAllowed()))
|
||||||
|
/// );
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn Any<F: Filter + 'static>(filter: F) -> AnyFilter {
|
pub fn Any<F: Filter + 'static>(filter: F) -> AnyFilter {
|
||||||
|
@ -42,7 +42,7 @@ impl AnyFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Filter for AnyFilter {
|
impl Filter for AnyFilter {
|
||||||
fn check(&self, req: &HttpRequest) -> bool {
|
fn check(&self, req: &RequestHead) -> bool {
|
||||||
for p in &self.0 {
|
for p in &self.0 {
|
||||||
if p.check(req) {
|
if p.check(req) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -56,15 +56,13 @@ impl Filter for AnyFilter {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # extern crate actix_web;
|
/// # extern crate actix_web;
|
||||||
/// use actix_web::{filter, App, HttpResponse};
|
/// use actix_web::{filter, web, App, HttpResponse};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// App::new().resource("/index.html", |r| {
|
/// App::new().resource("/index.html", |r| {
|
||||||
/// r.route(
|
/// r.route(web::route()
|
||||||
/// |r| r.filter(
|
/// .filter(
|
||||||
/// filter::All(filter::Get())
|
/// filter::All(filter::Get()).and(filter::Header("content-type", "text/plain")))
|
||||||
/// .and(filter::Header("content-type", "text/plain")),
|
|
||||||
/// )
|
|
||||||
/// .to(|| HttpResponse::MethodNotAllowed()))
|
/// .to(|| HttpResponse::MethodNotAllowed()))
|
||||||
/// });
|
/// });
|
||||||
/// }
|
/// }
|
||||||
|
@ -85,7 +83,7 @@ impl AllFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Filter for AllFilter {
|
impl Filter for AllFilter {
|
||||||
fn check(&self, request: &HttpRequest) -> bool {
|
fn check(&self, request: &RequestHead) -> bool {
|
||||||
for p in &self.0 {
|
for p in &self.0 {
|
||||||
if !p.check(request) {
|
if !p.check(request) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -104,7 +102,7 @@ pub fn Not<F: Filter + 'static>(filter: F) -> NotFilter {
|
||||||
pub struct NotFilter(Box<Filter>);
|
pub struct NotFilter(Box<Filter>);
|
||||||
|
|
||||||
impl Filter for NotFilter {
|
impl Filter for NotFilter {
|
||||||
fn check(&self, request: &HttpRequest) -> bool {
|
fn check(&self, request: &RequestHead) -> bool {
|
||||||
!self.0.check(request)
|
!self.0.check(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,8 +112,8 @@ impl Filter for NotFilter {
|
||||||
pub struct MethodFilter(http::Method);
|
pub struct MethodFilter(http::Method);
|
||||||
|
|
||||||
impl Filter for MethodFilter {
|
impl Filter for MethodFilter {
|
||||||
fn check(&self, request: &HttpRequest) -> bool {
|
fn check(&self, request: &RequestHead) -> bool {
|
||||||
request.method() == self.0
|
request.method == self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,8 +180,8 @@ pub fn Header(name: &'static str, value: &'static str) -> HeaderFilter {
|
||||||
pub struct HeaderFilter(header::HeaderName, header::HeaderValue);
|
pub struct HeaderFilter(header::HeaderName, header::HeaderValue);
|
||||||
|
|
||||||
impl Filter for HeaderFilter {
|
impl Filter for HeaderFilter {
|
||||||
fn check(&self, req: &HttpRequest) -> bool {
|
fn check(&self, req: &RequestHead) -> bool {
|
||||||
if let Some(val) = req.headers().get(&self.0) {
|
if let Some(val) = req.headers.get(&self.0) {
|
||||||
return val == self.1;
|
return val == self.1;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
@ -219,7 +217,7 @@ impl Filter for HeaderFilter {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// impl Filter for HostFilter {
|
// impl Filter for HostFilter {
|
||||||
// fn check(&self, _req: &HttpRequest) -> bool {
|
// fn check(&self, _req: &RequestHead) -> bool {
|
||||||
// // let info = req.connection_info();
|
// // let info = req.connection_info();
|
||||||
// // if let Some(ref scheme) = self.1 {
|
// // if let Some(ref scheme) = self.1 {
|
||||||
// // self.0 == info.host() && scheme == info.scheme()
|
// // self.0 == info.host() && scheme == info.scheme()
|
||||||
|
|
|
@ -7,7 +7,7 @@ use futures::{try_ready, Async, Future, IntoFuture, Poll};
|
||||||
|
|
||||||
use crate::request::HttpRequest;
|
use crate::request::HttpRequest;
|
||||||
use crate::responder::Responder;
|
use crate::responder::Responder;
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceFromRequest, ServiceRequest, ServiceResponse};
|
||||||
|
|
||||||
/// Trait implemented by types that can be extracted from request.
|
/// Trait implemented by types that can be extracted from request.
|
||||||
///
|
///
|
||||||
|
@ -20,7 +20,7 @@ pub trait FromRequest<P>: Sized {
|
||||||
type Future: Future<Item = Self, Error = Self::Error>;
|
type Future: Future<Item = Self, Error = Self::Error>;
|
||||||
|
|
||||||
/// Convert request to a Self
|
/// Convert request to a Self
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future;
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler converter factory
|
/// Handler converter factory
|
||||||
|
@ -306,7 +306,7 @@ impl<P, T: FromRequest<P>> Default for Extract<P, T> {
|
||||||
impl<P, T: FromRequest<P>> NewService for Extract<P, T> {
|
impl<P, T: FromRequest<P>> NewService for Extract<P, T> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = (T, HttpRequest);
|
type Response = (T, HttpRequest);
|
||||||
type Error = (Error, ServiceRequest<P>);
|
type Error = (Error, ServiceFromRequest<P>);
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Service = ExtractService<P, T>;
|
type Service = ExtractService<P, T>;
|
||||||
type Future = FutureResult<Self::Service, ()>;
|
type Future = FutureResult<Self::Service, ()>;
|
||||||
|
@ -323,14 +323,15 @@ pub struct ExtractService<P, T: FromRequest<P>> {
|
||||||
impl<P, T: FromRequest<P>> Service for ExtractService<P, T> {
|
impl<P, T: FromRequest<P>> Service for ExtractService<P, T> {
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
type Response = (T, HttpRequest);
|
type Response = (T, HttpRequest);
|
||||||
type Error = (Error, ServiceRequest<P>);
|
type Error = (Error, ServiceFromRequest<P>);
|
||||||
type Future = ExtractResponse<P, T>;
|
type Future = ExtractResponse<P, T>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
Ok(Async::Ready(()))
|
Ok(Async::Ready(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future {
|
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
|
||||||
|
let mut req = req.into();
|
||||||
ExtractResponse {
|
ExtractResponse {
|
||||||
fut: T::from_request(&mut req),
|
fut: T::from_request(&mut req),
|
||||||
req: Some(req),
|
req: Some(req),
|
||||||
|
@ -339,13 +340,13 @@ impl<P, T: FromRequest<P>> Service for ExtractService<P, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExtractResponse<P, T: FromRequest<P>> {
|
pub struct ExtractResponse<P, T: FromRequest<P>> {
|
||||||
req: Option<ServiceRequest<P>>,
|
req: Option<ServiceFromRequest<P>>,
|
||||||
fut: T::Future,
|
fut: T::Future,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, T: FromRequest<P>> Future for ExtractResponse<P, T> {
|
impl<P, T: FromRequest<P>> Future for ExtractResponse<P, T> {
|
||||||
type Item = (T, HttpRequest);
|
type Item = (T, HttpRequest);
|
||||||
type Error = (Error, ServiceRequest<P>);
|
type Error = (Error, ServiceFromRequest<P>);
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
let item = try_ready!(self
|
let item = try_ready!(self
|
||||||
|
|
81
src/lib.rs
81
src/lib.rs
|
@ -25,12 +25,91 @@ pub use crate::handler::FromRequest;
|
||||||
pub use crate::request::HttpRequest;
|
pub use crate::request::HttpRequest;
|
||||||
pub use crate::resource::Resource;
|
pub use crate::resource::Resource;
|
||||||
pub use crate::responder::{Either, Responder};
|
pub use crate::responder::{Either, Responder};
|
||||||
|
pub use crate::route::Route;
|
||||||
pub use crate::service::{ServiceRequest, ServiceResponse};
|
pub use crate::service::{ServiceRequest, ServiceResponse};
|
||||||
pub use crate::state::State;
|
pub use crate::state::State;
|
||||||
|
|
||||||
|
pub mod web {
|
||||||
|
use actix_http::{http::Method, Error, Response};
|
||||||
|
use futures::IntoFuture;
|
||||||
|
|
||||||
|
use crate::handler::{AsyncFactory, Factory, FromRequest};
|
||||||
|
use crate::responder::Responder;
|
||||||
|
use crate::Route;
|
||||||
|
|
||||||
|
pub fn route<P: 'static>() -> Route<P> {
|
||||||
|
Route::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get<P: 'static>() -> Route<P> {
|
||||||
|
Route::get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post<P: 'static>() -> Route<P> {
|
||||||
|
Route::post()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn put<P: 'static>() -> Route<P> {
|
||||||
|
Route::put()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete<P: 'static>() -> Route<P> {
|
||||||
|
Route::delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn head<P: 'static>() -> Route<P> {
|
||||||
|
Route::new().method(Method::HEAD)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn method<P: 'static>(method: Method) -> Route<P> {
|
||||||
|
Route::new().method(method)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new route and add handler.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use actix_web::{web, App, HttpResponse};
|
||||||
|
///
|
||||||
|
/// fn index() -> HttpResponse {
|
||||||
|
/// unimplemented!()
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// App::new().resource("/", |r| r.route(web::to(index)));
|
||||||
|
/// ```
|
||||||
|
pub fn to<F, I, R, P: 'static>(handler: F) -> Route<P>
|
||||||
|
where
|
||||||
|
F: Factory<I, R> + 'static,
|
||||||
|
I: FromRequest<P> + 'static,
|
||||||
|
R: Responder + 'static,
|
||||||
|
{
|
||||||
|
Route::new().to(handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new route and add async handler.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use actix_web::{web, App, HttpResponse, Error};
|
||||||
|
///
|
||||||
|
/// fn index() -> impl futures::Future<Item=HttpResponse, Error=Error> {
|
||||||
|
/// futures::future::ok(HttpResponse::Ok().finish())
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// App::new().resource("/", |r| r.route(web::to_async(index)));
|
||||||
|
/// ```
|
||||||
|
pub fn to_async<F, I, R, P: 'static>(handler: F) -> Route<P>
|
||||||
|
where
|
||||||
|
F: AsyncFactory<I, R>,
|
||||||
|
I: FromRequest<P> + 'static,
|
||||||
|
R: IntoFuture + 'static,
|
||||||
|
R::Item: Into<Response>,
|
||||||
|
R::Error: Into<Error>,
|
||||||
|
{
|
||||||
|
Route::new().to_async(handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod dev {
|
pub mod dev {
|
||||||
pub use crate::app::AppRouter;
|
pub use crate::app::AppRouter;
|
||||||
pub use crate::handler::{AsyncFactory, Extract, Factory, Handle};
|
pub use crate::handler::{AsyncFactory, Extract, Factory, Handle};
|
||||||
pub use crate::route::{Route, RouteBuilder};
|
|
||||||
// pub use crate::info::ConnectionInfo;
|
// pub use crate::info::ConnectionInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@ use actix_router::{Path, Url};
|
||||||
use futures::future::{ok, FutureResult};
|
use futures::future::{ok, FutureResult};
|
||||||
|
|
||||||
use crate::handler::FromRequest;
|
use crate::handler::FromRequest;
|
||||||
use crate::service::ServiceRequest;
|
use crate::service::ServiceFromRequest;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct HttpRequest {
|
pub struct HttpRequest {
|
||||||
head: Message<RequestHead>,
|
pub(crate) head: Message<RequestHead>,
|
||||||
pub(crate) path: Path<Url>,
|
pub(crate) path: Path<Url>,
|
||||||
extensions: Rc<Extensions>,
|
extensions: Rc<Extensions>,
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ impl<P> FromRequest<P> for HttpRequest {
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = FutureResult<Self, Error>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
ok(req.clone())
|
ok(req.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use actix_http::{http::Method, Error, Response};
|
use actix_http::{Error, Response};
|
||||||
use actix_service::boxed::{self, BoxedNewService, BoxedService};
|
use actix_service::boxed::{self, BoxedNewService, BoxedService};
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
ApplyNewService, IntoNewService, IntoNewTransform, NewService, NewTransform, Service,
|
ApplyNewService, IntoNewService, IntoNewTransform, NewService, NewTransform, Service,
|
||||||
|
@ -11,7 +11,7 @@ use futures::{Async, Future, IntoFuture, Poll};
|
||||||
|
|
||||||
use crate::handler::{AsyncFactory, Factory, FromRequest};
|
use crate::handler::{AsyncFactory, Factory, FromRequest};
|
||||||
use crate::responder::Responder;
|
use crate::responder::Responder;
|
||||||
use crate::route::{CreateRouteService, Route, RouteBuilder, RouteService};
|
use crate::route::{CreateRouteService, Route, RouteService};
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceRequest, ServiceResponse};
|
||||||
|
|
||||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
||||||
|
@ -74,92 +74,8 @@ where
|
||||||
/// .finish();
|
/// .finish();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn route<F>(mut self, f: F) -> Self
|
pub fn route(mut self, route: Route<P>) -> Self {
|
||||||
where
|
self.routes.push(route);
|
||||||
F: FnOnce(RouteBuilder<P>) -> Route<P>,
|
|
||||||
{
|
|
||||||
self.routes.push(f(Route::build()));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a new `GET` route.
|
|
||||||
pub fn get<F, I, R>(mut self, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: Factory<I, R> + 'static,
|
|
||||||
I: FromRequest<P> + 'static,
|
|
||||||
R: Responder + 'static,
|
|
||||||
{
|
|
||||||
self.routes.push(Route::get().to(f));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a new `POST` route.
|
|
||||||
pub fn post<F, I, R>(mut self, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: Factory<I, R> + 'static,
|
|
||||||
I: FromRequest<P> + 'static,
|
|
||||||
R: Responder + 'static,
|
|
||||||
{
|
|
||||||
self.routes.push(Route::post().to(f));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a new `PUT` route.
|
|
||||||
pub fn put<F, I, R>(mut self, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: Factory<I, R> + 'static,
|
|
||||||
I: FromRequest<P> + 'static,
|
|
||||||
R: Responder + 'static,
|
|
||||||
{
|
|
||||||
self.routes.push(Route::put().to(f));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a new `DELETE` route.
|
|
||||||
pub fn delete<F, I, R>(mut self, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: Factory<I, R> + 'static,
|
|
||||||
I: FromRequest<P> + 'static,
|
|
||||||
R: Responder + 'static,
|
|
||||||
{
|
|
||||||
self.routes.push(Route::delete().to(f));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a new `HEAD` route.
|
|
||||||
pub fn head<F, I, R>(mut self, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: Factory<I, R> + 'static,
|
|
||||||
I: FromRequest<P> + 'static,
|
|
||||||
R: Responder + 'static,
|
|
||||||
{
|
|
||||||
self.routes.push(Route::build().method(Method::HEAD).to(f));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a new route and add method check to route.
|
|
||||||
///
|
|
||||||
/// ```rust,ignore
|
|
||||||
/// # extern crate actix_web;
|
|
||||||
/// use actix_web::*;
|
|
||||||
/// fn index(req: &HttpRequest) -> HttpResponse { unimplemented!() }
|
|
||||||
///
|
|
||||||
/// App::new().resource("/", |r| r.method(http::Method::GET).f(index));
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// This is shortcut for:
|
|
||||||
///
|
|
||||||
/// ```rust,ignore
|
|
||||||
/// # extern crate actix_web;
|
|
||||||
/// # use actix_web::*;
|
|
||||||
/// # fn index(req: &HttpRequest) -> HttpResponse { unimplemented!() }
|
|
||||||
/// App::new().resource("/", |r| r.route().filter(pred::Get()).f(index));
|
|
||||||
/// ```
|
|
||||||
pub fn method<F>(mut self, method: Method, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: FnOnce(RouteBuilder<P>) -> Route<P>,
|
|
||||||
{
|
|
||||||
self.routes.push(f(Route::build().method(method)));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +103,7 @@ where
|
||||||
I: FromRequest<P> + 'static,
|
I: FromRequest<P> + 'static,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
{
|
{
|
||||||
self.routes.push(Route::build().to(handler));
|
self.routes.push(Route::new().to(handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +143,7 @@ where
|
||||||
R::Item: Into<Response>,
|
R::Item: Into<Response>,
|
||||||
R::Error: Into<Error>,
|
R::Error: Into<Error>,
|
||||||
{
|
{
|
||||||
self.routes.push(Route::build().to_async(handler));
|
self.routes.push(Route::new().to_async(handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
79
src/route.rs
79
src/route.rs
|
@ -1,4 +1,3 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use actix_http::{http::Method, Error, Response};
|
use actix_http::{http::Method, Error, Response};
|
||||||
|
@ -8,7 +7,8 @@ use futures::{Async, Future, IntoFuture, Poll};
|
||||||
use crate::filter::{self, Filter};
|
use crate::filter::{self, Filter};
|
||||||
use crate::handler::{AsyncFactory, AsyncHandle, Extract, Factory, FromRequest, Handle};
|
use crate::handler::{AsyncFactory, AsyncHandle, Extract, Factory, FromRequest, Handle};
|
||||||
use crate::responder::Responder;
|
use crate::responder::Responder;
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceFromRequest, ServiceRequest, ServiceResponse};
|
||||||
|
use crate::HttpResponse;
|
||||||
|
|
||||||
type BoxedRouteService<Req, Res> = Box<
|
type BoxedRouteService<Req, Res> = Box<
|
||||||
Service<
|
Service<
|
||||||
|
@ -40,24 +40,29 @@ pub struct Route<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: 'static> Route<P> {
|
impl<P: 'static> Route<P> {
|
||||||
pub fn build() -> RouteBuilder<P> {
|
pub fn new() -> Route<P> {
|
||||||
RouteBuilder::new()
|
Route {
|
||||||
|
service: Box::new(RouteNewService::new(Extract::new().and_then(
|
||||||
|
Handle::new(|| HttpResponse::NotFound()).map_err(|_| panic!()),
|
||||||
|
))),
|
||||||
|
filters: Rc::new(Vec::new()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get() -> RouteBuilder<P> {
|
pub fn get() -> Route<P> {
|
||||||
RouteBuilder::new().method(Method::GET)
|
Route::new().method(Method::GET)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn post() -> RouteBuilder<P> {
|
pub fn post() -> Route<P> {
|
||||||
RouteBuilder::new().method(Method::POST)
|
Route::new().method(Method::POST)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put() -> RouteBuilder<P> {
|
pub fn put() -> Route<P> {
|
||||||
RouteBuilder::new().method(Method::PUT)
|
Route::new().method(Method::PUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete() -> RouteBuilder<P> {
|
pub fn delete() -> Route<P> {
|
||||||
RouteBuilder::new().method(Method::DELETE)
|
Route::new().method(Method::DELETE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +114,7 @@ pub struct RouteService<P> {
|
||||||
impl<P> RouteService<P> {
|
impl<P> RouteService<P> {
|
||||||
pub fn check(&self, req: &mut ServiceRequest<P>) -> bool {
|
pub fn check(&self, req: &mut ServiceRequest<P>) -> bool {
|
||||||
for f in self.filters.iter() {
|
for f in self.filters.iter() {
|
||||||
if !f.check(req.request()) {
|
if !f.check(req.head()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,19 +137,7 @@ impl<P> Service for RouteService<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RouteBuilder<P> {
|
impl<P: 'static> Route<P> {
|
||||||
filters: Vec<Box<Filter>>,
|
|
||||||
_t: PhantomData<P>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P: 'static> RouteBuilder<P> {
|
|
||||||
fn new() -> RouteBuilder<P> {
|
|
||||||
RouteBuilder {
|
|
||||||
filters: Vec::new(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add method match filter to the route.
|
/// Add method match filter to the route.
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
|
@ -161,7 +154,9 @@ impl<P: 'static> RouteBuilder<P> {
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn method(mut self, method: Method) -> Self {
|
pub fn method(mut self, method: Method) -> Self {
|
||||||
self.filters.push(Box::new(filter::Method(method)));
|
Rc::get_mut(&mut self.filters)
|
||||||
|
.unwrap()
|
||||||
|
.push(Box::new(filter::Method(method)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +176,7 @@ impl<P: 'static> RouteBuilder<P> {
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn filter<F: Filter + 'static>(mut self, f: F) -> Self {
|
pub fn filter<F: Filter + 'static>(mut self, f: F) -> Self {
|
||||||
self.filters.push(Box::new(f));
|
Rc::get_mut(&mut self.filters).unwrap().push(Box::new(f));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,18 +254,16 @@ impl<P: 'static> RouteBuilder<P> {
|
||||||
/// ); // <- use `with` extractor
|
/// ); // <- use `with` extractor
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn to<F, T, R>(self, handler: F) -> Route<P>
|
pub fn to<F, T, R>(mut self, handler: F) -> Route<P>
|
||||||
where
|
where
|
||||||
F: Factory<T, R> + 'static,
|
F: Factory<T, R> + 'static,
|
||||||
T: FromRequest<P> + 'static,
|
T: FromRequest<P> + 'static,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
{
|
{
|
||||||
Route {
|
self.service = Box::new(RouteNewService::new(
|
||||||
service: Box::new(RouteNewService::new(
|
|
||||||
Extract::new().and_then(Handle::new(handler).map_err(|_| panic!())),
|
Extract::new().and_then(Handle::new(handler).map_err(|_| panic!())),
|
||||||
)),
|
));
|
||||||
filters: Rc::new(self.filters),
|
self
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set async handler function, use request extractor for parameters.
|
/// Set async handler function, use request extractor for parameters.
|
||||||
|
@ -303,7 +296,7 @@ impl<P: 'static> RouteBuilder<P> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
pub fn to_async<F, T, R>(self, handler: F) -> Route<P>
|
pub fn to_async<F, T, R>(mut self, handler: F) -> Self
|
||||||
where
|
where
|
||||||
F: AsyncFactory<T, R>,
|
F: AsyncFactory<T, R>,
|
||||||
T: FromRequest<P> + 'static,
|
T: FromRequest<P> + 'static,
|
||||||
|
@ -311,12 +304,10 @@ impl<P: 'static> RouteBuilder<P> {
|
||||||
R::Item: Into<Response>,
|
R::Item: Into<Response>,
|
||||||
R::Error: Into<Error>,
|
R::Error: Into<Error>,
|
||||||
{
|
{
|
||||||
Route {
|
self.service = Box::new(RouteNewService::new(
|
||||||
service: Box::new(RouteNewService::new(
|
|
||||||
Extract::new().and_then(AsyncHandle::new(handler).map_err(|_| panic!())),
|
Extract::new().and_then(AsyncHandle::new(handler).map_err(|_| panic!())),
|
||||||
)),
|
));
|
||||||
filters: Rc::new(self.filters),
|
self
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +441,7 @@ impl<P: 'static> RouteBuilder<P> {
|
||||||
|
|
||||||
struct RouteNewService<P, T>
|
struct RouteNewService<P, T>
|
||||||
where
|
where
|
||||||
T: NewService<Request = ServiceRequest<P>, Error = (Error, ServiceRequest<P>)>,
|
T: NewService<Request = ServiceRequest<P>, Error = (Error, ServiceFromRequest<P>)>,
|
||||||
{
|
{
|
||||||
service: T,
|
service: T,
|
||||||
}
|
}
|
||||||
|
@ -460,7 +451,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (Error, ServiceRequest<P>),
|
Error = (Error, ServiceFromRequest<P>),
|
||||||
>,
|
>,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
T::Service: 'static,
|
T::Service: 'static,
|
||||||
|
@ -476,7 +467,7 @@ where
|
||||||
T: NewService<
|
T: NewService<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (Error, ServiceRequest<P>),
|
Error = (Error, ServiceFromRequest<P>),
|
||||||
>,
|
>,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
T::Service: 'static,
|
T::Service: 'static,
|
||||||
|
@ -513,7 +504,7 @@ where
|
||||||
T: Service<
|
T: Service<
|
||||||
Request = ServiceRequest<P>,
|
Request = ServiceRequest<P>,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = (Error, ServiceRequest<P>),
|
Error = (Error, ServiceFromRequest<P>),
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
type Request = ServiceRequest<P>;
|
type Request = ServiceRequest<P>;
|
||||||
|
|
151
src/service.rs
151
src/service.rs
|
@ -1,9 +1,11 @@
|
||||||
|
use std::cell::{Ref, RefMut};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use actix_http::body::{Body, MessageBody, ResponseBody};
|
use actix_http::body::{Body, MessageBody, ResponseBody};
|
||||||
use actix_http::http::HeaderMap;
|
use actix_http::http::{HeaderMap, Method, Uri, Version};
|
||||||
use actix_http::{
|
use actix_http::{
|
||||||
Error, Extensions, HttpMessage, Payload, Request, Response, ResponseHead,
|
Error, Extensions, HttpMessage, Payload, Request, RequestHead, Response,
|
||||||
|
ResponseHead,
|
||||||
};
|
};
|
||||||
use actix_router::{Path, Url};
|
use actix_router::{Path, Url};
|
||||||
|
|
||||||
|
@ -27,11 +29,6 @@ impl<P> ServiceRequest<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn request(&self) -> &HttpRequest {
|
|
||||||
&self.req
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_request(self) -> HttpRequest {
|
pub fn into_request(self) -> HttpRequest {
|
||||||
self.req
|
self.req
|
||||||
|
@ -49,10 +46,93 @@ impl<P> ServiceRequest<P> {
|
||||||
ServiceResponse::new(self.req, err.into().into())
|
ServiceResponse::new(self.req, err.into().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This method returns reference to the request head
|
||||||
|
#[inline]
|
||||||
|
pub fn head(&self) -> &RequestHead {
|
||||||
|
&self.req.head
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This method returns reference to the request head
|
||||||
|
#[inline]
|
||||||
|
pub fn head_mut(&mut self) -> &mut RequestHead {
|
||||||
|
&mut self.req.head
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request's uri.
|
||||||
|
#[inline]
|
||||||
|
pub fn uri(&self) -> &Uri {
|
||||||
|
&self.head().uri
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the Request method.
|
||||||
|
#[inline]
|
||||||
|
pub fn method(&self) -> &Method {
|
||||||
|
&self.head().method
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the Request Version.
|
||||||
|
#[inline]
|
||||||
|
pub fn version(&self) -> Version {
|
||||||
|
self.head().version
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The target path of this Request.
|
||||||
|
#[inline]
|
||||||
|
pub fn path(&self) -> &str {
|
||||||
|
self.head().uri.path()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Returns Request's headers.
|
||||||
|
pub fn headers(&self) -> &HeaderMap {
|
||||||
|
&self.head().headers
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The query string in the URL.
|
||||||
|
///
|
||||||
|
/// E.g., id=10
|
||||||
|
#[inline]
|
||||||
|
pub fn query_string(&self) -> &str {
|
||||||
|
if let Some(query) = self.uri().query().as_ref() {
|
||||||
|
query
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference to the Path parameters.
|
||||||
|
///
|
||||||
|
/// Params is a container for url parameters.
|
||||||
|
/// A variable segment is specified in the form `{identifier}`,
|
||||||
|
/// where the identifier can be used later in a request handler to
|
||||||
|
/// access the matched value for that segment.
|
||||||
|
#[inline]
|
||||||
|
pub fn match_info(&self) -> &Path<Url> {
|
||||||
|
&self.req.path
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn match_info_mut(&mut self) -> &mut Path<Url> {
|
pub fn match_info_mut(&mut self) -> &mut Path<Url> {
|
||||||
&mut self.req.path
|
&mut self.req.path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Request extensions
|
||||||
|
#[inline]
|
||||||
|
pub fn extensions(&self) -> Ref<Extensions> {
|
||||||
|
self.req.head.extensions()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutable reference to a the request's extensions
|
||||||
|
#[inline]
|
||||||
|
pub fn extensions_mut(&self) -> RefMut<Extensions> {
|
||||||
|
self.req.head.extensions_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Application extensions
|
||||||
|
#[inline]
|
||||||
|
pub fn app_extensions(&self) -> &Extensions {
|
||||||
|
self.req.app_extensions()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> HttpMessage for ServiceRequest<P> {
|
impl<P> HttpMessage for ServiceRequest<P> {
|
||||||
|
@ -70,10 +150,65 @@ impl<P> HttpMessage for ServiceRequest<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> std::ops::Deref for ServiceRequest<P> {
|
impl<P> std::ops::Deref for ServiceRequest<P> {
|
||||||
|
type Target = RequestHead;
|
||||||
|
|
||||||
|
fn deref(&self) -> &RequestHead {
|
||||||
|
self.req.head()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> std::ops::DerefMut for ServiceRequest<P> {
|
||||||
|
fn deref_mut(&mut self) -> &mut RequestHead {
|
||||||
|
self.head_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ServiceFromRequest<P> {
|
||||||
|
req: HttpRequest,
|
||||||
|
payload: Payload<P>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> ServiceFromRequest<P> {
|
||||||
|
#[inline]
|
||||||
|
pub fn into_request(self) -> HttpRequest {
|
||||||
|
self.req
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create service response for error
|
||||||
|
#[inline]
|
||||||
|
pub fn error_response<E: Into<Error>>(self, err: E) -> ServiceResponse {
|
||||||
|
ServiceResponse::new(self.req, err.into().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> std::ops::Deref for ServiceFromRequest<P> {
|
||||||
type Target = HttpRequest;
|
type Target = HttpRequest;
|
||||||
|
|
||||||
fn deref(&self) -> &HttpRequest {
|
fn deref(&self) -> &HttpRequest {
|
||||||
self.request()
|
&self.req
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> HttpMessage for ServiceFromRequest<P> {
|
||||||
|
type Stream = P;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn headers(&self) -> &HeaderMap {
|
||||||
|
self.req.headers()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn take_payload(&mut self) -> Payload<Self::Stream> {
|
||||||
|
std::mem::replace(&mut self.payload, Payload::None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> From<ServiceRequest<P>> for ServiceFromRequest<P> {
|
||||||
|
fn from(req: ServiceRequest<P>) -> Self {
|
||||||
|
Self {
|
||||||
|
req: req.req,
|
||||||
|
payload: req.payload,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use futures::future::{err, ok, FutureResult};
|
||||||
use futures::{Async, Future, IntoFuture, Poll};
|
use futures::{Async, Future, IntoFuture, Poll};
|
||||||
|
|
||||||
use crate::handler::FromRequest;
|
use crate::handler::FromRequest;
|
||||||
use crate::service::ServiceRequest;
|
use crate::service::ServiceFromRequest;
|
||||||
|
|
||||||
/// Application state factory
|
/// Application state factory
|
||||||
pub(crate) trait StateFactory {
|
pub(crate) trait StateFactory {
|
||||||
|
@ -50,7 +50,7 @@ impl<S: 'static, P> FromRequest<P> for State<S> {
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = FutureResult<Self, Error>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
if let Some(st) = req.app_extensions().get::<State<S>>() {
|
if let Some(st) = req.app_extensions().get::<State<S>>() {
|
||||||
ok(st.clone())
|
ok(st.clone())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use flate2::write::ZlibDecoder;
|
||||||
use futures::stream::once; //Future, Stream
|
use futures::stream::once; //Future, Stream
|
||||||
use rand::{distributions::Alphanumeric, Rng};
|
use rand::{distributions::Alphanumeric, Rng};
|
||||||
|
|
||||||
use actix_web::{middleware, App};
|
use actix_web::{middleware, web, App};
|
||||||
|
|
||||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||||
Hello World Hello World Hello World Hello World Hello World \
|
Hello World Hello World Hello World Hello World Hello World \
|
||||||
|
@ -40,7 +40,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||||
fn test_body() {
|
fn test_body() {
|
||||||
let mut srv = TestServer::new(|| {
|
let mut srv = TestServer::new(|| {
|
||||||
h1::H1Service::new(
|
h1::H1Service::new(
|
||||||
App::new().resource("/", |r| r.get(|| Response::Ok().body(STR))),
|
App::new().resource("/", |r| r.route(web::to(|| Response::Ok().body(STR)))),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ fn test_body_gzip() {
|
||||||
h1::H1Service::new(
|
h1::H1Service::new(
|
||||||
App::new()
|
App::new()
|
||||||
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
||||||
.resource("/", |r| r.get(|| Response::Ok().body(STR))),
|
.resource("/", |r| r.route(web::to(|| Response::Ok().body(STR)))),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -87,7 +87,9 @@ fn test_body_gzip_large() {
|
||||||
h1::H1Service::new(
|
h1::H1Service::new(
|
||||||
App::new()
|
App::new()
|
||||||
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
||||||
.resource("/", |r| r.get(move || Response::Ok().body(data.clone()))),
|
.resource("/", |r| {
|
||||||
|
r.route(web::to(move || Response::Ok().body(data.clone())))
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -118,7 +120,9 @@ fn test_body_gzip_large_random() {
|
||||||
h1::H1Service::new(
|
h1::H1Service::new(
|
||||||
App::new()
|
App::new()
|
||||||
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
||||||
.resource("/", |r| r.get(move || Response::Ok().body(data.clone()))),
|
.resource("/", |r| {
|
||||||
|
r.route(web::to(move || Response::Ok().body(data.clone())))
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -144,11 +148,11 @@ fn test_body_chunked_implicit() {
|
||||||
App::new()
|
App::new()
|
||||||
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
.middleware(middleware::Compress::new(ContentEncoding::Gzip))
|
||||||
.resource("/", |r| {
|
.resource("/", |r| {
|
||||||
r.get(move || {
|
r.route(web::get().to(move || {
|
||||||
Response::Ok().streaming(once(Ok::<_, Error>(
|
Response::Ok().streaming(once(Ok::<_, Error>(
|
||||||
Bytes::from_static(STR.as_ref()),
|
Bytes::from_static(STR.as_ref()),
|
||||||
)))
|
)))
|
||||||
})
|
}))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -178,11 +182,11 @@ fn test_body_br_streaming() {
|
||||||
App::new()
|
App::new()
|
||||||
.middleware(middleware::Compress::new(ContentEncoding::Br))
|
.middleware(middleware::Compress::new(ContentEncoding::Br))
|
||||||
.resource("/", |r| {
|
.resource("/", |r| {
|
||||||
r.get(move || {
|
r.route(web::to(move || {
|
||||||
Response::Ok().streaming(once(Ok::<_, Error>(
|
Response::Ok().streaming(once(Ok::<_, Error>(
|
||||||
Bytes::from_static(STR.as_ref()),
|
Bytes::from_static(STR.as_ref()),
|
||||||
)))
|
)))
|
||||||
})
|
}))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -205,7 +209,7 @@ fn test_body_br_streaming() {
|
||||||
fn test_head_binary() {
|
fn test_head_binary() {
|
||||||
let mut srv = TestServer::new(move || {
|
let mut srv = TestServer::new(move || {
|
||||||
h1::H1Service::new(App::new().resource("/", |r| {
|
h1::H1Service::new(App::new().resource("/", |r| {
|
||||||
r.head(move || Response::Ok().content_length(100).body(STR))
|
r.route(web::head().to(move || Response::Ok().content_length(100).body(STR)))
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -227,12 +231,12 @@ fn test_head_binary() {
|
||||||
fn test_no_chunking() {
|
fn test_no_chunking() {
|
||||||
let mut srv = TestServer::new(move || {
|
let mut srv = TestServer::new(move || {
|
||||||
h1::H1Service::new(App::new().resource("/", |r| {
|
h1::H1Service::new(App::new().resource("/", |r| {
|
||||||
r.get(move || {
|
r.route(web::to(move || {
|
||||||
Response::Ok()
|
Response::Ok()
|
||||||
.no_chunking()
|
.no_chunking()
|
||||||
.content_length(STR.len() as u64)
|
.content_length(STR.len() as u64)
|
||||||
.streaming(once(Ok::<_, Error>(Bytes::from_static(STR.as_ref()))))
|
.streaming(once(Ok::<_, Error>(Bytes::from_static(STR.as_ref()))))
|
||||||
})
|
}))
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -252,7 +256,7 @@ fn test_body_deflate() {
|
||||||
h1::H1Service::new(
|
h1::H1Service::new(
|
||||||
App::new()
|
App::new()
|
||||||
.middleware(middleware::Compress::new(ContentEncoding::Deflate))
|
.middleware(middleware::Compress::new(ContentEncoding::Deflate))
|
||||||
.resource("/", |r| r.get(move || Response::Ok().body(STR))),
|
.resource("/", |r| r.route(web::to(move || Response::Ok().body(STR)))),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -277,7 +281,7 @@ fn test_body_brotli() {
|
||||||
h1::H1Service::new(
|
h1::H1Service::new(
|
||||||
App::new()
|
App::new()
|
||||||
.middleware(middleware::Compress::new(ContentEncoding::Br))
|
.middleware(middleware::Compress::new(ContentEncoding::Br))
|
||||||
.resource("/", |r| r.get(move || Response::Ok().body(STR))),
|
.resource("/", |r| r.route(web::to(move || Response::Ok().body(STR)))),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue