Exclude partial content from compression

This commit is contained in:
Alex 2021-12-10 16:40:05 +01:00
parent e3a030ceaf
commit 7488d8e907
No known key found for this signature in database
GPG key ID: EDABF9711E244EB1
2 changed files with 39 additions and 29 deletions

View file

@ -93,7 +93,7 @@ impl CertStore {
for dom in domains.iter() {
match t_last_check.get(dom) {
Some(t) if Instant::now() - *t < Duration::from_secs(3600) => continue,
Some(t) if Instant::now() - *t < Duration::from_secs(60) => continue,
_ => t_last_check.insert(dom.to_string(), Instant::now()),
};
@ -179,7 +179,7 @@ impl CertStore {
}
// ---- Acquire lock ----
// the lock is acquired for fifteen minutes,
// the lock is acquired for half an hour,
// so that in case of an error we won't retry before
// that delay expires
@ -190,8 +190,8 @@ impl CertStore {
.create_session(&ConsulSessionRequest {
name: lock_name.clone(),
node: None,
lock_delay: Some("15m".into()),
ttl: Some("30m".into()),
lock_delay: Some("30m".into()),
ttl: Some("45m".into()),
behavior: Some("delete".into()),
})
.await?;

View file

@ -10,6 +10,7 @@ use async_compression::tokio::bufread::*;
use futures::StreamExt;
use futures::TryStreamExt;
use http::header::{HeaderName, HeaderValue};
use http::method::Method;
use hyper::server::conn::Http;
use hyper::service::service_fn;
use hyper::{header, Body, Request, Response, StatusCode};
@ -164,7 +165,7 @@ async fn handle(
info!("{} {} {}", method, response.status().as_u16(), uri);
if https_config.enable_compression {
try_compress(response, accept_encoding, &https_config).await
try_compress(response, method, accept_encoding, &https_config).await
} else {
Ok(response)
}
@ -180,9 +181,21 @@ async fn handle(
async fn try_compress(
response: Response<Body>,
method: Method,
accept_encoding: Vec<(Option<Encoding>, f32)>,
https_config: &HttpsConfig,
) -> Result<Response<Body>> {
// Don't bother compressing successfull responses for HEAD and PUT (they should have an empty body)
// Don't compress partial content, that would be wierd
// If already compressed, return as is
if (response.status().is_success() && (method == Method::HEAD || method == Method::PUT))
|| response.status() == StatusCode::PARTIAL_CONTENT
|| response.headers().get(header::CONTENT_ENCODING).is_some()
{
return Ok(response);
}
// Select preferred encoding among those proposed in accept_encoding
let max_q: f32 = accept_encoding
.iter()
.max_by_key(|(_, q)| (q * 10000f32) as i64)
@ -208,11 +221,6 @@ async fn try_compress(
Some(enc) => enc,
};
// If already compressed, return as is
if response.headers().get(header::CONTENT_ENCODING).is_some() {
return Ok(response);
}
// If content type not in mime types for which to compress, return as is
match response.headers().get(header::CONTENT_TYPE) {
Some(ct) => {
@ -229,7 +237,7 @@ async fn try_compress(
return Ok(response);
}
}
None => return Ok(response),
None => return Ok(response), // don't compress if unknown mime type
};
let (mut head, mut body) = response.into_parts();
@ -257,34 +265,36 @@ async fn try_compress(
let body_rd =
StreamReader::new(body.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)));
debug!(
trace!(
"Compressing response body as {:?} (at least {} bytes)",
encoding, sum_lengths
encoding,
sum_lengths
);
// we don't know the compressed content-length so remove that header
head.headers.remove(header::CONTENT_LENGTH);
let compressed_body = match encoding {
Encoding::Gzip => {
head.headers
.insert(header::CONTENT_ENCODING, "gzip".parse()?);
Body::wrap_stream(ReaderStream::new(GzipEncoder::new(body_rd)))
}
let (encoding, compressed_body) = match encoding {
Encoding::Gzip => (
"gzip",
Body::wrap_stream(ReaderStream::new(GzipEncoder::new(body_rd))),
),
// Encoding::Brotli => {
// head.headers.insert(header::CONTENT_ENCODING, "br".parse()?);
// Body::wrap_stream(ReaderStream::new(BrotliEncoder::new(body_rd)))
// }
Encoding::Deflate => {
head.headers
.insert(header::CONTENT_ENCODING, "deflate".parse()?);
Body::wrap_stream(ReaderStream::new(DeflateEncoder::new(body_rd)))
}
Encoding::Zstd => {
head.headers
.insert(header::CONTENT_ENCODING, "zstd".parse()?);
Body::wrap_stream(ReaderStream::new(ZstdEncoder::new(body_rd)))
}
Encoding::Deflate => (
"deflate",
Body::wrap_stream(ReaderStream::new(DeflateEncoder::new(body_rd))),
),
Encoding::Zstd => (
"zstd",
Body::wrap_stream(ReaderStream::new(ZstdEncoder::new(body_rd))),
),
_ => unreachable!(),
};
head.headers
.insert(header::CONTENT_ENCODING, encoding.parse()?);
Ok(Response::from_parts(head, compressed_body))
}