actix / actix/actix-web

Next request timeouts after error in File upload

未关闭
#3,194 3 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Rust
星标
24.8k
派生
1.9k
平均合并
23 小时 10 分钟
30 天内合并 PR
26

描述

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

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。