Cannot close normally after takebody in middleware #2370
-
I am trying to use environment variables to control whether a certain directory returns HTTP403, the following is the simplified code. It seems that everything is normal, but there is a timeout phenomenon during the test, and there is no How should I modify my code to make it work? Or, is there any better way to return HTTP403 (without body)? [dependencies]
actix-web = "3"
actix-files = "0.5" use actix_web::{App, dev::Service, http::{HeaderMap, StatusCode}, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().wrap_fn(|req, srv| {
let fut = srv.call(req);
async move {
Ok(fut.await?.map_body(|head, mut body| {
if std::env::var("FORBIDDEN").unwrap_or("false".to_string()) == "true" {
head.status = StatusCode::FORBIDDEN;
*head.headers_mut() = HeaderMap::new();
let _ = body.take_body();
}
body
}))
}
}).service(actix_files::Files::new("/", "/").show_files_listing())
})
.bind("127.0.0.1:8080")?
.run()
.await
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
This is likely a design flaw as actix-web in general expect you to return something as body even if it's empty. The This is an work around use actix_web::body::Body;
use actix_web::dev::ResponseBody;
use actix_web::web::Bytes;
use actix_web::{
dev::Service,
http::{HeaderMap, HeaderName, HeaderValue, StatusCode},
App, HttpServer,
};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap_fn(|req, srv| {
let fut = srv.call(req);
async move {
Ok(fut.await?.map_body(|head, _| {
head.status = StatusCode::FORBIDDEN;
*head.headers_mut() = HeaderMap::new();
head.headers_mut().insert(
HeaderName::from_static("content-length"),
HeaderValue::from_static("0"),
);
ResponseBody::<Body>::Other(Body::Bytes(Bytes::new()))
}))
}
})
.service(actix_files::Files::new("/", "/").show_files_listing())
})
.bind("127.0.0.1:8080")?
.run()
.await
} You can also keep your code as is with extra |
Beta Was this translation helpful? Give feedback.
-
And a side note you may want to use a middleware where you check the env before |
Beta Was this translation helpful? Give feedback.
And a side note you may want to use a middleware where you check the env before
actix_files
service get called. Your current code would call the service regardless and make fs syscall.