actix / actix/actix-web

Next request timeouts after error in File upload

Đang mở
#3,194 3 bình luận 1 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Rust
Star
24.8k
Fork
1.9k
Merge trung bình
23 giờ 10 phút
Pull request đã merge (30 ngày)
26

Mô tả

## 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

```rust
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>;

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
```python
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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.