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() { for dom in domains.iter() {
match t_last_check.get(dom) { 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()), _ => t_last_check.insert(dom.to_string(), Instant::now()),
}; };
@ -179,7 +179,7 @@ impl CertStore {
} }
// ---- Acquire lock ---- // ---- 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 // so that in case of an error we won't retry before
// that delay expires // that delay expires
@ -190,8 +190,8 @@ impl CertStore {
.create_session(&ConsulSessionRequest { .create_session(&ConsulSessionRequest {
name: lock_name.clone(), name: lock_name.clone(),
node: None, node: None,
lock_delay: Some("15m".into()), lock_delay: Some("30m".into()),
ttl: Some("30m".into()), ttl: Some("45m".into()),
behavior: Some("delete".into()), behavior: Some("delete".into()),
}) })
.await?; .await?;

View file

@ -10,6 +10,7 @@ use async_compression::tokio::bufread::*;
use futures::StreamExt; use futures::StreamExt;
use futures::TryStreamExt; use futures::TryStreamExt;
use http::header::{HeaderName, HeaderValue}; use http::header::{HeaderName, HeaderValue};
use http::method::Method;
use hyper::server::conn::Http; use hyper::server::conn::Http;
use hyper::service::service_fn; use hyper::service::service_fn;
use hyper::{header, Body, Request, Response, StatusCode}; use hyper::{header, Body, Request, Response, StatusCode};
@ -164,7 +165,7 @@ async fn handle(
info!("{} {} {}", method, response.status().as_u16(), uri); info!("{} {} {}", method, response.status().as_u16(), uri);
if https_config.enable_compression { if https_config.enable_compression {
try_compress(response, accept_encoding, &https_config).await try_compress(response, method, accept_encoding, &https_config).await
} else { } else {
Ok(response) Ok(response)
} }
@ -180,9 +181,21 @@ async fn handle(
async fn try_compress( async fn try_compress(
response: Response<Body>, response: Response<Body>,
method: Method,
accept_encoding: Vec<(Option<Encoding>, f32)>, accept_encoding: Vec<(Option<Encoding>, f32)>,
https_config: &HttpsConfig, https_config: &HttpsConfig,
) -> Result<Response<Body>> { ) -> 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 let max_q: f32 = accept_encoding
.iter() .iter()
.max_by_key(|(_, q)| (q * 10000f32) as i64) .max_by_key(|(_, q)| (q * 10000f32) as i64)
@ -208,11 +221,6 @@ async fn try_compress(
Some(enc) => enc, 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 // If content type not in mime types for which to compress, return as is
match response.headers().get(header::CONTENT_TYPE) { match response.headers().get(header::CONTENT_TYPE) {
Some(ct) => { Some(ct) => {
@ -229,7 +237,7 @@ async fn try_compress(
return Ok(response); 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(); let (mut head, mut body) = response.into_parts();
@ -257,34 +265,36 @@ async fn try_compress(
let body_rd = let body_rd =
StreamReader::new(body.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))); StreamReader::new(body.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)));
debug!( trace!(
"Compressing response body as {:?} (at least {} bytes)", "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); head.headers.remove(header::CONTENT_LENGTH);
let compressed_body = match encoding { let (encoding, compressed_body) = match encoding {
Encoding::Gzip => { Encoding::Gzip => (
head.headers "gzip",
.insert(header::CONTENT_ENCODING, "gzip".parse()?); Body::wrap_stream(ReaderStream::new(GzipEncoder::new(body_rd))),
Body::wrap_stream(ReaderStream::new(GzipEncoder::new(body_rd))) ),
}
// Encoding::Brotli => { // Encoding::Brotli => {
// head.headers.insert(header::CONTENT_ENCODING, "br".parse()?); // head.headers.insert(header::CONTENT_ENCODING, "br".parse()?);
// Body::wrap_stream(ReaderStream::new(BrotliEncoder::new(body_rd))) // Body::wrap_stream(ReaderStream::new(BrotliEncoder::new(body_rd)))
// } // }
Encoding::Deflate => { Encoding::Deflate => (
head.headers "deflate",
.insert(header::CONTENT_ENCODING, "deflate".parse()?); Body::wrap_stream(ReaderStream::new(DeflateEncoder::new(body_rd))),
Body::wrap_stream(ReaderStream::new(DeflateEncoder::new(body_rd))) ),
} Encoding::Zstd => (
Encoding::Zstd => { "zstd",
head.headers Body::wrap_stream(ReaderStream::new(ZstdEncoder::new(body_rd))),
.insert(header::CONTENT_ENCODING, "zstd".parse()?); ),
Body::wrap_stream(ReaderStream::new(ZstdEncoder::new(body_rd)))
}
_ => unreachable!(), _ => unreachable!(),
}; };
head.headers
.insert(header::CONTENT_ENCODING, encoding.parse()?);
Ok(Response::from_parts(head, compressed_body)) Ok(Response::from_parts(head, compressed_body))
} }