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, Ready}; pub struct CheckLogin; impl Transform for CheckLogin where S: Service, Error = Error>, S::Future: 'static, { type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); type Transform = CheckLoginMiddleware; type Future = Ready>; fn new_transform(&self, service: S) -> Self::Future { ok(CheckLoginMiddleware { service }) } } pub struct CheckLoginMiddleware { service: S, } impl Service for CheckLoginMiddleware where S: Service, Error = Error>, S::Future: 'static, { type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = Either>>; fn poll_ready(&mut self, cx: &mut Context) -> Poll> { self.service.poll_ready(cx) } fn call(&mut self, req: ServiceRequest) -> Self::Future { // We only need to hook into the `start` for this middleware. let is_logged_in = false; // Change this to see the change in outcome in the browser if is_logged_in { Either::Left(self.service.call(req)) } else { // Don't forward to /login if we are already on /login if req.path() == "/login" { Either::Left(self.service.call(req)) } else { Either::Right(ok(req.into_response( HttpResponse::Found() .header(http::header::LOCATION, "/login") .finish() .into_body(), ))) } } } }