Skip to content

There are only successful examples and no failed examples. I need to return JSON immediately and not continue. What should I do #809

@WyntersN

Description

@WyntersN
use std::{
    future::{ready, Ready},
    rc::Rc,
};

use actix_web::{
    dev::{self, Service, ServiceRequest, ServiceResponse, Transform},
    web, Error, HttpResponse,
};
use futures_util::future::LocalBoxFuture;

pub struct Auth;

impl<S: 'static, B> Transform<S, ServiceRequest> for Auth
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = AuthMiddleware<S>;
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ready(Ok(AuthMiddleware {
            service: Rc::new(service),
        }))
    }
}

pub struct AuthMiddleware<S> {
    // This is special: We need this to avoid lifetime issues.
    service: Rc<S>,
}

impl<S, B> Service<ServiceRequest> for AuthMiddleware<S>
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

    dev::forward_ready!(service);

    fn call(&self, mut req: ServiceRequest) -> Self::Future {
        let svc = self.service.clone();
        let fut = async move {
            let token = req
            .headers()
            .get("Authorization")
            .and_then(|header| header.to_str().ok())
            .map(|token| token.trim_start_matches("Bearer "));

            match token {
                Some(_) => {
                    let res = svc.call(req).await?;
                    println!("response: {:?}", res.headers());
                    Ok(res)
                },
                None => {
                    
                    let json = serde_json::json!({"code": 401, "message": "Unauthorized"});
                    let response = HttpResponse::Unauthorized()
                        .content_type("application/json")
                        .body(json.to_string());
                    Ok(ServiceResponse::new(req, response))
                }
            }
        };
        Box::pin(fut)
    }
}

You can use this middleware example as a guide for writing your custom logger that can print the body it reads.

There are only successful examples and no failed examples. I need to return JSON immediately and not continue. What should I do

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions