mirror of
https://github.com/actix/actix-web.git
synced 2024-11-25 11:01:14 +00:00
rename .to_async() to .to()
This commit is contained in:
parent
0b9e3d381b
commit
8683ba8bb0
25 changed files with 232 additions and 396 deletions
|
@ -74,7 +74,7 @@ actix-service = "1.0.0-alpha.1"
|
|||
actix-utils = "0.5.0-alpha.1"
|
||||
actix-router = "0.1.5"
|
||||
actix-rt = "1.0.0-alpha.1"
|
||||
actix-web-codegen = "0.1.2"
|
||||
actix-web-codegen = "0.2.0-alpha.1"
|
||||
actix-http = "0.3.0-alpha.1"
|
||||
actix-server = "0.8.0-alpha.1"
|
||||
actix-server-config = "0.3.0-alpha.1"
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
## 2.0.0
|
||||
|
||||
* Sync handlers has been removed. `.to_async()` methtod has been renamed to `.to()`
|
||||
|
||||
replace `fn` with `async fn` to convert sync handler to async
|
||||
|
||||
|
||||
## 1.0.1
|
||||
|
||||
* Cors middleware has been moved to `actix-cors` crate
|
||||
|
|
|
@ -29,7 +29,7 @@ Actix web is a simple, pragmatic and extremely fast web framework for Rust.
|
|||
```rust
|
||||
use actix_web::{web, App, HttpServer, Responder};
|
||||
|
||||
fn index(info: web::Path<(u32, String)>) -> impl Responder {
|
||||
async fn index(info: web::Path<(u32, String)>) -> impl Responder {
|
||||
format!("Hello {}! id:{}", info.1, info.0)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
//! Http response
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::future::Future;
|
||||
use std::io::Write;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{fmt, str};
|
||||
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use futures::future::{ok, Ready};
|
||||
use futures::Stream;
|
||||
use futures::stream::Stream;
|
||||
use serde::Serialize;
|
||||
use serde_json;
|
||||
|
||||
|
@ -280,15 +283,20 @@ impl<B: MessageBody> fmt::Debug for Response<B> {
|
|||
}
|
||||
}
|
||||
|
||||
// impl IntoFuture for Response {
|
||||
// type Item = Response;
|
||||
// type Error = Error;
|
||||
// type Future = FutureResult<Response, Error>;
|
||||
impl Future for Response {
|
||||
type Output = Result<Response, Error>;
|
||||
|
||||
// fn into_future(self) -> Self::Future {
|
||||
// ok(self)
|
||||
// }
|
||||
// }
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
|
||||
Poll::Ready(Ok(Response {
|
||||
head: std::mem::replace(
|
||||
&mut self.head,
|
||||
BoxedResponseHead::new(StatusCode::OK),
|
||||
),
|
||||
body: self.body.take_body(),
|
||||
error: self.error.take(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CookieIter<'a> {
|
||||
iter: header::GetAll<'a>,
|
||||
|
@ -757,15 +765,13 @@ impl<'a> From<&'a ResponseHead> for ResponseBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
// impl IntoFuture for ResponseBuilder {
|
||||
// type Item = Response;
|
||||
// type Error = Error;
|
||||
// type Future = FutureResult<Response, Error>;
|
||||
impl Future for ResponseBuilder {
|
||||
type Output = Result<Response, Error>;
|
||||
|
||||
// fn into_future(mut self) -> Self::Future {
|
||||
// ok(self.finish())
|
||||
// }
|
||||
// }
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
|
||||
Poll::Ready(Ok(self.finish()))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ResponseBuilder {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
|
|
@ -13,7 +13,7 @@ enum ResourceType {
|
|||
impl ToTokens for ResourceType {
|
||||
fn to_tokens(&self, stream: &mut TokenStream2) {
|
||||
let ident = match self {
|
||||
ResourceType::Async => "to_async",
|
||||
ResourceType::Async => "to",
|
||||
ResourceType::Sync => "to",
|
||||
};
|
||||
let ident = Ident::new(ident, Span::call_site());
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use actix_web::{
|
||||
get, middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer,
|
||||
};
|
||||
use actix_web::{get, middleware, web, App, HttpRequest, HttpResponse, HttpServer};
|
||||
|
||||
#[get("/resource1/{name}/index.html")]
|
||||
fn index(req: HttpRequest, name: web::Path<String>) -> String {
|
||||
async fn index(req: HttpRequest, name: web::Path<String>) -> String {
|
||||
println!("REQ: {:?}", req);
|
||||
format!("Hello: {}!\r\n", name)
|
||||
}
|
||||
|
@ -14,7 +12,7 @@ async fn index_async(req: HttpRequest) -> &'static str {
|
|||
}
|
||||
|
||||
#[get("/")]
|
||||
fn no_params() -> &'static str {
|
||||
async fn no_params() -> &'static str {
|
||||
"Hello world!\r\n"
|
||||
}
|
||||
|
||||
|
@ -37,9 +35,9 @@ fn main() -> std::io::Result<()> {
|
|||
.default_service(
|
||||
web::route().to(|| HttpResponse::MethodNotAllowed()),
|
||||
)
|
||||
.route(web::get().to_async(index_async)),
|
||||
.route(web::get().to(index_async)),
|
||||
)
|
||||
.service(web::resource("/test1.html").to(|| "Test\r\n"))
|
||||
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))
|
||||
})
|
||||
.bind("127.0.0.1:8080")?
|
||||
.workers(1)
|
||||
|
|
|
@ -3,7 +3,7 @@ use actix_web::{
|
|||
};
|
||||
|
||||
#[get("/resource1/{name}/index.html")]
|
||||
fn index(req: HttpRequest, name: web::Path<String>) -> String {
|
||||
async fn index(req: HttpRequest, name: web::Path<String>) -> String {
|
||||
println!("REQ: {:?}", req);
|
||||
format!("Hello: {}!\r\n", name)
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ async fn index_async(req: HttpRequest) -> Result<&'static str, Error> {
|
|||
}
|
||||
|
||||
#[get("/")]
|
||||
fn no_params() -> &'static str {
|
||||
async fn no_params() -> &'static str {
|
||||
"Hello world!\r\n"
|
||||
}
|
||||
|
||||
#[cfg(feature = "uds")]
|
||||
#[cfg(unix)]
|
||||
fn main() -> std::io::Result<()> {
|
||||
std::env::set_var("RUST_LOG", "actix_server=info,actix_web=info");
|
||||
env_logger::init();
|
||||
|
@ -27,7 +27,7 @@ fn main() -> std::io::Result<()> {
|
|||
App::new()
|
||||
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
|
||||
.wrap(middleware::Compress::default())
|
||||
// .wrap(middleware::Logger::default())
|
||||
.wrap(middleware::Logger::default())
|
||||
.service(index)
|
||||
.service(no_params)
|
||||
.service(
|
||||
|
@ -36,16 +36,16 @@ fn main() -> std::io::Result<()> {
|
|||
middleware::DefaultHeaders::new().header("X-Version-R2", "0.3"),
|
||||
)
|
||||
.default_service(
|
||||
web::route().to(|| ok(HttpResponse::MethodNotAllowed())),
|
||||
web::route().to(|| HttpResponse::MethodNotAllowed()),
|
||||
)
|
||||
.route(web::get().to_async(index_async)),
|
||||
.route(web::get().to(index_async)),
|
||||
)
|
||||
.service(web::resource("/test1.html").to(|| "Test\r\n"))
|
||||
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))
|
||||
})
|
||||
.bind_uds("/Users/fafhrd91/uds-test")?
|
||||
.workers(1)
|
||||
.run()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "uds"))]
|
||||
#[cfg(not(unix))]
|
||||
fn main() {}
|
||||
|
|
12
src/app.rs
12
src/app.rs
|
@ -90,7 +90,7 @@ where
|
|||
/// counter: Cell<usize>,
|
||||
/// }
|
||||
///
|
||||
/// fn index(data: web::Data<MyData>) {
|
||||
/// async fn index(data: web::Data<MyData>) {
|
||||
/// data.counter.set(data.counter.get() + 1);
|
||||
/// }
|
||||
///
|
||||
|
@ -192,7 +192,7 @@ where
|
|||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -247,7 +247,7 @@ where
|
|||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -302,7 +302,7 @@ where
|
|||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpRequest, HttpResponse, Result};
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> Result<HttpResponse> {
|
||||
/// async fn index(req: HttpRequest) -> Result<HttpResponse> {
|
||||
/// let url = req.url_for("youtube", &["asdlkjqme"])?;
|
||||
/// assert_eq!(url.as_str(), "https://youtube.com/watch/asdlkjqme");
|
||||
/// Ok(HttpResponse::Ok().into())
|
||||
|
@ -346,7 +346,7 @@ where
|
|||
/// use actix_web::{middleware, web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -404,7 +404,7 @@ where
|
|||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -45,7 +45,7 @@ pub(crate) trait DataFactory {
|
|||
/// }
|
||||
///
|
||||
/// /// Use `Data<T>` extractor to access data in handler.
|
||||
/// fn index(data: web::Data<Mutex<MyData>>) {
|
||||
/// async fn index(data: web::Data<Mutex<MyData>>) {
|
||||
/// let mut data = data.lock().unwrap();
|
||||
/// data.counter += 1;
|
||||
/// }
|
||||
|
|
|
@ -75,7 +75,7 @@ pub trait FromRequest: Sized {
|
|||
/// }
|
||||
///
|
||||
/// /// extract `Thing` from request
|
||||
/// fn index(supplied_thing: Option<Thing>) -> String {
|
||||
/// async fn index(supplied_thing: Option<Thing>) -> String {
|
||||
/// match supplied_thing {
|
||||
/// // Puns not intended
|
||||
/// Some(thing) => format!("Got something: {:?}", thing),
|
||||
|
@ -146,7 +146,7 @@ where
|
|||
/// }
|
||||
///
|
||||
/// /// extract `Thing` from request
|
||||
/// fn index(supplied_thing: Result<Thing>) -> String {
|
||||
/// async fn index(supplied_thing: Result<Thing>) -> String {
|
||||
/// match supplied_thing {
|
||||
/// Ok(thing) => format!("Got thing: {:?}", thing),
|
||||
/// Err(e) => format!("Error extracting thing: {}", e)
|
||||
|
|
146
src/handler.rs
146
src/handler.rs
|
@ -15,111 +15,8 @@ use crate::request::HttpRequest;
|
|||
use crate::responder::Responder;
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
|
||||
/// Handler converter factory
|
||||
pub trait Factory<T, R>: Clone
|
||||
where
|
||||
R: Responder,
|
||||
{
|
||||
fn call(&self, param: T) -> R;
|
||||
}
|
||||
|
||||
impl<F, R> Factory<(), R> for F
|
||||
where
|
||||
F: Fn() -> R + Clone,
|
||||
R: Responder,
|
||||
{
|
||||
fn call(&self, _: ()) -> R {
|
||||
(self)()
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct Handler<F, T, R>
|
||||
where
|
||||
F: Factory<T, R>,
|
||||
R: Responder,
|
||||
{
|
||||
hnd: F,
|
||||
_t: PhantomData<(T, R)>,
|
||||
}
|
||||
|
||||
impl<F, T, R> Handler<F, T, R>
|
||||
where
|
||||
F: Factory<T, R>,
|
||||
R: Responder,
|
||||
{
|
||||
pub fn new(hnd: F) -> Self {
|
||||
Handler {
|
||||
hnd,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, T, R> Clone for Handler<F, T, R>
|
||||
where
|
||||
F: Factory<T, R>,
|
||||
R: Responder,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
hnd: self.hnd.clone(),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, T, R> Service for Handler<F, T, R>
|
||||
where
|
||||
F: Factory<T, R>,
|
||||
R: Responder,
|
||||
{
|
||||
type Request = (T, HttpRequest);
|
||||
type Response = ServiceResponse;
|
||||
type Error = Infallible;
|
||||
type Future = HandlerServiceResponse<R>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, (param, req): (T, HttpRequest)) -> Self::Future {
|
||||
let fut = self.hnd.call(param).respond_to(&req);
|
||||
HandlerServiceResponse {
|
||||
fut,
|
||||
req: Some(req),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
pub struct HandlerServiceResponse<T: Responder> {
|
||||
#[pin]
|
||||
fut: T::Future,
|
||||
req: Option<HttpRequest>,
|
||||
}
|
||||
|
||||
impl<T: Responder> Future for HandlerServiceResponse<T> {
|
||||
type Output = Result<ServiceResponse, Infallible>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
let this = self.project();
|
||||
|
||||
match this.fut.poll(cx) {
|
||||
Poll::Ready(Ok(res)) => {
|
||||
Poll::Ready(Ok(ServiceResponse::new(this.req.take().unwrap(), res)))
|
||||
}
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(Err(e)) => {
|
||||
let res: Response = e.into().into();
|
||||
Poll::Ready(Ok(ServiceResponse::new(this.req.take().unwrap(), res)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Async handler converter factory
|
||||
pub trait AsyncFactory<T, R, O>: Clone + 'static
|
||||
pub trait Factory<T, R, O>: Clone + 'static
|
||||
where
|
||||
R: Future<Output = O>,
|
||||
O: Responder,
|
||||
|
@ -127,7 +24,7 @@ where
|
|||
fn call(&self, param: T) -> R;
|
||||
}
|
||||
|
||||
impl<F, R, O> AsyncFactory<(), R, O> for F
|
||||
impl<F, R, O> Factory<(), R, O> for F
|
||||
where
|
||||
F: Fn() -> R + Clone + 'static,
|
||||
R: Future<Output = O>,
|
||||
|
@ -139,9 +36,9 @@ where
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct AsyncHandler<F, T, R, O>
|
||||
pub struct Handler<F, T, R, O>
|
||||
where
|
||||
F: AsyncFactory<T, R, O>,
|
||||
F: Factory<T, R, O>,
|
||||
R: Future<Output = O>,
|
||||
O: Responder,
|
||||
{
|
||||
|
@ -149,51 +46,51 @@ where
|
|||
_t: PhantomData<(T, R, O)>,
|
||||
}
|
||||
|
||||
impl<F, T, R, O> AsyncHandler<F, T, R, O>
|
||||
impl<F, T, R, O> Handler<F, T, R, O>
|
||||
where
|
||||
F: AsyncFactory<T, R, O>,
|
||||
F: Factory<T, R, O>,
|
||||
R: Future<Output = O>,
|
||||
O: Responder,
|
||||
{
|
||||
pub fn new(hnd: F) -> Self {
|
||||
AsyncHandler {
|
||||
Handler {
|
||||
hnd,
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, T, R, O> Clone for AsyncHandler<F, T, R, O>
|
||||
impl<F, T, R, O> Clone for Handler<F, T, R, O>
|
||||
where
|
||||
F: AsyncFactory<T, R, O>,
|
||||
F: Factory<T, R, O>,
|
||||
R: Future<Output = O>,
|
||||
O: Responder,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
AsyncHandler {
|
||||
Handler {
|
||||
hnd: self.hnd.clone(),
|
||||
_t: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, T, R, O> Service for AsyncHandler<F, T, R, O>
|
||||
impl<F, T, R, O> Service for Handler<F, T, R, O>
|
||||
where
|
||||
F: AsyncFactory<T, R, O>,
|
||||
F: Factory<T, R, O>,
|
||||
R: Future<Output = O>,
|
||||
O: Responder,
|
||||
{
|
||||
type Request = (T, HttpRequest);
|
||||
type Response = ServiceResponse;
|
||||
type Error = Infallible;
|
||||
type Future = AsyncHandlerServiceResponse<R, O>;
|
||||
type Future = HandlerServiceResponse<R, O>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, (param, req): (T, HttpRequest)) -> Self::Future {
|
||||
AsyncHandlerServiceResponse {
|
||||
HandlerServiceResponse {
|
||||
fut: self.hnd.call(param),
|
||||
fut2: None,
|
||||
req: Some(req),
|
||||
|
@ -203,7 +100,7 @@ where
|
|||
|
||||
#[doc(hidden)]
|
||||
#[pin_project]
|
||||
pub struct AsyncHandlerServiceResponse<T, R>
|
||||
pub struct HandlerServiceResponse<T, R>
|
||||
where
|
||||
T: Future<Output = R>,
|
||||
R: Responder,
|
||||
|
@ -215,7 +112,7 @@ where
|
|||
req: Option<HttpRequest>,
|
||||
}
|
||||
|
||||
impl<T, R> Future for AsyncHandlerServiceResponse<T, R>
|
||||
impl<T, R> Future for HandlerServiceResponse<T, R>
|
||||
where
|
||||
T: Future<Output = R>,
|
||||
R: Responder,
|
||||
|
@ -366,16 +263,7 @@ where
|
|||
|
||||
/// FromRequest trait impl for tuples
|
||||
macro_rules! factory_tuple ({ $(($n:tt, $T:ident)),+} => {
|
||||
impl<Func, $($T,)+ Res> Factory<($($T,)+), Res> for Func
|
||||
where Func: Fn($($T,)+) -> Res + Clone,
|
||||
Res: Responder,
|
||||
{
|
||||
fn call(&self, param: ($($T,)+)) -> Res {
|
||||
(self)($(param.$n,)+)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Func, $($T,)+ Res, O> AsyncFactory<($($T,)+), Res, O> for Func
|
||||
impl<Func, $($T,)+ Res, O> Factory<($($T,)+), Res, O> for Func
|
||||
where Func: Fn($($T,)+) -> Res + Clone + 'static,
|
||||
Res: Future<Output = O>,
|
||||
O: Responder,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
//! use actix_web::{web, App, Responder, HttpServer};
|
||||
//! # use std::thread;
|
||||
//!
|
||||
//! fn index(info: web::Path<(String, u32)>) -> impl Responder {
|
||||
//! async fn index(info: web::Path<(String, u32)>) -> impl Responder {
|
||||
//! format!("Hello {}! id:{}", info.0, info.1)
|
||||
//! }
|
||||
//!
|
||||
|
@ -136,7 +136,7 @@ pub mod dev {
|
|||
|
||||
pub use crate::config::{AppConfig, AppService};
|
||||
#[doc(hidden)]
|
||||
pub use crate::handler::{AsyncFactory, Factory};
|
||||
pub use crate::handler::Factory;
|
||||
pub use crate::info::ConnectionInfo;
|
||||
pub use crate::rmap::ResourceMap;
|
||||
pub use crate::service::{
|
||||
|
|
|
@ -276,7 +276,7 @@ impl Drop for HttpRequest {
|
|||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// /// extract `Thing` from request
|
||||
/// fn index(req: HttpRequest) -> String {
|
||||
/// async fn index(req: HttpRequest) -> String {
|
||||
/// format!("Got thing: {:?}", req)
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::data::Data;
|
|||
use crate::dev::{insert_slash, AppService, HttpServiceFactory, ResourceDef};
|
||||
use crate::extract::FromRequest;
|
||||
use crate::guard::Guard;
|
||||
use crate::handler::{AsyncFactory, Factory};
|
||||
use crate::handler::Factory;
|
||||
use crate::responder::Responder;
|
||||
use crate::route::{CreateRouteService, Route, RouteService};
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
|
@ -98,7 +98,7 @@ where
|
|||
/// ```rust
|
||||
/// use actix_web::{web, guard, App, HttpResponse};
|
||||
///
|
||||
/// fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -156,9 +156,9 @@ where
|
|||
/// .route(web::delete().to(delete_handler))
|
||||
/// );
|
||||
/// }
|
||||
/// # fn get_handler() {}
|
||||
/// # fn post_handler() {}
|
||||
/// # fn delete_handler() {}
|
||||
/// # async fn get_handler() -> impl actix_web::Responder { HttpResponse::Ok() }
|
||||
/// # async fn post_handler() -> impl actix_web::Responder { HttpResponse::Ok() }
|
||||
/// # async fn delete_handler() -> impl actix_web::Responder { HttpResponse::Ok() }
|
||||
/// ```
|
||||
pub fn route(mut self, route: Route) -> Self {
|
||||
self.routes.push(route);
|
||||
|
@ -174,7 +174,7 @@ where
|
|||
/// use actix_web::{web, App, FromRequest};
|
||||
///
|
||||
/// /// extract text data from request
|
||||
/// fn index(body: String) -> String {
|
||||
/// async fn index(body: String) -> String {
|
||||
/// format!("Body {}!", body)
|
||||
/// }
|
||||
///
|
||||
|
@ -230,46 +230,14 @@ where
|
|||
/// # fn index(req: HttpRequest) -> HttpResponse { unimplemented!() }
|
||||
/// App::new().service(web::resource("/").route(web::route().to(index)));
|
||||
/// ```
|
||||
pub fn to<F, I, R>(mut self, handler: F) -> Self
|
||||
pub fn to<F, I, R, U>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: Factory<I, R> + 'static,
|
||||
I: FromRequest + 'static,
|
||||
R: Responder + 'static,
|
||||
{
|
||||
self.routes.push(Route::new().to(handler));
|
||||
self
|
||||
}
|
||||
|
||||
/// Register a new route and add async handler.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::*;
|
||||
///
|
||||
/// async fn index(req: HttpRequest) -> Result<HttpResponse, Error> {
|
||||
/// Ok(HttpResponse::Ok().finish())
|
||||
/// }
|
||||
///
|
||||
/// App::new().service(web::resource("/").to_async(index));
|
||||
/// ```
|
||||
///
|
||||
/// This is shortcut for:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use actix_web::*;
|
||||
/// # async fn index(req: HttpRequest) -> Result<HttpResponse, Error> {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// App::new().service(web::resource("/").route(web::route().to_async(index)));
|
||||
/// ```
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn to_async<F, I, R, U>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: AsyncFactory<I, R, U>,
|
||||
F: Factory<I, R, U>,
|
||||
I: FromRequest + 'static,
|
||||
R: Future<Output = U> + 'static,
|
||||
U: Responder + 'static,
|
||||
{
|
||||
self.routes.push(Route::new().to_async(handler));
|
||||
self.routes.push(Route::new().to(handler));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -327,7 +295,7 @@ where
|
|||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -705,17 +673,16 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_async() {
|
||||
fn test_to() {
|
||||
block_on(async {
|
||||
let mut srv = init_service(App::new().service(
|
||||
web::resource("/test").to_async(|| {
|
||||
let mut srv =
|
||||
init_service(App::new().service(web::resource("/test").to(|| {
|
||||
async {
|
||||
delay_for(Duration::from_millis(100)).await;
|
||||
Ok::<_, Error>(HttpResponse::Ok())
|
||||
}
|
||||
}),
|
||||
))
|
||||
.await;
|
||||
})))
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = call_service(&mut srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
|
|
@ -475,9 +475,10 @@ pub(crate) mod tests {
|
|||
let mut srv = init_service(
|
||||
App::new()
|
||||
.service(
|
||||
web::resource("/none").to(|| -> Option<&'static str> { None }),
|
||||
web::resource("/none")
|
||||
.to(|| async { Option::<&'static str>::None }),
|
||||
)
|
||||
.service(web::resource("/some").to(|| Some("some"))),
|
||||
.service(web::resource("/some").to(|| async { Some("some") })),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
|
65
src/route.rs
65
src/route.rs
|
@ -5,11 +5,11 @@ use std::task::{Context, Poll};
|
|||
|
||||
use actix_http::{http::Method, Error};
|
||||
use actix_service::{Service, ServiceFactory};
|
||||
use futures::future::{ok, Either, FutureExt, LocalBoxFuture, Ready};
|
||||
use futures::future::{ok, ready, Either, FutureExt, LocalBoxFuture, Ready};
|
||||
|
||||
use crate::extract::FromRequest;
|
||||
use crate::guard::{self, Guard};
|
||||
use crate::handler::{AsyncFactory, AsyncHandler, Extract, Factory, Handler};
|
||||
use crate::handler::{Extract, Factory, Handler};
|
||||
use crate::responder::Responder;
|
||||
use crate::service::{ServiceRequest, ServiceResponse};
|
||||
use crate::HttpResponse;
|
||||
|
@ -49,7 +49,7 @@ impl Route {
|
|||
pub fn new() -> Route {
|
||||
Route {
|
||||
service: Box::new(RouteNewService::new(Extract::new(Handler::new(|| {
|
||||
HttpResponse::NotFound()
|
||||
ready(HttpResponse::NotFound())
|
||||
})))),
|
||||
guards: Rc::new(Vec::new()),
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ impl Route {
|
|||
/// }
|
||||
///
|
||||
/// /// extract path info using serde
|
||||
/// fn index(info: web::Path<Info>) -> String {
|
||||
/// async fn index(info: web::Path<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
|
@ -212,7 +212,7 @@ impl Route {
|
|||
/// }
|
||||
///
|
||||
/// /// extract path info using serde
|
||||
/// fn index(path: web::Path<Info>, query: web::Query<HashMap<String, String>>, body: web::Json<Info>) -> String {
|
||||
/// async fn index(path: web::Path<Info>, query: web::Query<HashMap<String, String>>, body: web::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", path.username)
|
||||
/// }
|
||||
///
|
||||
|
@ -223,52 +223,15 @@ impl Route {
|
|||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
pub fn to<F, T, R>(mut self, handler: F) -> Route
|
||||
pub fn to<F, T, R, U>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: Factory<T, R> + 'static,
|
||||
T: FromRequest + 'static,
|
||||
R: Responder + 'static,
|
||||
{
|
||||
self.service =
|
||||
Box::new(RouteNewService::new(Extract::new(Handler::new(handler))));
|
||||
self
|
||||
}
|
||||
|
||||
/// Set async handler function, use request extractors for parameters.
|
||||
/// This method has to be used if your handler function returns `impl Future<>`
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, Error};
|
||||
/// use serde_derive::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Info {
|
||||
/// username: String,
|
||||
/// }
|
||||
///
|
||||
/// /// extract path info using serde
|
||||
/// async fn index(info: web::Path<Info>) -> Result<&'static str, Error> {
|
||||
/// Ok("Hello World!")
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/{username}/index.html") // <- define path parameters
|
||||
/// .route(web::get().to_async(index)) // <- register async handler
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn to_async<F, T, R, U>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: AsyncFactory<T, R, U>,
|
||||
F: Factory<T, R, U>,
|
||||
T: FromRequest + 'static,
|
||||
R: Future<Output = U> + 'static,
|
||||
U: Responder + 'static,
|
||||
{
|
||||
self.service = Box::new(RouteNewService::new(Extract::new(AsyncHandler::new(
|
||||
handler,
|
||||
))));
|
||||
self.service =
|
||||
Box::new(RouteNewService::new(Extract::new(Handler::new(handler))));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -402,22 +365,24 @@ mod tests {
|
|||
web::resource("/test")
|
||||
.route(web::get().to(|| HttpResponse::Ok()))
|
||||
.route(web::put().to(|| {
|
||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||
async {
|
||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||
}
|
||||
}))
|
||||
.route(web::post().to_async(|| {
|
||||
.route(web::post().to(|| {
|
||||
async {
|
||||
delay_for(Duration::from_millis(100)).await;
|
||||
HttpResponse::Created()
|
||||
}
|
||||
}))
|
||||
.route(web::delete().to_async(|| {
|
||||
.route(web::delete().to(|| {
|
||||
async {
|
||||
delay_for(Duration::from_millis(100)).await;
|
||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||
}
|
||||
})),
|
||||
)
|
||||
.service(web::resource("/json").route(web::get().to_async(|| {
|
||||
.service(web::resource("/json").route(web::get().to(|| {
|
||||
async {
|
||||
delay_for(Duration::from_millis(25)).await;
|
||||
web::Json(MyObject {
|
||||
|
|
60
src/scope.rs
60
src/scope.rs
|
@ -46,7 +46,7 @@ type BoxedResponse = LocalBoxFuture<'static, Result<ServiceResponse, Error>>;
|
|||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// web::scope("/{project_id}/")
|
||||
/// .service(web::resource("/path1").to(|| HttpResponse::Ok()))
|
||||
/// .service(web::resource("/path1").to(|| async { HttpResponse::Ok() }))
|
||||
/// .service(web::resource("/path2").route(web::get().to(|| HttpResponse::Ok())))
|
||||
/// .service(web::resource("/path3").route(web::head().to(|| HttpResponse::MethodNotAllowed())))
|
||||
/// );
|
||||
|
@ -101,7 +101,7 @@ where
|
|||
/// ```rust
|
||||
/// use actix_web::{web, guard, App, HttpRequest, HttpResponse};
|
||||
///
|
||||
/// fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -132,7 +132,7 @@ where
|
|||
/// counter: Cell<usize>,
|
||||
/// }
|
||||
///
|
||||
/// fn index(data: web::Data<MyData>) {
|
||||
/// async fn index(data: web::Data<MyData>) {
|
||||
/// data.counter.set(data.counter.get() + 1);
|
||||
/// }
|
||||
///
|
||||
|
@ -228,7 +228,7 @@ where
|
|||
///
|
||||
/// struct AppState;
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> &'static str {
|
||||
/// async fn index(req: HttpRequest) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -258,7 +258,7 @@ where
|
|||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
///
|
||||
/// fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// async fn index(data: web::Path<(String, String)>) -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -356,7 +356,7 @@ where
|
|||
/// use actix_web::{web, App};
|
||||
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
|
||||
///
|
||||
/// fn index() -> &'static str {
|
||||
/// async fn index() -> &'static str {
|
||||
/// "Welcome!"
|
||||
/// }
|
||||
///
|
||||
|
@ -846,8 +846,10 @@ mod tests {
|
|||
let mut srv =
|
||||
init_service(App::new().service(web::scope("/ab-{project}").service(
|
||||
web::resource("/path1").to(|r: HttpRequest| {
|
||||
HttpResponse::Ok()
|
||||
.body(format!("project: {}", &r.match_info()["project"]))
|
||||
async move {
|
||||
HttpResponse::Ok()
|
||||
.body(format!("project: {}", &r.match_info()["project"]))
|
||||
}
|
||||
}),
|
||||
)))
|
||||
.await;
|
||||
|
@ -962,8 +964,12 @@ mod tests {
|
|||
let mut srv = init_service(App::new().service(web::scope("/app").service(
|
||||
web::scope("/{project_id}").service(web::resource("/path1").to(
|
||||
|r: HttpRequest| {
|
||||
HttpResponse::Created()
|
||||
.body(format!("project: {}", &r.match_info()["project_id"]))
|
||||
async move {
|
||||
HttpResponse::Created().body(format!(
|
||||
"project: {}",
|
||||
&r.match_info()["project_id"]
|
||||
))
|
||||
}
|
||||
},
|
||||
)),
|
||||
)))
|
||||
|
@ -989,11 +995,13 @@ mod tests {
|
|||
let mut srv = init_service(App::new().service(web::scope("/app").service(
|
||||
web::scope("/{project}").service(web::scope("/{id}").service(
|
||||
web::resource("/path1").to(|r: HttpRequest| {
|
||||
HttpResponse::Created().body(format!(
|
||||
"project: {} - {}",
|
||||
&r.match_info()["project"],
|
||||
&r.match_info()["id"],
|
||||
))
|
||||
async move {
|
||||
HttpResponse::Created().body(format!(
|
||||
"project: {} - {}",
|
||||
&r.match_info()["project"],
|
||||
&r.match_info()["id"],
|
||||
))
|
||||
}
|
||||
}),
|
||||
)),
|
||||
)))
|
||||
|
@ -1241,12 +1249,14 @@ mod tests {
|
|||
s.route(
|
||||
"/",
|
||||
web::get().to(|req: HttpRequest| {
|
||||
HttpResponse::Ok().body(format!(
|
||||
"{}",
|
||||
req.url_for("youtube", &["xxxxxx"])
|
||||
.unwrap()
|
||||
.as_str()
|
||||
))
|
||||
async move {
|
||||
HttpResponse::Ok().body(format!(
|
||||
"{}",
|
||||
req.url_for("youtube", &["xxxxxx"])
|
||||
.unwrap()
|
||||
.as_str()
|
||||
))
|
||||
}
|
||||
}),
|
||||
);
|
||||
}));
|
||||
|
@ -1267,8 +1277,12 @@ mod tests {
|
|||
let mut srv = init_service(App::new().service(web::scope("/a").service(
|
||||
web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(
|
||||
web::get().to(|req: HttpRequest| {
|
||||
HttpResponse::Ok()
|
||||
.body(format!("{}", req.url_for("c", &["12345"]).unwrap()))
|
||||
async move {
|
||||
HttpResponse::Ok().body(format!(
|
||||
"{}",
|
||||
req.url_for("c", &["12345"]).unwrap()
|
||||
))
|
||||
}
|
||||
}),
|
||||
)),
|
||||
)))
|
||||
|
|
76
src/test.rs
76
src/test.rs
|
@ -55,7 +55,7 @@ pub fn default_service(
|
|||
/// fn test_init_service() {
|
||||
/// let mut app = test::init_service(
|
||||
/// App::new()
|
||||
/// .service(web::resource("/test").to(|| HttpResponse::Ok()))
|
||||
/// .service(web::resource("/test").to(|| async { HttpResponse::Ok() }))
|
||||
/// );
|
||||
///
|
||||
/// // Create request object
|
||||
|
@ -94,14 +94,16 @@ where
|
|||
/// fn test_response() {
|
||||
/// let mut app = test::init_service(
|
||||
/// App::new()
|
||||
/// .service(web::resource("/test").to(|| HttpResponse::Ok()))
|
||||
/// );
|
||||
/// .service(web::resource("/test").to(|| async {
|
||||
/// HttpResponse::Ok()
|
||||
/// }))
|
||||
/// ).await;
|
||||
///
|
||||
/// // Create request object
|
||||
/// let req = test::TestRequest::with_uri("/test").to_request();
|
||||
///
|
||||
/// // Call application
|
||||
/// let resp = test::call_service(&mut app, req);
|
||||
/// let resp = test::call_service(&mut app, req).await;
|
||||
/// assert_eq!(resp.status(), StatusCode::OK);
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -125,15 +127,17 @@ where
|
|||
/// let mut app = test::init_service(
|
||||
/// App::new().service(
|
||||
/// web::resource("/index.html")
|
||||
/// .route(web::post().to(
|
||||
/// || HttpResponse::Ok().body("welcome!")))));
|
||||
/// .route(web::post().to(|| async {
|
||||
/// HttpResponse::Ok().body("welcome!")
|
||||
/// })))
|
||||
/// ).await;
|
||||
///
|
||||
/// let req = test::TestRequest::post()
|
||||
/// .uri("/index.html")
|
||||
/// .header(header::CONTENT_TYPE, "application/json")
|
||||
/// .to_request();
|
||||
///
|
||||
/// let result = test::read_response(&mut app, req);
|
||||
/// let result = test::read_response(&mut app, req).await;
|
||||
/// assert_eq!(result, Bytes::from_static(b"welcome!"));
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -167,15 +171,17 @@ where
|
|||
/// let mut app = test::init_service(
|
||||
/// App::new().service(
|
||||
/// web::resource("/index.html")
|
||||
/// .route(web::post().to(
|
||||
/// || HttpResponse::Ok().body("welcome!")))));
|
||||
/// .route(web::post().to(|| async {
|
||||
/// HttpResponse::Ok().body("welcome!")
|
||||
/// })))
|
||||
/// ).await;
|
||||
///
|
||||
/// let req = test::TestRequest::post()
|
||||
/// .uri("/index.html")
|
||||
/// .header(header::CONTENT_TYPE, "application/json")
|
||||
/// .to_request();
|
||||
///
|
||||
/// let resp = test::call_service(&mut app, req);
|
||||
/// let resp = test::call_service(&mut app, req).await;
|
||||
/// let result = test::read_body(resp);
|
||||
/// assert_eq!(result, Bytes::from_static(b"welcome!"));
|
||||
/// }
|
||||
|
@ -221,10 +227,11 @@ where
|
|||
/// let mut app = test::init_service(
|
||||
/// App::new().service(
|
||||
/// web::resource("/people")
|
||||
/// .route(web::post().to(|person: web::Json<Person>| {
|
||||
/// .route(web::post().to(|person: web::Json<Person>| async {
|
||||
/// HttpResponse::Ok()
|
||||
/// .json(person.into_inner())})
|
||||
/// )));
|
||||
/// ))
|
||||
/// ).await;
|
||||
///
|
||||
/// let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
|
||||
///
|
||||
|
@ -234,7 +241,7 @@ where
|
|||
/// .set_payload(payload)
|
||||
/// .to_request();
|
||||
///
|
||||
/// let result: Person = test::read_response_json(&mut app, req);
|
||||
/// let result: Person = test::read_response_json(&mut app, req).await;
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn read_response_json<S, B, T>(app: &mut S, req: Request) -> T
|
||||
|
@ -262,7 +269,7 @@ where
|
|||
/// use actix_web::{test, HttpRequest, HttpResponse, HttpMessage};
|
||||
/// use actix_web::http::{header, StatusCode};
|
||||
///
|
||||
/// fn index(req: HttpRequest) -> HttpResponse {
|
||||
/// async fn index(req: HttpRequest) -> HttpResponse {
|
||||
/// if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
|
||||
/// HttpResponse::Ok().into()
|
||||
/// } else {
|
||||
|
@ -275,11 +282,11 @@ where
|
|||
/// let req = test::TestRequest::with_header("content-type", "text/plain")
|
||||
/// .to_http_request();
|
||||
///
|
||||
/// let resp = test::block_on(index(req)).unwrap();
|
||||
/// let resp = index(req).await.unwrap();
|
||||
/// assert_eq!(resp.status(), StatusCode::OK);
|
||||
///
|
||||
/// let req = test::TestRequest::default().to_http_request();
|
||||
/// let resp = test::block_on(index(req)).unwrap();
|
||||
/// let resp = index(req).await.unwrap();
|
||||
/// assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -535,9 +542,17 @@ mod tests {
|
|||
let mut app = init_service(
|
||||
App::new().service(
|
||||
web::resource("/index.html")
|
||||
.route(web::put().to(|| HttpResponse::Ok().body("put!")))
|
||||
.route(web::patch().to(|| HttpResponse::Ok().body("patch!")))
|
||||
.route(web::delete().to(|| HttpResponse::Ok().body("delete!"))),
|
||||
.route(
|
||||
web::put().to(|| async { HttpResponse::Ok().body("put!") }),
|
||||
)
|
||||
.route(
|
||||
web::patch()
|
||||
.to(|| async { HttpResponse::Ok().body("patch!") }),
|
||||
)
|
||||
.route(
|
||||
web::delete()
|
||||
.to(|| async { HttpResponse::Ok().body("delete!") }),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
@ -567,13 +582,11 @@ mod tests {
|
|||
#[test]
|
||||
fn test_response() {
|
||||
block_on(async {
|
||||
let mut app = init_service(
|
||||
App::new().service(
|
||||
web::resource("/index.html")
|
||||
.route(web::post().to(|| HttpResponse::Ok().body("welcome!"))),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let mut app =
|
||||
init_service(App::new().service(web::resource("/index.html").route(
|
||||
web::post().to(|| async { HttpResponse::Ok().body("welcome!") }),
|
||||
)))
|
||||
.await;
|
||||
|
||||
let req = TestRequest::post()
|
||||
.uri("/index.html")
|
||||
|
@ -597,7 +610,7 @@ mod tests {
|
|||
let mut app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| {
|
||||
HttpResponse::Ok().json(person.into_inner())
|
||||
async { HttpResponse::Ok().json(person.into_inner()) }
|
||||
}),
|
||||
)))
|
||||
.await;
|
||||
|
@ -621,7 +634,7 @@ mod tests {
|
|||
let mut app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Form<Person>| {
|
||||
HttpResponse::Ok().json(person.into_inner())
|
||||
async { HttpResponse::Ok().json(person.into_inner()) }
|
||||
}),
|
||||
)))
|
||||
.await;
|
||||
|
@ -650,7 +663,7 @@ mod tests {
|
|||
let mut app =
|
||||
init_service(App::new().service(web::resource("/people").route(
|
||||
web::post().to(|person: web::Json<Person>| {
|
||||
HttpResponse::Ok().json(person.into_inner())
|
||||
async { HttpResponse::Ok().json(person.into_inner()) }
|
||||
}),
|
||||
)))
|
||||
.await;
|
||||
|
@ -688,8 +701,7 @@ mod tests {
|
|||
}
|
||||
|
||||
let mut app = init_service(
|
||||
App::new()
|
||||
.service(web::resource("/index.html").to_async(async_with_block)),
|
||||
App::new().service(web::resource("/index.html").to(async_with_block)),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
@ -721,7 +733,7 @@ mod tests {
|
|||
|
||||
// let addr = run_on(|| MyActor.start());
|
||||
// let mut app = init_service(App::new().service(
|
||||
// web::resource("/index.html").to_async(move || {
|
||||
// web::resource("/index.html").to(move || {
|
||||
// addr.send(Num(1)).from_err().and_then(|res| {
|
||||
// if res == 1 {
|
||||
// HttpResponse::Ok()
|
||||
|
|
|
@ -181,7 +181,7 @@ impl<T: Serialize> Responder for Form<T> {
|
|||
///
|
||||
/// /// Extract form data using serde.
|
||||
/// /// Custom configuration is used for this handler, max payload size is 4k
|
||||
/// fn index(form: web::Form<FormData>) -> Result<String> {
|
||||
/// async fn index(form: web::Form<FormData>) -> Result<String> {
|
||||
/// Ok(format!("Welcome {}!", form.username))
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -46,7 +46,7 @@ use crate::responder::Responder;
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's body
|
||||
/// fn index(info: web::Json<Info>) -> String {
|
||||
/// async fn index(info: web::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
|
@ -157,7 +157,7 @@ impl<T: Serialize> Responder for Json<T> {
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's body
|
||||
/// fn index(info: web::Json<Info>) -> String {
|
||||
/// async fn index(info: web::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
|
@ -217,7 +217,7 @@ where
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's body, max payload size is 4kb
|
||||
/// fn index(info: web::Json<Info>) -> String {
|
||||
/// async fn index(info: web::Json<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -24,7 +24,7 @@ use crate::FromRequest;
|
|||
/// /// extract path info from "/{username}/{count}/index.html" url
|
||||
/// /// {username} - deserializes to a String
|
||||
/// /// {count} - - deserializes to a u32
|
||||
/// fn index(info: web::Path<(String, u32)>) -> String {
|
||||
/// async fn index(info: web::Path<(String, u32)>) -> String {
|
||||
/// format!("Welcome {}! {}", info.0, info.1)
|
||||
/// }
|
||||
///
|
||||
|
@ -49,7 +49,7 @@ use crate::FromRequest;
|
|||
/// }
|
||||
///
|
||||
/// /// extract `Info` from a path using serde
|
||||
/// fn index(info: web::Path<Info>) -> Result<String, Error> {
|
||||
/// async fn index(info: web::Path<Info>) -> Result<String, Error> {
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
///
|
||||
|
@ -119,7 +119,7 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
|
|||
/// /// extract path info from "/{username}/{count}/index.html" url
|
||||
/// /// {username} - deserializes to a String
|
||||
/// /// {count} - - deserializes to a u32
|
||||
/// fn index(info: web::Path<(String, u32)>) -> String {
|
||||
/// async fn index(info: web::Path<(String, u32)>) -> String {
|
||||
/// format!("Welcome {}! {}", info.0, info.1)
|
||||
/// }
|
||||
///
|
||||
|
@ -144,7 +144,7 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
|
|||
/// }
|
||||
///
|
||||
/// /// extract `Info` from a path using serde
|
||||
/// fn index(info: web::Path<Info>) -> Result<String, Error> {
|
||||
/// async fn index(info: web::Path<Info>) -> Result<String, Error> {
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
///
|
||||
|
@ -206,7 +206,7 @@ where
|
|||
/// }
|
||||
///
|
||||
/// // deserialize `Info` from request's path
|
||||
/// fn index(folder: web::Path<Folder>) -> String {
|
||||
/// async fn index(folder: web::Path<Folder>) -> String {
|
||||
/// format!("Selected folder: {:?}!", folder)
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -40,7 +40,7 @@ use crate::request::HttpRequest;
|
|||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::get().to_async(index))
|
||||
/// web::get().to(index))
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -88,7 +88,7 @@ impl Stream for Payload {
|
|||
/// fn main() {
|
||||
/// let app = App::new().service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::get().to_async(index))
|
||||
/// web::get().to(index))
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -117,7 +117,7 @@ impl FromRequest for Payload {
|
|||
/// use actix_web::{web, App};
|
||||
///
|
||||
/// /// extract binary data from request
|
||||
/// fn index(body: Bytes) -> String {
|
||||
/// async fn index(body: Bytes) -> String {
|
||||
/// format!("Body {:?}!", body)
|
||||
/// }
|
||||
///
|
||||
|
@ -169,7 +169,7 @@ impl FromRequest for Bytes {
|
|||
/// use actix_web::{web, App, FromRequest};
|
||||
///
|
||||
/// /// extract text data from request
|
||||
/// fn index(text: String) -> String {
|
||||
/// async fn index(text: String) -> String {
|
||||
/// format!("Body {}!", text)
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -40,7 +40,7 @@ use crate::request::HttpRequest;
|
|||
/// // Use `Query` extractor for query information (and destructure it within the signature).
|
||||
/// // This handler gets called only if the request's query string contains a `username` field.
|
||||
/// // The correct request for this handler would be `/index.html?id=64&response_type=Code"`.
|
||||
/// fn index(web::Query(info): web::Query<AuthRequest>) -> String {
|
||||
/// async fn index(web::Query(info): web::Query<AuthRequest>) -> String {
|
||||
/// format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type)
|
||||
/// }
|
||||
///
|
||||
|
@ -118,7 +118,7 @@ impl<T: fmt::Display> fmt::Display for Query<T> {
|
|||
/// // Use `Query` extractor for query information.
|
||||
/// // This handler get called only if request's query contains `username` field
|
||||
/// // The correct request for this handler would be `/index.html?id=64&response_type=Code"`
|
||||
/// fn index(info: web::Query<AuthRequest>) -> String {
|
||||
/// async fn index(info: web::Query<AuthRequest>) -> String {
|
||||
/// format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type)
|
||||
/// }
|
||||
///
|
||||
|
@ -179,7 +179,7 @@ where
|
|||
/// }
|
||||
///
|
||||
/// /// deserialize `Info` from request's querystring
|
||||
/// fn index(info: web::Query<Info>) -> String {
|
||||
/// async fn index(info: web::Query<Info>) -> String {
|
||||
/// format!("Welcome {}!", info.username)
|
||||
/// }
|
||||
///
|
||||
|
|
36
src/web.rs
36
src/web.rs
|
@ -8,7 +8,7 @@ pub use futures::channel::oneshot::Canceled;
|
|||
|
||||
use crate::error::Error;
|
||||
use crate::extract::FromRequest;
|
||||
use crate::handler::{AsyncFactory, Factory};
|
||||
use crate::handler::Factory;
|
||||
use crate::resource::Resource;
|
||||
use crate::responder::Responder;
|
||||
use crate::route::Route;
|
||||
|
@ -231,10 +231,10 @@ pub fn method(method: Method) -> Route {
|
|||
/// Create a new route and add handler.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse};
|
||||
/// use actix_web::{web, App, HttpResponse, Responder};
|
||||
///
|
||||
/// fn index() -> HttpResponse {
|
||||
/// unimplemented!()
|
||||
/// async fn index() -> impl Responder {
|
||||
/// HttpResponse::Ok()
|
||||
/// }
|
||||
///
|
||||
/// App::new().service(
|
||||
|
@ -242,36 +242,14 @@ pub fn method(method: Method) -> Route {
|
|||
/// web::to(index))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn to<F, I, R>(handler: F) -> Route
|
||||
pub fn to<F, I, R, U>(handler: F) -> Route
|
||||
where
|
||||
F: Factory<I, R> + 'static,
|
||||
I: FromRequest + 'static,
|
||||
R: Responder + 'static,
|
||||
{
|
||||
Route::new().to(handler)
|
||||
}
|
||||
|
||||
/// Create a new route and add async handler.
|
||||
///
|
||||
/// ```rust
|
||||
/// use actix_web::{web, App, HttpResponse, Error};
|
||||
///
|
||||
/// async fn index() -> Result<HttpResponse, Error> {
|
||||
/// Ok(HttpResponse::Ok().finish())
|
||||
/// }
|
||||
///
|
||||
/// App::new().service(web::resource("/").route(
|
||||
/// web::to_async(index))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn to_async<F, I, R, U>(handler: F) -> Route
|
||||
where
|
||||
F: AsyncFactory<I, R, U>,
|
||||
F: Factory<I, R, U>,
|
||||
I: FromRequest + 'static,
|
||||
R: Future<Output = U> + 'static,
|
||||
U: Responder + 'static,
|
||||
{
|
||||
Route::new().to_async(handler)
|
||||
Route::new().to(handler)
|
||||
}
|
||||
|
||||
/// Create raw service for a specific path.
|
||||
|
|
|
@ -11,13 +11,11 @@ use bytes::Bytes;
|
|||
use flate2::read::GzDecoder;
|
||||
use flate2::write::{GzEncoder, ZlibDecoder, ZlibEncoder};
|
||||
use flate2::Compression;
|
||||
use futures::future::ok;
|
||||
use futures::stream::once;
|
||||
use futures::{future::ok, stream::once};
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
|
||||
use actix_connect::start_default_resolver;
|
||||
use actix_web::middleware::{BodyEncoding, Compress};
|
||||
use actix_web::{dev, http, test, web, App, HttpResponse, HttpServer};
|
||||
use actix_web::{dev, http, web, App, HttpResponse, HttpServer};
|
||||
|
||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||
Hello World Hello World Hello World Hello World Hello World \
|
||||
|
@ -817,18 +815,19 @@ fn test_brotli_encoding_large() {
|
|||
// }
|
||||
|
||||
#[cfg(all(
|
||||
feature = "rust-tls",
|
||||
feature = "ssl",
|
||||
feature = "rustls",
|
||||
feature = "openssl",
|
||||
any(feature = "flate2-zlib", feature = "flate2-rust")
|
||||
))]
|
||||
#[test]
|
||||
fn test_reading_deflate_encoding_large_random_ssl() {
|
||||
block_on(async {
|
||||
use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
||||
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
|
||||
use rustls::{NoClientAuth, ServerConfig};
|
||||
use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
||||
use rust_tls::internal::pemfile::{certs, pkcs8_private_keys};
|
||||
use rust_tls::{NoClientAuth, ServerConfig};
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::sync::mpsc;
|
||||
|
||||
let addr = TestServer::unused_addr();
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
@ -838,7 +837,7 @@ fn test_reading_deflate_encoding_large_random_ssl() {
|
|||
.take(160_000)
|
||||
.collect::<String>();
|
||||
|
||||
thread::spawn(move || {
|
||||
std::thread::spawn(move || {
|
||||
let sys = actix_rt::System::new("test");
|
||||
|
||||
// load ssl keys
|
||||
|
@ -851,11 +850,13 @@ fn test_reading_deflate_encoding_large_random_ssl() {
|
|||
|
||||
let srv = HttpServer::new(|| {
|
||||
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
|
||||
Ok::<_, Error>(
|
||||
HttpResponse::Ok()
|
||||
.encoding(http::ContentEncoding::Identity)
|
||||
.body(bytes),
|
||||
)
|
||||
async move {
|
||||
Ok::<_, Error>(
|
||||
HttpResponse::Ok()
|
||||
.encoding(http::ContentEncoding::Identity)
|
||||
.body(bytes),
|
||||
)
|
||||
}
|
||||
})))
|
||||
})
|
||||
.bind_rustls(addr, config)
|
||||
|
@ -866,8 +867,7 @@ fn test_reading_deflate_encoding_large_random_ssl() {
|
|||
let _ = sys.run();
|
||||
});
|
||||
let (srv, _sys) = rx.recv().unwrap();
|
||||
test::block_on(futures::lazy(|| Ok::<_, ()>(start_default_resolver()))).unwrap();
|
||||
let client = test::run_on(|| {
|
||||
let client = {
|
||||
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||
builder.set_verify(SslVerifyMode::NONE);
|
||||
let _ = builder.set_alpn_protos(b"\x02h2\x08http/1.1").unwrap();
|
||||
|
@ -880,7 +880,7 @@ fn test_reading_deflate_encoding_large_random_ssl() {
|
|||
.finish(),
|
||||
)
|
||||
.finish()
|
||||
});
|
||||
};
|
||||
|
||||
// encode data
|
||||
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
|
||||
|
@ -893,11 +893,11 @@ fn test_reading_deflate_encoding_large_random_ssl() {
|
|||
.header(http::header::CONTENT_ENCODING, "deflate")
|
||||
.send_body(enc);
|
||||
|
||||
let mut response = test::block_on(req).unwrap();
|
||||
let mut response = req.await.unwrap();
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// read response
|
||||
let bytes = test::block_on(response.body()).unwrap();
|
||||
let bytes = response.body().await.unwrap();
|
||||
assert_eq!(bytes.len(), data.len());
|
||||
assert_eq!(bytes, Bytes::from(data));
|
||||
|
||||
|
|
Loading…
Reference in a new issue