http2: decompress zstd encoding

Ticket: 7904
pull/16253/head
Philippe Antoine 3 months ago committed by Victor Julien
parent 103abc2d33
commit 8873259fc9

@ -21,7 +21,8 @@ use brotli::{BrotliDecompressStream, BrotliResult, BrotliState, HeapAlloc, Huffm
use flate2::read::{DeflateDecoder, GzDecoder};
use std;
use std::io;
use std::io::{Cursor, Read, Write};
use std::io::{BufReader, Cursor, Read, Write};
use zstd;
pub const HTTP2_DECOMPRESSION_CHUNK_SIZE: usize = 0x1000; // 4096
@ -34,7 +35,8 @@ pub enum HTTP2ContentEncoding {
Gzip = 1,
Br = 2,
Deflate = 3,
Unrecognized = 4,
Zstd = 4,
Unrecognized = 5,
}
//a cursor turning EOF into blocking errors
@ -148,6 +150,9 @@ pub enum HTTP2Decompresser {
// This one is not so large, at 88 bytes as of doing this, but box
// for consistency.
Deflate(Box<DeflateDecoder<HTTP2cursor>>),
// usage of 'static, alternative could be trait instead of enum
Zstd(Box<zstd::stream::read::Decoder<'static, BufReader<HTTP2cursor>>>),
}
impl std::fmt::Debug for HTTP2Decompresser {
@ -157,6 +162,7 @@ impl std::fmt::Debug for HTTP2Decompresser {
HTTP2Decompresser::Gzip(_) => write!(f, "GZIP"),
HTTP2Decompresser::Brotli(_) => write!(f, "BROTLI"),
HTTP2Decompresser::Deflate(_) => write!(f, "DEFLATE"),
HTTP2Decompresser::Zstd(_) => write!(f, "ZSTD"),
}
}
}
@ -191,6 +197,12 @@ impl GetMutCursor for BrotliDecompressor {
}
}
impl GetMutCursor for zstd::stream::read::Decoder<'_, BufReader<HTTP2cursor>> {
fn get_mut(&mut self) -> &mut HTTP2cursor {
return self.get_mut().get_mut();
}
}
fn http2_decompress<'a>(
decoder: &mut (impl Read + GetMutCursor), input: &'a [u8], output: &'a mut Vec<u8>,
) -> io::Result<&'a [u8]> {
@ -259,6 +271,19 @@ impl HTTP2DecoderHalf {
self.decoder = HTTP2Decompresser::Brotli(Box::new(BrotliDecompressor::new(
HTTP2cursor::new(),
)));
} else if input.eq_ignore_ascii_case(b"zstd") {
self.encoding = HTTP2ContentEncoding::Zstd;
if let Ok(mut z) = zstd::stream::read::Decoder::new(HTTP2cursor::new()) {
if z.window_log_max(23).is_ok() {
self.decoder = HTTP2Decompresser::Zstd(Box::new(z));
} else {
SCLogWarning!("Failed to set zstd window log max");
self.decoder = HTTP2Decompresser::Unassigned;
}
} else {
SCLogWarning!("Failed to create zstd decoder");
self.decoder = HTTP2Decompresser::Unassigned;
}
} else {
self.encoding = HTTP2ContentEncoding::Unrecognized;
}
@ -295,6 +320,19 @@ impl HTTP2DecoderHalf {
self.input_len += input.len() as u64;
return r;
}
HTTP2Decompresser::Zstd(ref mut zstd_decoder) => {
let r = http2_decompress(&mut *zstd_decoder.as_mut(), input, output);
match r {
Err(_) => {
self.decoder = HTTP2Decompresser::Unassigned;
}
Ok(o) => {
self.output_len += o.len() as u64;
}
}
self.input_len += input.len() as u64;
return r;
}
HTTP2Decompresser::Deflate(ref mut df_decoder) => {
let r = http2_decompress(&mut *df_decoder.as_mut(), input, output);
match r {

Loading…
Cancel
Save