actix-web
actix-web copied to clipboard
Next request timeouts after error in File upload
Current Behavior
When uploading an image or some other kind of file, but a custom extractor returns an error, the next request runs into a timeout.
Expected Behavior
Get no timeout
Possible Solution
No idea
Steps to Reproduce (for bugs)
I have this small example
use std::future::{Ready, ready};
use actix_web::{App, FromRequest, get, HttpRequest, HttpResponse, HttpServer, post, Responder};
use actix_web::error::{ErrorBadRequest};
use actix_web::web::Payload;
struct SomeFailingExtractor;
impl FromRequest for SomeFailingExtractor {
type Error = actix_web::Error;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(_: &HttpRequest, _: &mut actix_web::dev::Payload) -> Self::Future {
return ready(Err(ErrorBadRequest("Bad request")));
}
}
#[post("/image")]
async fn upload_image(
_: SomeFailingExtractor,
_payload: Payload
) -> impl Responder {
return HttpResponse::Ok().body("Uploaded");
}
#[get("/other")]
async fn other_endpoint() -> impl Responder {
println!("Other endpoint called");
return HttpResponse::Ok().body("Hello there");
}
#[actix_web::main]
async fn main() {
HttpServer::new(move || {
App::new()
.service(upload_image)
.service(other_endpoint)
})
.bind(("0.0.0.0", 8080)).expect("Error")
.run()
.await.expect("Error")
}
The following python script runs into the timeout. It works, if you don't use a session. The second request on /other works. The bug also occurs on a simple website
import requests
session = requests.session()
file = open("/path/to/image.png", "rb").read()
resp1 = session.post(
"http://localhorst:8080/image",
data=file,
headers={
# also happens with multipart/form-data, image/png
"content-type": "application/octet-stream",
}
)
print(resp1.text)
try:
resp2 = session.get("http://localhorst:8080/other", timeout=30)
print(resp2.text)
except requests.exceptions.ReadTimeout:
print("Timeout")
resp2 = session.get("http://localhorst:8080/other", timeout=3)
print(resp2.text)
Context
I wanted to add an endpoint, where you can upload an image.
Your Environment
- Rust Version (I.e, output of
rustc -V
): 1.74, but also doesn't work with 1.69 - Actix Web Version: 4.4.0
- OS: Arch Linux
A temporary workaround is to disable keep_alive.
Just bumped the same issue. One more note. If I try to upload 2.4MB image file everything FromRequest works well. If i try to upload small size image (in my case less than 100kb) it will stack on next request
related to https://github.com/actix/actix-web/issues/3220 pr: https://github.com/actix/actix-web/pull/3221