actix-web: file upload timeout
I have a POST request that does some complex processing. However, for debug purposes I have commented out the meat of the handler body. This is what’s left:
// For details on the available formatting options for `LOG_FMT`, see
// https://docs.rs/actix-web/3.0.2/actix_web/middleware/struct.Logger.html
const LOG_FMT: &str = r#"{
remote_ip: %a,
serve_time: %D ms,
status: %s,
request: "%r",
response_size: %b bytes,
user_agent: "%{User-Agent}i",
}"#;
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
// some code here
let mut settings = Settings::parse_toml("Server.toml")?;
// more code here
let settings = Arc::new(settings); // Leverage `Arc` to not waste memory
let insettings = Arc::clone(&settings);
HttpServer::new(move || {
let route = |path| if insettings.actix.enable_log { "N/A" } else { path };
App::new()
.wrap(Compress::new(if insettings.actix.enable_compression {
ContentEncoding::Deflate
} else {
ContentEncoding::Identity
}))
.wrap(
Logger::new(LOG_FMT)
.exclude(route("/"))
.exclude(route("/favicon.ico"))
)
.data(insettings.clone())
// Define routes:
.service(index)
.service(upload)
})
.apply_settings(&settings) // This comes from the actix-settings crate; all it does is apply the settings in a file using APIs defined by `actix-web`.
.run()
.await
}
#[get("/")]
async fn index() -> impl Responder {
let html = r#"
<html>
<head><title>Upload Test</title></head>
<body style="background: #3c3c3c;">
<form target="/" method="post" enctype="multipart/form-data">
<input type="file" multiple name="file"/>
<button type="submit">Submit</button>
</form>
</body>
</html>
"#;
HttpResponse::Ok().body(html)
}
#[post("/")]
async fn upload(
mut payload: Multipart,
settings: web::Data<Arc<Settings>>,
) -> ActixResult<impl Responder> {
// NOTE: The original body has been replaced by returning a simple string
Ok("[upload] foo bar".to_string())
}
Expected Behavior
I expect the POST request to complete, and quickly too.
Current Behavior
The POST request hangs indefinitely until the connection with the client is broken.
Altering the keep-alive
setting merely keeps the connection hanging for longer.
Possible Solution
No clue, as I’m not familiar with actix-web
internals.
Steps to Reproduce (for bugs)
- Run the server
- Send the POST request to
/
to engage theupload
route using the HTML form located atget("/")
- A new tab/page appears…
- …and it never completes, instead just timing out.
Context
This is a show-stopper bug. The entire server is unusable like this during development, never mind production.
Your Environment
The environment doesn’t really matter as the issue is reproducible on a regular OS install as well as in a Kubernetes cluster. In all cases the OS is linux-based.
-
Ubuntu Linux 19.10
-
rustc 1.48.0 (7eac88abb 2020-11-16)
-
Actix-web 3.3.0
-
actix-settings 0.5
-
Rust Version (I.e, output of
rustc -V
): -
Actix Web Version:
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 19 (8 by maintainers)
Like I said please make a minimal example. For example you don’t need three endpoints to produce a leak. You don’t need logger. You don’t need middleware.
There is not enough man power to look into your big block of code and analyze it.
That’s a lot of code. Please try to make a minimal reproduce able one so the problem can be more clear.