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 } }