1
0
mirror of https://github.com/actix/actix-website synced 2025-06-27 15:39:02 +02:00

First pass at Middlewares.

This commit is contained in:
Cameron Dershem
2019-06-17 16:57:57 -04:00
parent 083522ef19
commit 9a16b6db93
8 changed files with 189 additions and 125 deletions

View File

@ -21,4 +21,5 @@ exclude = [
"requests",
"responses",
"testing",
"middleware",
]

View File

@ -0,0 +1,11 @@
[package]
name = "middleware"
version = "0.1.0"
edition = "2018"
[dependencies]
actix-web = "1.0"
actix-service = "0.4"
actix-session = "0.1"
futures = "0.1"
env_logger = "0.6"

View File

@ -0,0 +1,16 @@
// <default-headers>
use actix_web::{http, middleware, web, App, HttpResponse};
fn main() {
App::new()
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
.service(
web::resource("/test")
.route(web::get().to(|| HttpResponse::Ok()))
.route(
web::method(http::Method::HEAD)
.to(|| HttpResponse::MethodNotAllowed()),
),
);
}
// </default-headers>

View File

@ -0,0 +1,25 @@
// <error-handler>
use actix_web::middleware::errhandlers::{ErrorHandlerResponse, ErrorHandlers};
use actix_web::{dev, http, web, App, HttpResponse, Result};
fn render_500<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
res.response_mut().headers_mut().insert(
http::header::CONTENT_TYPE,
http::HeaderValue::from_static("Error"),
);
Ok(ErrorHandlerResponse::Response(res))
}
fn main() {
App::new()
.wrap(
ErrorHandlers::new()
.handler(http::StatusCode::INTERNAL_SERVER_ERROR, render_500),
)
.service(
web::resource("/test")
.route(web::get().to(|| HttpResponse::Ok()))
.route(web::head().to(|| HttpResponse::MethodNotAllowed())),
);
}
// </error-handler>

View File

@ -0,0 +1,14 @@
// <logger>
use actix_web::middleware::Logger;
use actix_web::App;
use env_logger;
fn main() {
std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
App::new()
.wrap(Logger::default())
.wrap(Logger::new("%a %{User-Agent}i"));
}
// </logger>

View File

@ -0,0 +1,72 @@
mod default_headers;
mod errorhandler;
mod logger;
mod user_sessions;
// <main>
use actix_service::{Service, Transform};
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, web, App, Error};
use futures::future::{ok, FutureResult};
use futures::{Future, Poll};
// There are two steps in middleware processing.
// 1. Middleware initialization, middleware factory gets called with
// next service in chain as parameter.
// 2. Middleware's call method gets called with normal request.
pub struct SayHi;
// Middleware factory is `Transform` trait from actix-service crate
// `S` - type of the next service
// `B` - type of response's body
impl<S, B> Transform<S> for SayHi
where
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Request = ServiceRequest;
type Response = ServiceResponse<B>;
type Error = Error;
type InitError = ();
type Transform = SayHiMiddleware<S>;
type Future = FutureResult<Self::Transform, Self::InitError>;
fn new_transform(&self, service: S) -> Self::Future {
ok(SayHiMiddleware { service })
}
}
pub struct SayHiMiddleware<S> {
service: S,
}
impl<S, B> Service for SayHiMiddleware<S>
where
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Request = ServiceRequest;
type Response = ServiceResponse<B>;
type Error = Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.service.poll_ready()
}
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| {
println!("Hi from response");
Ok(res)
}))
}
}
// </main>
fn main() {
App::new().wrap(SayHi).service(
web::resource("/")
.to(|| "Hello, middleware! Check the console where the server is run."),
);
}

View File

@ -0,0 +1,37 @@
// <user-session>
use actix_session::{CookieSession, Session};
use actix_web::{middleware::Logger, web, App, HttpRequest, HttpServer, Result};
/// simple index handler with session
fn index(session: Session, req: HttpRequest) -> Result<&'static str> {
println!("{:?}", req);
// RequestSession trait is used for session access
let mut counter = 1;
if let Some(count) = session.get::<i32>("counter")? {
println!("SESSION value: {}", count);
counter = count + 1;
session.set("counter", counter)?;
} else {
session.set("counter", counter)?;
}
Ok("welcome!")
}
fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
HttpServer::new(|| {
App::new()
// enable logger
.wrap(Logger::default())
// cookie session middleware
.wrap(CookieSession::signed(&[0; 32]).secure(false))
.service(web::resource("/").to(index))
})
.bind("127.0.0.1:8080")?
.run()
}
// </user-session>