How do I construct HttpResponse without calling the service in actix-web?

38 Views Asked by At

I'd like to want to return forbidden to some crawlers which I don't like. I have tried to implement it by wrap_fn because I couldn't get how I can use Middleware trait:

use std::future::Future;
use std::net::Ipv4Addr;
use std::pin::Pin;
use actix_web::{App, HttpResponseBuilder, HttpServer, web};
use actix_web::dev::ServiceResponse;
use actix_web::http::StatusCode;
use actix_web::dev::Service;
use futures_util::future::BoxFuture;

#[actix_web::main]
async fn main() {
    let http_server = HttpServer::new(move || {
        App::new().route("/", web::get().to(|| async {
            return "Hello, World!"
        })).wrap_fn(|req, srv| {
            println!("Hi from start. You requested: {}", req.path());

            let x: Pin<Box<dyn Future<Output = Result<ServiceResponse, actix_web::Error>>>>;

            const CRAWLER: Ipv4Addr = some_value();
            'handle: {
                if req.peer_addr().map(|x| x.ip()).is_some_and(|x| x == CRAWLER) {
                    x = Box::pin(async {
                        Ok(ServiceResponse::new(req, HttpResponseBuilder::new(StatusCode::FORBIDDEN).body("Forbidden")))
                    }) as _;
                    break 'handle;
                }

                x = Box::pin(srv.call(req).map(|res| async {
                    let Ok(ref r) = &res else { return res };

                    if req.peer_addr().map(|x| x.ip()).is_some_and(|x| x == CRAWLER) {
                        return res
                    }

                    println!("Hi from response");
                    res
                })) as _;
            }

            use futures_util::future::FutureExt;

            x
        })
    });

    http_server.bind(("localhost", 12345)).expect("bind")
        .run()
        .await
        .expect("run")
}

However, I get the following error:

error[E0308]: mismatched types
   --> src/main.rs:23:49
    |
23  |                         Ok(ServiceResponse::new(req, HttpResponseBuilder::new(StatusCode::FORBIDDEN).body("Forbidden")))
    |                            -------------------- ^^^ expected `HttpRequest`, found `ServiceRequest`
    |                            |
    |                            arguments to this function are incorrect
    |
note: associated function defined here
   --> $HOME/.cargo/registry/src/index.crates.io-6f17d22bba15001f/actix-web-4.5.1/src/service.rs:403:12
    |
403 |     pub fn new(request: HttpRequest, response: HttpResponse<B>) -> Self {
    |            ^^^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `blacklist-ip-actix-minimize` (bin "blacklist-ip-actix-minimize") due to 1 previous error

What am I missing?

0

There are 0 best solutions below