mirror of
https://github.com/actix/examples
synced 2025-06-26 17:17:42 +02:00
upgrade to 2.0 alpha.3
This commit is contained in:
@ -1,13 +1,15 @@
|
||||
[package]
|
||||
name = "middleware-example"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
authors = ["Gorm Casper <gcasper@gmail.com>", "Sven-Hendrik Haase <svenstaro@gmail.com>"]
|
||||
edition = "2018"
|
||||
workspace = ".."
|
||||
|
||||
[dependencies]
|
||||
actix-service = "0.4.1"
|
||||
actix-web = "1.0.0"
|
||||
futures = "0.1.25"
|
||||
actix-service = "1.0.0-alpha.3"
|
||||
actix-rt = "1.0.0-alpha.3"
|
||||
actix-web = "2.0.0-alpha.3"
|
||||
futures = "0.3.1"
|
||||
env_logger = "0.6"
|
||||
bytes = "0.4"
|
||||
bytes = "0.5"
|
||||
pin-project = "0.4.6"
|
@ -1,17 +1,18 @@
|
||||
use actix_web::{web, App, HttpServer};
|
||||
use actix_service::Service;
|
||||
use futures::future::Future;
|
||||
use actix_web::{web, App, HttpServer};
|
||||
use futures::future::FutureExt;
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod redirect;
|
||||
#[allow(dead_code)]
|
||||
mod read_request_body;
|
||||
#[allow(dead_code)]
|
||||
mod read_response_body;
|
||||
#[allow(dead_code)]
|
||||
mod redirect;
|
||||
#[allow(dead_code)]
|
||||
mod simple;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
#[actix_rt::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
std::env::set_var("RUST_LOG", "actix_web=debug");
|
||||
env_logger::init();
|
||||
|
||||
@ -30,14 +31,15 @@ fn main() -> std::io::Result<()> {
|
||||
})
|
||||
})
|
||||
.service(web::resource("/login").to(|| {
|
||||
"You are on /login. Go to src/redirect.rs to change this behavior."
|
||||
async {
|
||||
"You are on /login. Go to src/redirect.rs to change this behavior."
|
||||
}
|
||||
}))
|
||||
.service(web::resource("/").to(|| {
|
||||
async { "Hello, middleware! Check the console where the server is run." }
|
||||
}))
|
||||
.service(
|
||||
web::resource("/").to(|| {
|
||||
"Hello, middleware! Check the console where the server is run."
|
||||
}),
|
||||
)
|
||||
})
|
||||
.bind("127.0.0.1:8080")?
|
||||
.run()
|
||||
.start()
|
||||
.await
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
use std::cell::RefCell;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_service::{Service, Transform};
|
||||
use actix_web::error::PayloadError;
|
||||
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error, HttpMessage};
|
||||
use bytes::BytesMut;
|
||||
use futures::future::{ok, FutureResult};
|
||||
use futures::stream::Stream;
|
||||
use futures::{Future, Poll};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use futures::future::{ok, Future, Ready};
|
||||
use futures::stream::StreamExt;
|
||||
|
||||
pub struct Logging;
|
||||
|
||||
@ -21,7 +22,7 @@ where
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Transform = LoggingMiddleware<S>;
|
||||
type Future = FutureResult<Self::Transform, Self::InitError>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(LoggingMiddleware {
|
||||
@ -45,26 +46,27 @@ where
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Future = Box<dyn Future<Item = Self::Response, Error = Self::Error>>;
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready()
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
self.service.poll_ready(cx)
|
||||
}
|
||||
|
||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
||||
let mut svc = self.service.clone();
|
||||
|
||||
Box::new(
|
||||
req.take_payload()
|
||||
.fold(BytesMut::new(), move |mut body, chunk| {
|
||||
body.extend_from_slice(&chunk);
|
||||
Ok::<_, PayloadError>(body)
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
.and_then(move |bytes| {
|
||||
println!("request body: {:?}", bytes);
|
||||
svc.call(req).and_then(|res| Ok(res))
|
||||
}),
|
||||
)
|
||||
Box::pin(async move {
|
||||
let mut body = BytesMut::new();
|
||||
let mut stream = req.take_payload();
|
||||
while let Some(chunk) = stream.next().await {
|
||||
body.extend_from_slice(&chunk?);
|
||||
}
|
||||
|
||||
println!("request body: {:?}", body);
|
||||
let res = svc.call(req).await?;
|
||||
|
||||
println!("response: {:?}", res.headers());
|
||||
Ok(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_service::{Service, Transform};
|
||||
use actix_web::body::{BodySize, MessageBody, ResponseBody};
|
||||
use std::marker::PhantomData;
|
||||
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures::Async;
|
||||
use futures::future::{ok, FutureResult};
|
||||
use futures::{Future, Poll};
|
||||
use futures::future::{ok, Ready};
|
||||
|
||||
pub struct Logging;
|
||||
|
||||
@ -19,12 +21,10 @@ where
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Transform = LoggingMiddleware<S>;
|
||||
type Future = FutureResult<Self::Transform, Self::InitError>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(LoggingMiddleware {
|
||||
service,
|
||||
})
|
||||
ok(LoggingMiddleware { service })
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,8 +42,8 @@ where
|
||||
type Error = Error;
|
||||
type Future = WrapperStream<S, B>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready()
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
self.service.poll_ready(cx)
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
@ -54,11 +54,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project::pin_project]
|
||||
pub struct WrapperStream<S, B>
|
||||
where
|
||||
B: MessageBody,
|
||||
S: Service,
|
||||
{
|
||||
#[pin]
|
||||
fut: S::Future,
|
||||
_t: PhantomData<(B,)>,
|
||||
}
|
||||
@ -68,18 +70,19 @@ where
|
||||
B: MessageBody,
|
||||
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
{
|
||||
type Item = ServiceResponse<BodyLogger<B>>;
|
||||
type Error = Error;
|
||||
type Output = Result<ServiceResponse<BodyLogger<B>>, Error>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
let res = futures::try_ready!(self.fut.poll());
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let res = futures::ready!(self.project().fut.poll(cx));
|
||||
|
||||
Ok(Async::Ready(res.map_body(move |_, body| {
|
||||
ResponseBody::Body(BodyLogger {
|
||||
body,
|
||||
body_accum: BytesMut::new(),
|
||||
Poll::Ready(res.map(|res| {
|
||||
res.map_body(move |_, body| {
|
||||
ResponseBody::Body(BodyLogger {
|
||||
body,
|
||||
body_accum: BytesMut::new(),
|
||||
})
|
||||
})
|
||||
})))
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,13 +102,15 @@ impl<B: MessageBody> MessageBody for BodyLogger<B> {
|
||||
self.body.size()
|
||||
}
|
||||
|
||||
fn poll_next(&mut self) -> Poll<Option<Bytes>, Error> {
|
||||
match self.body.poll_next()? {
|
||||
Async::Ready(Some(chunk)) => {
|
||||
fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
match self.body.poll_next(cx) {
|
||||
Poll::Ready(Some(Ok(chunk))) => {
|
||||
self.body_accum.extend_from_slice(&chunk);
|
||||
Ok(Async::Ready(Some(chunk)))
|
||||
Poll::Ready(Some(Ok(chunk)))
|
||||
}
|
||||
val => Ok(val),
|
||||
Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
|
||||
Poll::Ready(None) => Poll::Ready(None),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_service::{Service, Transform};
|
||||
use actix_web::dev::{ServiceRequest, ServiceResponse};
|
||||
use actix_web::{http, Error, HttpResponse};
|
||||
use futures::future::{ok, Either, FutureResult};
|
||||
use futures::Poll;
|
||||
use futures::future::{ok, Either, Ready};
|
||||
|
||||
pub struct CheckLogin;
|
||||
|
||||
@ -16,7 +17,7 @@ where
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Transform = CheckLoginMiddleware<S>;
|
||||
type Future = FutureResult<Self::Transform, Self::InitError>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(CheckLoginMiddleware { service })
|
||||
@ -34,10 +35,10 @@ where
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Future = Either<S::Future, FutureResult<Self::Response, Self::Error>>;
|
||||
type Future = Either<S::Future, Ready<Result<Self::Response, Self::Error>>>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready()
|
||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
self.service.poll_ready(cx)
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
@ -46,13 +47,13 @@ where
|
||||
let is_logged_in = false; // Change this to see the change in outcome in the browser
|
||||
|
||||
if is_logged_in {
|
||||
Either::A(self.service.call(req))
|
||||
Either::Left(self.service.call(req))
|
||||
} else {
|
||||
// Don't forward to /login if we are already on /login
|
||||
if req.path() == "/login" {
|
||||
Either::A(self.service.call(req))
|
||||
Either::Left(self.service.call(req))
|
||||
} else {
|
||||
Either::B(ok(req.into_response(
|
||||
Either::Right(ok(req.into_response(
|
||||
HttpResponse::Found()
|
||||
.header(http::header::LOCATION, "/login")
|
||||
.finish()
|
||||
|
@ -1,7 +1,10 @@
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_service::{Service, Transform};
|
||||
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error};
|
||||
use futures::future::{ok, FutureResult};
|
||||
use futures::{Future, Poll};
|
||||
use futures::future::{ok, Ready};
|
||||
use futures::Future;
|
||||
|
||||
// There are two steps in middleware processing.
|
||||
// 1. Middleware initialization, middleware factory gets called with
|
||||
@ -23,7 +26,7 @@ where
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Transform = SayHiMiddleware<S>;
|
||||
type Future = FutureResult<Self::Transform, Self::InitError>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ok(SayHiMiddleware { service })
|
||||
@ -43,18 +46,22 @@ where
|
||||
type Request = ServiceRequest;
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Future = Box<dyn Future<Item = Self::Response, Error = Self::Error>>;
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.service.poll_ready()
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.service.poll_ready(cx)
|
||||
}
|
||||
|
||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
||||
println!("Hi from start. You requested: {}", req.path());
|
||||
|
||||
Box::new(self.service.call(req).and_then(|res| {
|
||||
let fut = self.service.call(req);
|
||||
|
||||
Box::pin(async move {
|
||||
let res = fut.await?;
|
||||
|
||||
println!("Hi from response");
|
||||
Ok(res)
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user