summaryrefslogtreecommitdiff
path: root/ext/http
diff options
context:
space:
mode:
authorud2 <sjx233@qq.com>2024-06-20 23:14:24 +0800
committerGitHub <noreply@github.com>2024-06-20 20:44:24 +0530
commit88e3f465d3a95db277ac7e685a0ed239958f8e6e (patch)
tree55d2b17abe8f31e8e47c6936f91e5743b20e55c3 /ext/http
parent6ab143335a402965943eb42114c29d0ba02c9a8e (diff)
refactor(ext): remove use of `brotli::ffi` (#24214)
Diffstat (limited to 'ext/http')
-rw-r--r--ext/http/Cargo.toml2
-rw-r--r--ext/http/response_body.rs143
2 files changed, 44 insertions, 101 deletions
diff --git a/ext/http/Cargo.toml b/ext/http/Cargo.toml
index e5fed0750..4b5755d89 100644
--- a/ext/http/Cargo.toml
+++ b/ext/http/Cargo.toml
@@ -24,7 +24,7 @@ harness = false
async-compression = { version = "0.4", features = ["tokio", "brotli", "gzip"] }
async-trait.workspace = true
base64.workspace = true
-brotli = "3.3.4"
+brotli.workspace = true
bytes.workspace = true
cache_control.workspace = true
deno_core.workspace = true
diff --git a/ext/http/response_body.rs b/ext/http/response_body.rs
index 3c25265d7..42080e8c9 100644
--- a/ext/http/response_body.rs
+++ b/ext/http/response_body.rs
@@ -3,8 +3,10 @@ use std::io::Write;
use std::pin::Pin;
use std::rc::Rc;
+use brotli::enc::encode::BrotliEncoderOperation;
use brotli::enc::encode::BrotliEncoderParameter;
-use brotli::ffi::compressor::BrotliEncoderState;
+use brotli::enc::encode::BrotliEncoderStateStruct;
+use brotli::writer::StandardAlloc;
use bytes::Bytes;
use bytes::BytesMut;
use deno_core::error::AnyError;
@@ -448,58 +450,24 @@ enum BrotliState {
EndOfStream,
}
-struct BrotliEncoderStateWrapper {
- stm: *mut BrotliEncoderState,
-}
-
#[pin_project]
pub struct BrotliResponseStream {
state: BrotliState,
- stm: BrotliEncoderStateWrapper,
- current_cursor: usize,
- output_written_so_far: usize,
+ stm: BrotliEncoderStateStruct<StandardAlloc>,
#[pin]
underlying: ResponseStream,
}
-impl Drop for BrotliEncoderStateWrapper {
- fn drop(&mut self) {
- // SAFETY: since we are dropping, we can be sure that this instance will not
- // be used again.
- unsafe {
- brotli::ffi::compressor::BrotliEncoderDestroyInstance(self.stm);
- }
- }
-}
-
impl BrotliResponseStream {
pub fn new(underlying: ResponseStream) -> Self {
- // SAFETY: creating an FFI instance should be OK with these args.
- let stm = unsafe {
- let stm = brotli::ffi::compressor::BrotliEncoderCreateInstance(
- None,
- None,
- std::ptr::null_mut(),
- );
- // Quality level 6 is based on google's nginx default value for on-the-fly compression
- // https://github.com/google/ngx_brotli#brotli_comp_level
- // lgwin 22 is equivalent to brotli window size of (2**22)-16 bytes (~4MB)
- brotli::ffi::compressor::BrotliEncoderSetParameter(
- stm,
- BrotliEncoderParameter::BROTLI_PARAM_QUALITY,
- 6,
- );
- brotli::ffi::compressor::BrotliEncoderSetParameter(
- stm,
- BrotliEncoderParameter::BROTLI_PARAM_LGWIN,
- 22,
- );
- BrotliEncoderStateWrapper { stm }
- };
+ let mut stm = BrotliEncoderStateStruct::new(StandardAlloc::default());
+ // Quality level 6 is based on google's nginx default value for on-the-fly compression
+ // https://github.com/google/ngx_brotli#brotli_comp_level
+ // lgwin 22 is equivalent to brotli window size of (2**22)-16 bytes (~4MB)
+ stm.set_parameter(BrotliEncoderParameter::BROTLI_PARAM_QUALITY, 6);
+ stm.set_parameter(BrotliEncoderParameter::BROTLI_PARAM_LGWIN, 22);
Self {
stm,
- output_written_so_far: 0,
- current_cursor: 0,
state: BrotliState::Streaming,
underlying,
}
@@ -546,71 +514,46 @@ impl PollFrame for BrotliResponseStream {
let res = match frame {
ResponseStreamResult::NonEmptyBuf(buf) => {
- let mut output_written = 0;
- let mut total_output_written = 0;
- let mut input_size = buf.len();
- let input_buffer = buf.as_ref();
- let mut len = max_compressed_size(input_size);
- let mut output_buffer = vec![0u8; len];
- let mut ob_ptr = output_buffer.as_mut_ptr();
-
- // SAFETY: these are okay arguments to these FFI calls.
- unsafe {
- brotli::ffi::compressor::BrotliEncoderCompressStream(
- this.stm.stm,
- brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_PROCESS,
- &mut input_size,
- &input_buffer.as_ptr() as *const *const u8 as *mut *const u8,
- &mut len,
- &mut ob_ptr,
- &mut output_written,
- );
- total_output_written += output_written;
- output_written = 0;
-
- brotli::ffi::compressor::BrotliEncoderCompressStream(
- this.stm.stm,
- brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FLUSH,
- &mut input_size,
- &input_buffer.as_ptr() as *const *const u8 as *mut *const u8,
- &mut len,
- &mut ob_ptr,
- &mut output_written,
- );
- total_output_written += output_written;
- };
-
- output_buffer
- .truncate(total_output_written - this.output_written_so_far);
- this.output_written_so_far = total_output_written;
+ let mut output_buffer = vec![0; max_compressed_size(buf.len())];
+ let mut output_offset = 0;
+
+ this.stm.compress_stream(
+ BrotliEncoderOperation::BROTLI_OPERATION_FLUSH,
+ &mut buf.len(),
+ &buf,
+ &mut 0,
+ &mut output_buffer.len(),
+ &mut output_buffer,
+ &mut output_offset,
+ &mut None,
+ &mut |_, _, _, _| (),
+ );
+
+ output_buffer.truncate(output_offset);
ResponseStreamResult::NonEmptyBuf(BufView::from(output_buffer))
}
ResponseStreamResult::EndOfStream => {
- let mut len = 1024usize;
- let mut output_buffer = vec![0u8; len];
- let mut input_size = 0;
- let mut output_written = 0;
- let ob_ptr = output_buffer.as_mut_ptr();
-
- // SAFETY: these are okay arguments to these FFI calls.
- unsafe {
- brotli::ffi::compressor::BrotliEncoderCompressStream(
- this.stm.stm,
- brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FINISH,
- &mut input_size,
- std::ptr::null_mut(),
- &mut len,
- &ob_ptr as *const *mut u8 as *mut *mut u8,
- &mut output_written,
- );
- };
-
- if output_written == 0 {
+ let mut output_buffer = vec![0; 1024];
+ let mut output_offset = 0;
+
+ this.stm.compress_stream(
+ BrotliEncoderOperation::BROTLI_OPERATION_FINISH,
+ &mut 0,
+ &[],
+ &mut 0,
+ &mut output_buffer.len(),
+ &mut output_buffer,
+ &mut output_offset,
+ &mut None,
+ &mut |_, _, _, _| (),
+ );
+
+ if output_offset == 0 {
this.state = BrotliState::EndOfStream;
ResponseStreamResult::EndOfStream
} else {
this.state = BrotliState::Flushing;
- output_buffer.truncate(output_written - this.output_written_so_far);
+ output_buffer.truncate(output_offset);
ResponseStreamResult::NonEmptyBuf(BufView::from(output_buffer))
}
}