Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
WyntersN opened this issue May 9, 2024 · 0 comments

Comments

@WyntersN
Copy link

WyntersN commented May 9, 2024

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

@actix actix locked and limited conversation to collaborators Jun 9, 2024
@robjtede robjtede converted this issue into discussion #829 Jun 9, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant