79 lines
2.6 KiB
Rust
79 lines
2.6 KiB
Rust
use crate::settings::PanelCompression;
|
|
use axum::{body::Body, response::Response};
|
|
use bytes::Bytes;
|
|
use flate2::{write::GzEncoder, Compression};
|
|
use http::{header, HeaderMap, HeaderValue};
|
|
use std::io::Write;
|
|
|
|
pub(super) struct PanelContent {
|
|
plain: Bytes,
|
|
gzip: Bytes,
|
|
brotli: Bytes,
|
|
zstd: Bytes,
|
|
}
|
|
|
|
impl PanelContent {
|
|
pub(super) fn new(raw: &'static str) -> Self {
|
|
let mut gzip = GzEncoder::new(Vec::new(), Compression::default());
|
|
gzip.write_all(raw.as_bytes()).expect("compress panel gzip");
|
|
let gzip = Bytes::from(gzip.finish().expect("finish panel gzip"));
|
|
let mut br = Vec::new();
|
|
{
|
|
let mut writer = brotli::CompressorWriter::new(&mut br, 4096, 5, 22);
|
|
writer
|
|
.write_all(raw.as_bytes())
|
|
.expect("compress panel Brotli");
|
|
}
|
|
let zstd = zstd::stream::encode_all(raw.as_bytes(), 3).expect("compress panel zstd");
|
|
Self {
|
|
plain: Bytes::from_static(raw.as_bytes()),
|
|
gzip,
|
|
brotli: Bytes::from(br),
|
|
zstd: Bytes::from(zstd),
|
|
}
|
|
}
|
|
|
|
pub(super) fn response(
|
|
&self,
|
|
headers: &HeaderMap,
|
|
codecs: &PanelCompression,
|
|
mime: &'static str,
|
|
) -> Response {
|
|
let settings = crate::compression::Settings {
|
|
gzip: codecs.gzip,
|
|
br: codecs.br,
|
|
zstd: codecs.zstd,
|
|
deflate: false,
|
|
min_bytes: 1024,
|
|
};
|
|
let encoding = if crate::compression::no_transform(headers) {
|
|
None
|
|
} else {
|
|
crate::compression::preferred_encoding(headers, &settings)
|
|
};
|
|
let (body, name) = match encoding.map(|codec| codec.as_str()) {
|
|
Some("zstd") => (self.zstd.clone(), Some("zstd")),
|
|
Some("br") => (self.brotli.clone(), Some("br")),
|
|
Some("gzip") => (self.gzip.clone(), Some("gzip")),
|
|
_ => (self.plain.clone(), None),
|
|
};
|
|
let mut response = Response::new(Body::from(body.clone()));
|
|
response
|
|
.headers_mut()
|
|
.insert(header::CONTENT_TYPE, HeaderValue::from_static(mime));
|
|
response.headers_mut().insert(
|
|
header::CONTENT_LENGTH,
|
|
HeaderValue::from_str(&body.len().to_string()).expect("valid length"),
|
|
);
|
|
if let Some(name) = name {
|
|
response
|
|
.headers_mut()
|
|
.insert(header::CONTENT_ENCODING, HeaderValue::from_static(name));
|
|
}
|
|
response
|
|
.headers_mut()
|
|
.insert(header::VARY, HeaderValue::from_static("Accept-Encoding"));
|
|
response
|
|
}
|
|
}
|