mirror of
https://github.com/fafhrd91/actix-web
synced 2025-08-22 13:45:13 +02:00
Add zstd ContentEncoding support (#2244)
Co-authored-by: Igor Aleksanov <popzxc@yandex.ru> Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
@@ -12,6 +12,7 @@ use brotli2::write::BrotliDecoder;
|
||||
use bytes::Bytes;
|
||||
use flate2::write::{GzDecoder, ZlibDecoder};
|
||||
use futures_core::{ready, Stream};
|
||||
use zstd::stream::write::Decoder as ZstdDecoder;
|
||||
|
||||
use crate::{
|
||||
encoding::Writer,
|
||||
@@ -45,6 +46,12 @@ where
|
||||
ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(
|
||||
GzDecoder::new(Writer::new()),
|
||||
))),
|
||||
ContentEncoding::Zstd => Some(ContentDecoder::Zstd(Box::new(
|
||||
ZstdDecoder::new(Writer::new()).expect(
|
||||
"Failed to create zstd decoder. This is a bug. \
|
||||
Please report it to the actix-web repository.",
|
||||
),
|
||||
))),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@@ -144,6 +151,9 @@ enum ContentDecoder {
|
||||
Deflate(Box<ZlibDecoder<Writer>>),
|
||||
Gzip(Box<GzDecoder<Writer>>),
|
||||
Br(Box<BrotliDecoder<Writer>>),
|
||||
// We need explicit 'static lifetime here because ZstdDecoder need lifetime
|
||||
// argument, and we use `spawn_blocking` in `Decoder::poll_next` that require `FnOnce() -> R + Send + 'static`
|
||||
Zstd(Box<ZstdDecoder<'static, Writer>>),
|
||||
}
|
||||
|
||||
impl ContentDecoder {
|
||||
@@ -186,6 +196,18 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
|
||||
ContentDecoder::Zstd(ref mut decoder) => match decoder.flush() {
|
||||
Ok(_) => {
|
||||
let b = decoder.get_mut().take();
|
||||
if !b.is_empty() {
|
||||
Ok(Some(b))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +254,20 @@ impl ContentDecoder {
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
|
||||
ContentDecoder::Zstd(ref mut decoder) => match decoder.write_all(&data) {
|
||||
Ok(_) => {
|
||||
decoder.flush()?;
|
||||
|
||||
let b = decoder.get_mut().take();
|
||||
if !b.is_empty() {
|
||||
Ok(Some(b))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user