middleware::Compress seems to be buffering content indefinitely
- Linguagem predominante
- Rust
- Estrelas
- 24.8k
- Forks
- 1.9k
- Merge médio
- 23h 10min
- PRs com merge (30d)
- 26
Descrição
Initially reported https://github.com/lovasoa/SQLpage/issues/435
When making streaming responses and activating `middleware::Compress`, the compression seems to buffer content indefinitely, without ever flushing the streaming data when it's small enough.
Here is an example demonstrating the problem
```rust
use actix_web::{
get, middleware,
web::{self, Bytes},
App, HttpResponse, HttpServer,
};
use futures::stream::{self, StreamExt};
use std::time::Duration;
use tokio::time::sleep;
#[get("/")]
async fn index() -> HttpResponse {
let stream = stream::once(async {
let initial_content = r#"
Streaming HTML Example
"#;
Ok::<_, std::io::Error>(Bytes::from(initial_content))
})
.chain(stream::once(async {
sleep(Duration::from_secs(5)).await;
let delayed_content = r#"
"#;
Ok::<_, std::io::Error>(Bytes::from(delayed_content))
}));
HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.streaming(stream)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(
web::scope("/compressed")
.wrap(middleware::Compress::default())
.service(index),
)
.service(index)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
```
## Expected Behavior
- When visiting I should see `This content appears immediately` immediateley, and then after 5 seconds `This content appears after 5 seconds`
- When visiting http://localhost:8080/compressed/ the behavior should be the same, or as close as possible.
## Current Behavior
- When visiting http://localhost:8080/compressed/ the page stays blank for five seconds, then displays `This content appears immediately` and `This content appears after 5 seconds` at the same time.
## Possible Solution
The compression middleware should flush the writer object after a few milliseconds without new input data, to avoid indefinitely retaining data in memory on the server when it could actually already be rendered on the client.
It's possible to retain data in memory for a few milliseconds to ensure good compression ratios, but actix shouldn't keep streaming data in memory for multiple seconds.
## Context
We are trying to integrate easy native loading spinners without javascript in [SQLPage](https://sql.ophir.dev)
## Your Environment
- Actix Web Version: 4.8.0
Guia de contribuição
Avaliação
Esta issue ainda não foi avaliada.