This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new ea8ad983e4 compress plugin: refactor compression algorithms into their 
own files (#12590)
ea8ad983e4 is described below

commit ea8ad983e48aafd346aa42ea647b465ec9e77c28
Author: Jake Champion <[email protected]>
AuthorDate: Mon Oct 27 22:20:15 2025 +0000

    compress plugin: refactor compression algorithms into their own files 
(#12590)
    
    this separates gzip/deflate and brotli compression implementations into 
dedicated modules with their own namespaces
    
    the intention behind this is to make is simpler to contribute new 
compression algorithms to the compress plugin and to try and keep the main 
plugin file contents centered around the compressing feature and not the 
implementation of each compression algorithm option
---
 plugins/compress/CMakeLists.txt     |   5 +-
 plugins/compress/brotli_compress.cc | 148 ++++++++++++++
 plugins/compress/brotli_compress.h  |  46 +++++
 plugins/compress/compress.cc        | 386 +++++++++---------------------------
 plugins/compress/compress_common.cc |  37 ++++
 plugins/compress/compress_common.h  |  76 +++++++
 plugins/compress/configuration.cc   |   4 +-
 plugins/compress/configuration.h    |   4 +-
 plugins/compress/gzip_compress.cc   | 169 ++++++++++++++++
 plugins/compress/gzip_compress.h    |  51 +++++
 plugins/compress/misc.cc            |  22 --
 plugins/compress/misc.h             |  64 ------
 12 files changed, 624 insertions(+), 388 deletions(-)

diff --git a/plugins/compress/CMakeLists.txt b/plugins/compress/CMakeLists.txt
index f630bf0d1c..6744d69d47 100644
--- a/plugins/compress/CMakeLists.txt
+++ b/plugins/compress/CMakeLists.txt
@@ -15,10 +15,13 @@
 #
 #######################
 
-add_atsplugin(compress compress.cc configuration.cc misc.cc)
+add_atsplugin(compress compress.cc configuration.cc misc.cc compress_common.cc 
gzip_compress.cc)
 target_link_libraries(compress PRIVATE libswoc::libswoc)
+
 if(HAVE_BROTLI_ENCODE_H)
+  target_sources(compress PRIVATE brotli_compress.cc)
   target_link_libraries(compress PRIVATE brotli::brotlienc)
+  target_compile_definitions(compress PRIVATE HAVE_BROTLI_ENCODE_H=1)
 endif()
 verify_global_plugin(compress)
 verify_remap_plugin(compress)
diff --git a/plugins/compress/brotli_compress.cc 
b/plugins/compress/brotli_compress.cc
new file mode 100644
index 0000000000..da0eb29997
--- /dev/null
+++ b/plugins/compress/brotli_compress.cc
@@ -0,0 +1,148 @@
+/** @file
+
+  Brotli compression implementation
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "brotli_compress.h"
+
+#if HAVE_BROTLI_ENCODE_H
+
+#include "debug_macros.h"
+
+#include <brotli/encode.h>
+#include <cinttypes>
+
+namespace Brotli
+{
+const int BROTLI_COMPRESSION_LEVEL = 6;
+const int BROTLI_LGW               = 16;
+
+static bool
+compress_operation(Data *data, const char *upstream_buffer, int64_t 
upstream_length, BrotliEncoderOperation op)
+{
+  TSIOBufferBlock downstream_blkp;
+  int64_t         downstream_length;
+
+  data->bstrm.next_in  = (uint8_t *)upstream_buffer;
+  data->bstrm.avail_in = upstream_length;
+
+  bool ok = true;
+  while (ok) {
+    downstream_blkp         = TSIOBufferStart(data->downstream_buffer);
+    char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, 
&downstream_length);
+
+    data->bstrm.next_out  = reinterpret_cast<unsigned char 
*>(downstream_buffer);
+    data->bstrm.avail_out = downstream_length;
+    data->bstrm.total_out = 0;
+
+    ok =
+      !!BrotliEncoderCompressStream(data->bstrm.br, op, &data->bstrm.avail_in, 
&const_cast<const uint8_t *&>(data->bstrm.next_in),
+                                    &data->bstrm.avail_out, 
&data->bstrm.next_out, &data->bstrm.total_out);
+
+    if (!ok) {
+      error("BrotliEncoderCompressStream(%d) call failed", op);
+      return false;
+    }
+
+    TSIOBufferProduce(data->downstream_buffer, downstream_length - 
data->bstrm.avail_out);
+    data->downstream_length += (downstream_length - data->bstrm.avail_out);
+    if (data->bstrm.avail_in || BrotliEncoderHasMoreOutput(data->bstrm.br)) {
+      continue;
+    }
+
+    break;
+  }
+
+  return ok;
+}
+
+void
+data_alloc(Data *data)
+{
+  debug("brotli compression. Create Brotli Encoder Instance.");
+  data->bstrm.br = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
+  if (!data->bstrm.br) {
+    fatal("Brotli Encoder Instance Failed");
+  }
+  BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_QUALITY, 
BROTLI_COMPRESSION_LEVEL);
+  BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_LGWIN, BROTLI_LGW);
+  data->bstrm.next_in   = nullptr;
+  data->bstrm.avail_in  = 0;
+  data->bstrm.total_in  = 0;
+  data->bstrm.next_out  = nullptr;
+  data->bstrm.avail_out = 0;
+  data->bstrm.total_out = 0;
+}
+
+void
+data_destroy(Data *data)
+{
+  BrotliEncoderDestroyInstance(data->bstrm.br);
+}
+
+void
+transform_one(Data *data, const char *upstream_buffer, int64_t upstream_length)
+{
+  bool ok = compress_operation(data, upstream_buffer, upstream_length, 
BROTLI_OPERATION_PROCESS);
+  if (!ok) {
+    error("BrotliEncoderCompressStream(PROCESS) call failed");
+    return;
+  }
+
+  data->bstrm.total_in += upstream_length;
+
+  if (!data->hc->flush()) {
+    return;
+  }
+
+  ok = compress_operation(data, nullptr, 0, BROTLI_OPERATION_FLUSH);
+  if (!ok) {
+    error("BrotliEncoderCompressStream(FLUSH) call failed");
+    return;
+  }
+}
+
+void
+transform_finish(Data *data)
+{
+  if (data->state != transform_state_output) {
+    return;
+  }
+
+  data->state = transform_state_finished;
+
+  bool ok = compress_operation(data, nullptr, 0, BROTLI_OPERATION_FINISH);
+  if (!ok) {
+    error("BrotliEncoderCompressStream(PROCESS) call failed");
+    return;
+  }
+
+  if (data->downstream_length != static_cast<int64_t>(data->bstrm.total_out)) {
+    error("brotli-transform: output lengths don't match (%" PRId64 ", %zu)", 
data->downstream_length, data->bstrm.total_out);
+  }
+
+  debug("brotli-transform: Finished brotli");
+  log_compression_ratio(data->bstrm.total_in, data->downstream_length);
+}
+
+} // namespace Brotli
+
+#endif // HAVE_BROTLI_ENCODE_H
diff --git a/plugins/compress/brotli_compress.h 
b/plugins/compress/brotli_compress.h
new file mode 100644
index 0000000000..40be1b9036
--- /dev/null
+++ b/plugins/compress/brotli_compress.h
@@ -0,0 +1,46 @@
+/** @file
+
+  Brotli compression implementation
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include "compress_common.h"
+
+#if HAVE_BROTLI_ENCODE_H
+
+namespace Brotli
+{
+// Initialize brotli compression context
+void data_alloc(Data *data);
+
+// Destroy brotli compression context
+void data_destroy(Data *data);
+
+// Compress one chunk of data
+void transform_one(Data *data, const char *upstream_buffer, int64_t 
upstream_length);
+
+// Finish compression and flush remaining data
+void transform_finish(Data *data);
+
+} // namespace Brotli
+
+#endif // HAVE_BROTLI_ENCODE_H
diff --git a/plugins/compress/compress.cc b/plugins/compress/compress.cc
index 5290d9ec11..319059ea56 100644
--- a/plugins/compress/compress.cc
+++ b/plugins/compress/compress.cc
@@ -23,28 +23,25 @@
 
 #include <cstring>
 #include <cinttypes>
-#include <zlib.h>
 
 #include "ts/apidefs.h"
 #include "tscore/ink_config.h"
 
 #include <tsutil/PostScript.h>
 
-#if HAVE_BROTLI_ENCODE_H
-#include <brotli/encode.h>
-#endif
-
 #include "ts/ts.h"
 #include "tscore/ink_defs.h"
 
 #include "debug_macros.h"
+#include "compress_common.h"
 #include "misc.h"
 #include "configuration.h"
+#include "gzip_compress.h"
+#include "brotli_compress.h"
 #include "ts/remap.h"
 #include "ts/remap_version.h"
 
 using namespace std;
-using namespace Gzip;
 
 // FIXME: custom dictionaries would be nice. configurable/content-type?
 // a GPRS device might benefit from a higher compression ratio, whereas a 
desktop w. high bandwidth
@@ -63,14 +60,10 @@ namespace compress_ns
 DbgCtl dbg_ctl{TAG};
 }
 
-const int   ZLIB_COMPRESSION_LEVEL = 6;
-const char *dictionary             = nullptr;
+namespace Compress
+{
 
-// brotli compression quality 1-11. Testing proved level '6'
-#if HAVE_BROTLI_ENCODE_H
-const int BROTLI_COMPRESSION_LEVEL = 6;
-const int BROTLI_LGW               = 16;
-#endif
+const char *dictionary = nullptr;
 
 static const char *global_hidden_header_name = nullptr;
 
@@ -82,66 +75,65 @@ Configuration *prev_config = nullptr;
 
 namespace
 {
-/**
-  If client request has both of Range and Accept-Encoding header, follow 
range-request config.
- */
-void
-handle_range_request(TSMBuffer req_buf, TSMLoc req_loc, HostConfiguration *hc)
-{
-  TSMLoc accept_encoding_hdr_field =
-    TSMimeHdrFieldFind(req_buf, req_loc, TS_MIME_FIELD_ACCEPT_ENCODING, 
TS_MIME_LEN_ACCEPT_ENCODING);
-  ts::PostScript accept_encoding_defer([&]() -> void { 
TSHandleMLocRelease(req_buf, req_loc, accept_encoding_hdr_field); });
-  if (accept_encoding_hdr_field == TS_NULL_MLOC) {
-    return;
-  }
+  /**
+    If client request has both of Range and Accept-Encoding header, follow 
range-request config.
+    */
+  void
+  handle_range_request(TSMBuffer req_buf, TSMLoc req_loc, HostConfiguration 
*hc)
+  {
+    TSMLoc accept_encoding_hdr_field =
+      TSMimeHdrFieldFind(req_buf, req_loc, TS_MIME_FIELD_ACCEPT_ENCODING, 
TS_MIME_LEN_ACCEPT_ENCODING);
+    ts::PostScript accept_encoding_defer([&]() -> void { 
TSHandleMLocRelease(req_buf, req_loc, accept_encoding_hdr_field); });
+    if (accept_encoding_hdr_field == TS_NULL_MLOC) {
+      return;
+    }
 
-  TSMLoc         range_hdr_field = TSMimeHdrFieldFind(req_buf, req_loc, 
TS_MIME_FIELD_RANGE, TS_MIME_LEN_RANGE);
-  ts::PostScript range_defer([&]() -> void { TSHandleMLocRelease(req_buf, 
req_loc, range_hdr_field); });
-  if (range_hdr_field == TS_NULL_MLOC) {
-    return;
-  }
+    TSMLoc         range_hdr_field = TSMimeHdrFieldFind(req_buf, req_loc, 
TS_MIME_FIELD_RANGE, TS_MIME_LEN_RANGE);
+    ts::PostScript range_defer([&]() -> void { TSHandleMLocRelease(req_buf, 
req_loc, range_hdr_field); });
+    if (range_hdr_field == TS_NULL_MLOC) {
+      return;
+    }
 
-  debug("Both of Accept-Encoding and Range header are found in the request");
+    debug("Both of Accept-Encoding and Range header are found in the request");
 
-  switch (hc->range_request_ctl()) {
-  case RangeRequestCtrl::REMOVE_RANGE: {
-    debug("Remove the Range header by remove-range config");
-    while (range_hdr_field) {
-      TSMLoc next_dup = TSMimeHdrFieldNextDup(req_buf, req_loc, 
range_hdr_field);
-      TSMimeHdrFieldDestroy(req_buf, req_loc, range_hdr_field);
-      TSHandleMLocRelease(req_buf, req_loc, range_hdr_field);
-      range_hdr_field = next_dup;
+    switch (hc->range_request_ctl()) {
+    case RangeRequestCtrl::REMOVE_RANGE: {
+      debug("Remove the Range header by remove-range config");
+      while (range_hdr_field) {
+        TSMLoc next_dup = TSMimeHdrFieldNextDup(req_buf, req_loc, 
range_hdr_field);
+        TSMimeHdrFieldDestroy(req_buf, req_loc, range_hdr_field);
+        TSHandleMLocRelease(req_buf, req_loc, range_hdr_field);
+        range_hdr_field = next_dup;
+      }
+      break;
     }
-    break;
-  }
-  case RangeRequestCtrl::REMOVE_ACCEPT_ENCODING: {
-    debug("Remove the Accept-Encoding header by remove-accept-encoding 
config");
-    while (accept_encoding_hdr_field) {
-      TSMLoc next_dup = TSMimeHdrFieldNextDup(req_buf, req_loc, 
accept_encoding_hdr_field);
-      TSMimeHdrFieldDestroy(req_buf, req_loc, accept_encoding_hdr_field);
-      TSHandleMLocRelease(req_buf, req_loc, accept_encoding_hdr_field);
-      accept_encoding_hdr_field = next_dup;
+    case RangeRequestCtrl::REMOVE_ACCEPT_ENCODING: {
+      debug("Remove the Accept-Encoding header by remove-accept-encoding 
config");
+      while (accept_encoding_hdr_field) {
+        TSMLoc next_dup = TSMimeHdrFieldNextDup(req_buf, req_loc, 
accept_encoding_hdr_field);
+        TSMimeHdrFieldDestroy(req_buf, req_loc, accept_encoding_hdr_field);
+        TSHandleMLocRelease(req_buf, req_loc, accept_encoding_hdr_field);
+        accept_encoding_hdr_field = next_dup;
+      }
+      break;
+    }
+    case RangeRequestCtrl::NO_COMPRESSION:
+      // Do NOT touch header - this config is referred by `transformable()` 
function
+      debug("no header modification by no-compression config");
+      break;
+    case RangeRequestCtrl::NONE:
+      [[fallthrough]];
+    default:
+      debug("Do nothing by none config");
+      break;
     }
-    break;
-  }
-  case RangeRequestCtrl::NO_COMPRESSION:
-    // Do NOT touch header - this config is referred by `transformable()` 
function
-    debug("no header modification by no-compression config");
-    break;
-  case RangeRequestCtrl::NONE:
-    [[fallthrough]];
-  default:
-    debug("Do nothing by none config");
-    break;
   }
-}
 } // namespace
 
 static Data *
-data_alloc(int compression_type, int compression_algorithms)
+data_alloc(int compression_type, int compression_algorithms, HostConfiguration 
*hc)
 {
   Data *data;
-  int   err;
 
   data                         = static_cast<Data *>(TSmalloc(sizeof(Data)));
   data->downstream_vio         = nullptr;
@@ -151,50 +143,17 @@ data_alloc(int compression_type, int 
compression_algorithms)
   data->state                  = transform_state_initialized;
   data->compression_type       = compression_type;
   data->compression_algorithms = compression_algorithms;
-  data->zstrm.next_in          = Z_NULL;
-  data->zstrm.avail_in         = 0;
-  data->zstrm.total_in         = 0;
-  data->zstrm.next_out         = Z_NULL;
-  data->zstrm.avail_out        = 0;
-  data->zstrm.total_out        = 0;
-  data->zstrm.zalloc           = gzip_alloc;
-  data->zstrm.zfree            = gzip_free;
-  data->zstrm.opaque           = (voidpf) nullptr;
-  data->zstrm.data_type        = Z_ASCII;
-
-  int window_bits = WINDOW_BITS_GZIP;
-  if (compression_type & COMPRESSION_TYPE_DEFLATE) {
-    window_bits = WINDOW_BITS_DEFLATE;
-  }
+  data->hc                     = hc;
 
-  err = deflateInit2(&data->zstrm, ZLIB_COMPRESSION_LEVEL, Z_DEFLATED, 
window_bits, ZLIB_MEMLEVEL, Z_DEFAULT_STRATEGY);
-
-  if (err != Z_OK) {
-    fatal("gzip-transform: ERROR: deflateInit (%d)!", err);
+  // Initialize algorithm-specific compression contexts
+  if ((compression_type & (COMPRESSION_TYPE_GZIP | COMPRESSION_TYPE_DEFLATE)) 
&&
+      (compression_algorithms & (ALGORITHM_GZIP | ALGORITHM_DEFLATE))) {
+    Gzip::data_alloc(data);
   }
 
-  if (dictionary) {
-    err = deflateSetDictionary(&data->zstrm, reinterpret_cast<const Bytef 
*>(dictionary), strlen(dictionary));
-    if (err != Z_OK) {
-      fatal("gzip-transform: ERROR: deflateSetDictionary (%d)!", err);
-    }
-  }
 #if HAVE_BROTLI_ENCODE_H
-  data->bstrm.br = nullptr;
-  if (compression_type & COMPRESSION_TYPE_BROTLI) {
-    debug("brotli compression. Create Brotli Encoder Instance.");
-    data->bstrm.br = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
-    if (!data->bstrm.br) {
-      fatal("Brotli Encoder Instance Failed");
-    }
-    BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_QUALITY, 
BROTLI_COMPRESSION_LEVEL);
-    BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_LGWIN, BROTLI_LGW);
-    data->bstrm.next_in   = nullptr;
-    data->bstrm.avail_in  = 0;
-    data->bstrm.total_in  = 0;
-    data->bstrm.next_out  = nullptr;
-    data->bstrm.avail_out = 0;
-    data->bstrm.total_out = 0;
+  if (compression_type & COMPRESSION_TYPE_BROTLI && compression_algorithms & 
ALGORITHM_BROTLI) {
+    Brotli::data_alloc(data);
   }
 #endif
   return data;
@@ -205,17 +164,20 @@ data_destroy(Data *data)
 {
   TSReleaseAssert(data);
 
-  // deflateEnd return value ignore is intentional
-  // it would spew log on every client abort
-  deflateEnd(&data->zstrm);
-
   if (data->downstream_buffer) {
     TSIOBufferDestroy(data->downstream_buffer);
   }
 
-// brotlidestory
+  // Destroy algorithm-specific compression contexts
+  if ((data->compression_type & (COMPRESSION_TYPE_GZIP | 
COMPRESSION_TYPE_DEFLATE)) &&
+      (data->compression_algorithms & (ALGORITHM_GZIP | ALGORITHM_DEFLATE))) {
+    Gzip::data_destroy(data);
+  }
+
 #if HAVE_BROTLI_ENCODE_H
-  BrotliEncoderDestroyInstance(data->bstrm.br);
+  if (data->compression_type & COMPRESSION_TYPE_BROTLI && 
data->compression_algorithms & ALGORITHM_BROTLI) {
+    Brotli::data_destroy(data);
+  }
 #endif
 
   TSfree(data);
@@ -241,7 +203,6 @@ content_encoding_header(TSMBuffer bufp, TSMLoc hdr_loc, 
const int compression_ty
   }
 
   if (value_len == 0) {
-    error("no need to add Content-Encoding header");
     return TS_SUCCESS;
   }
 
@@ -365,108 +326,6 @@ compress_transform_init(TSCont contp, Data *data)
   TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
 }
 
-static void
-gzip_transform_one(Data *data, const char *upstream_buffer, int64_t 
upstream_length)
-{
-  TSIOBufferBlock downstream_blkp;
-  int64_t         downstream_length;
-  int             err;
-  data->zstrm.next_in  = (unsigned char *)upstream_buffer;
-  data->zstrm.avail_in = upstream_length;
-
-  while (data->zstrm.avail_in > 0) {
-    downstream_blkp         = TSIOBufferStart(data->downstream_buffer);
-    char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, 
&downstream_length);
-
-    data->zstrm.next_out  = reinterpret_cast<unsigned char 
*>(downstream_buffer);
-    data->zstrm.avail_out = downstream_length;
-
-    if (!data->hc->flush()) {
-      err = deflate(&data->zstrm, Z_NO_FLUSH);
-    } else {
-      err = deflate(&data->zstrm, Z_SYNC_FLUSH);
-    }
-
-    if (err != Z_OK) {
-      warning("deflate() call failed: %d", err);
-    }
-
-    if (downstream_length > data->zstrm.avail_out) {
-      TSIOBufferProduce(data->downstream_buffer, downstream_length - 
data->zstrm.avail_out);
-      data->downstream_length += (downstream_length - data->zstrm.avail_out);
-    }
-
-    if (data->zstrm.avail_out > 0) {
-      if (data->zstrm.avail_in != 0) {
-        error("gzip-transform: avail_in is (%d): should be 0", 
data->zstrm.avail_in);
-      }
-    }
-  }
-}
-
-#if HAVE_BROTLI_ENCODE_H
-static bool
-brotli_compress_operation(Data *data, const char *upstream_buffer, int64_t 
upstream_length, BrotliEncoderOperation op)
-{
-  TSIOBufferBlock downstream_blkp;
-  int64_t         downstream_length;
-
-  data->bstrm.next_in  = (uint8_t *)upstream_buffer;
-  data->bstrm.avail_in = upstream_length;
-
-  bool ok = true;
-  while (ok) {
-    downstream_blkp         = TSIOBufferStart(data->downstream_buffer);
-    char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, 
&downstream_length);
-
-    data->bstrm.next_out  = reinterpret_cast<unsigned char 
*>(downstream_buffer);
-    data->bstrm.avail_out = downstream_length;
-    data->bstrm.total_out = 0;
-
-    ok =
-      !!BrotliEncoderCompressStream(data->bstrm.br, op, &data->bstrm.avail_in, 
&const_cast<const uint8_t *&>(data->bstrm.next_in),
-                                    &data->bstrm.avail_out, 
&data->bstrm.next_out, &data->bstrm.total_out);
-
-    if (!ok) {
-      error("BrotliEncoderCompressStream(%d) call failed", op);
-      return false;
-    }
-
-    TSIOBufferProduce(data->downstream_buffer, downstream_length - 
data->bstrm.avail_out);
-    data->downstream_length += (downstream_length - data->bstrm.avail_out);
-    if (data->bstrm.avail_in || BrotliEncoderHasMoreOutput(data->bstrm.br)) {
-      continue;
-    }
-
-    break;
-  }
-
-  return ok;
-}
-
-static void
-brotli_transform_one(Data *data, const char *upstream_buffer, int64_t 
upstream_length)
-{
-  bool ok = brotli_compress_operation(data, upstream_buffer, upstream_length, 
BROTLI_OPERATION_PROCESS);
-  if (!ok) {
-    error("BrotliEncoderCompressStream(PROCESS) call failed");
-    return;
-  }
-
-  data->bstrm.total_in += upstream_length;
-
-  if (!data->hc->flush()) {
-    return;
-  }
-
-  ok = brotli_compress_operation(data, nullptr, 0, BROTLI_OPERATION_FLUSH);
-  if (!ok) {
-    error("BrotliEncoderCompressStream(FLUSH) call failed");
-    return;
-  }
-}
-#endif
-
 static void
 compress_transform_one(Data *data, TSIOBufferReader upstream_reader, int 
amount)
 {
@@ -491,12 +350,12 @@ compress_transform_one(Data *data, TSIOBufferReader 
upstream_reader, int amount)
 
 #if HAVE_BROTLI_ENCODE_H
     if (data->compression_type & COMPRESSION_TYPE_BROTLI && 
(data->compression_algorithms & ALGORITHM_BROTLI)) {
-      brotli_transform_one(data, upstream_buffer, upstream_length);
+      Brotli::transform_one(data, upstream_buffer, upstream_length);
     } else
 #endif
       if ((data->compression_type & (COMPRESSION_TYPE_GZIP | 
COMPRESSION_TYPE_DEFLATE)) &&
           (data->compression_algorithms & (ALGORITHM_GZIP | 
ALGORITHM_DEFLATE))) {
-      gzip_transform_one(data, upstream_buffer, upstream_length);
+      Gzip::transform_one(data, upstream_buffer, upstream_length);
     } else {
       warning("No compression supported. Shouldn't come here.");
     }
@@ -506,85 +365,18 @@ compress_transform_one(Data *data, TSIOBufferReader 
upstream_reader, int amount)
   }
 }
 
-static void
-gzip_transform_finish(Data *data)
-{
-  if (data->state == transform_state_output) {
-    TSIOBufferBlock downstream_blkp;
-    int64_t         downstream_length;
-
-    data->state = transform_state_finished;
-
-    for (;;) {
-      downstream_blkp = TSIOBufferStart(data->downstream_buffer);
-
-      char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, 
&downstream_length);
-      data->zstrm.next_out    = reinterpret_cast<unsigned char 
*>(downstream_buffer);
-      data->zstrm.avail_out   = downstream_length;
-
-      int err = deflate(&data->zstrm, Z_FINISH);
-
-      if (downstream_length > static_cast<int64_t>(data->zstrm.avail_out)) {
-        TSIOBufferProduce(data->downstream_buffer, downstream_length - 
data->zstrm.avail_out);
-        data->downstream_length += (downstream_length - data->zstrm.avail_out);
-      }
-
-      if (err == Z_OK) { /* some more data to encode */
-        continue;
-      }
-
-      if (err != Z_STREAM_END) {
-        warning("deflate should report Z_STREAM_END");
-      }
-      break;
-    }
-
-    if (data->downstream_length != 
static_cast<int64_t>(data->zstrm.total_out)) {
-      error("gzip-transform: output lengths don't match (%" PRId64 ", %lu)", 
data->downstream_length, data->zstrm.total_out);
-    }
-
-    debug("gzip-transform: Finished gzip");
-    log_compression_ratio(data->zstrm.total_in, data->downstream_length);
-  }
-}
-
-#if HAVE_BROTLI_ENCODE_H
-static void
-brotli_transform_finish(Data *data)
-{
-  if (data->state != transform_state_output) {
-    return;
-  }
-
-  data->state = transform_state_finished;
-
-  bool ok = brotli_compress_operation(data, nullptr, 0, 
BROTLI_OPERATION_FINISH);
-  if (!ok) {
-    error("BrotliEncoderCompressStream(PROCESS) call failed");
-    return;
-  }
-
-  if (data->downstream_length != static_cast<int64_t>(data->bstrm.total_out)) {
-    error("brotli-transform: output lengths don't match (%" PRId64 ", %zu)", 
data->downstream_length, data->bstrm.total_out);
-  }
-
-  debug("brotli-transform: Finished brotli");
-  log_compression_ratio(data->bstrm.total_in, data->downstream_length);
-}
-#endif
-
 static void
 compress_transform_finish(Data *data)
 {
 #if HAVE_BROTLI_ENCODE_H
   if (data->compression_type & COMPRESSION_TYPE_BROTLI && 
data->compression_algorithms & ALGORITHM_BROTLI) {
-    brotli_transform_finish(data);
+    Brotli::transform_finish(data);
     debug("compress_transform_finish: brotli compression finish");
   } else
 #endif
     if ((data->compression_type & (COMPRESSION_TYPE_GZIP | 
COMPRESSION_TYPE_DEFLATE)) &&
         (data->compression_algorithms & (ALGORITHM_GZIP | ALGORITHM_DEFLATE))) 
{
-    gzip_transform_finish(data);
+    Gzip::transform_finish(data);
     debug("compress_transform_finish: gzip compression finish");
   } else {
     error("No Compression matched, shouldn't come here");
@@ -888,9 +680,8 @@ compress_transform_add(TSHttpTxn txnp, HostConfiguration 
*hc, int compress_type,
   }
 
   connp     = TSTransformCreate(compress_transform, txnp);
-  data      = data_alloc(compress_type, algorithms);
+  data      = data_alloc(compress_type, algorithms, hc);
   data->txn = txnp;
-  data->hc  = hc;
 
   TSContDataSet(connp, data);
   TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);
@@ -1091,12 +882,13 @@ management_update(TSCont contp, TSEvent event, void * /* 
edata ATS_UNUSED */)
 
   return 0;
 }
+} // namespace Compress
 
 void
 TSPluginInit(int argc, const char *argv[])
 {
-  const char *config_path = nullptr;
-  compress_config_mutex   = TSMutexCreate();
+  const char *config_path         = nullptr;
+  Compress::compress_config_mutex = TSMutexCreate();
 
   if (argc > 2) {
     fatal("the compress plugin does not accept more than 1 plugin argument");
@@ -1110,19 +902,19 @@ TSPluginInit(int argc, const char *argv[])
 
   info("TSPluginInit %s", argv[0]);
 
-  if (!global_hidden_header_name) {
-    global_hidden_header_name = init_hidden_header_name();
+  if (!Compress::global_hidden_header_name) {
+    Compress::global_hidden_header_name = init_hidden_header_name();
   }
 
-  TSCont management_contp = TSContCreate(management_update, nullptr);
+  TSCont management_contp = TSContCreate(Compress::management_update, nullptr);
 
   // Make sure the global configuration is properly loaded and reloaded on 
changes
   TSContDataSet(management_contp, (void *)config_path);
   TSMgmtUpdateRegister(management_contp, TAG);
-  load_global_configuration(management_contp);
+  Compress::load_global_configuration(management_contp);
 
   // Setup the global hook, main entry point for kicking off the plugin
-  TSCont transform_global_contp = TSContCreate(transform_global_plugin, 
nullptr);
+  TSCont transform_global_contp = 
TSContCreate(Compress::transform_global_plugin, nullptr);
 
   TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, transform_global_contp);
   info("loaded");
@@ -1152,12 +944,12 @@ TSRemapNewInstance(int argc, char *argv[], void 
**instance, char * /* errbuf ATS
   } else {
     config_path = TSstrdup(3 == argc ? argv[2] : "");
   }
-  if (!global_hidden_header_name) {
-    global_hidden_header_name = init_hidden_header_name();
+  if (!Compress::global_hidden_header_name) {
+    Compress::global_hidden_header_name = init_hidden_header_name();
   }
 
-  Configuration *config = Configuration::Parse(config_path);
-  *instance             = config;
+  Compress::Configuration *config = 
Compress::Configuration::Parse(config_path);
+  *instance                       = config;
 
   free((void *)config_path);
   info("Configuration loaded");
@@ -1168,7 +960,7 @@ void
 TSRemapDeleteInstance(void *instance)
 {
   debug("Cleanup configs read from remap");
-  auto c = static_cast<Configuration *>(instance);
+  auto c = static_cast<Compress::Configuration *>(instance);
   delete c;
 }
 
@@ -1179,7 +971,7 @@ TSRemapDoRemap(void *instance, TSHttpTxn txnp, 
TSRemapRequestInfo * /* rri ATS_U
     info("No Rules configured, falling back to default");
   } else {
     info("Remap Rules configured for compress");
-    Configuration *config = static_cast<Configuration *>(instance);
+    Compress::Configuration *config = static_cast<Compress::Configuration 
*>(instance);
     // Handle compress request and use the configs populated from remap 
instance
     handle_request(txnp, config);
   }
diff --git a/plugins/compress/compress_common.cc 
b/plugins/compress/compress_common.cc
new file mode 100644
index 0000000000..f5b3a2d230
--- /dev/null
+++ b/plugins/compress/compress_common.cc
@@ -0,0 +1,37 @@
+/** @file
+
+  Common types and utilities for compression plugin
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "compress_common.h"
+#include "debug_macros.h"
+
+#include <cinttypes>
+
+void
+log_compression_ratio(int64_t in, int64_t out)
+{
+  if (in) {
+    info("Compressed size %" PRId64 " (bytes), Original size %" PRId64 ", 
ratio: %f", out, in, ((float)(in - out) / in));
+  } else {
+    debug("Compressed size %" PRId64 " (bytes), Original size %" PRId64 ", 
ratio: %f", out, in, 0.0F);
+  }
+}
diff --git a/plugins/compress/compress_common.h 
b/plugins/compress/compress_common.h
new file mode 100644
index 0000000000..1dccd4aa25
--- /dev/null
+++ b/plugins/compress/compress_common.h
@@ -0,0 +1,76 @@
+/** @file
+
+  Common types and structures for compression plugin
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include <zlib.h>
+#include <ts/ts.h>
+
+#if HAVE_BROTLI_ENCODE_H
+#include <brotli/encode.h>
+#endif
+
+#include "configuration.h"
+
+enum CompressionType {
+  COMPRESSION_TYPE_DEFAULT = 0,
+  COMPRESSION_TYPE_DEFLATE = 1,
+  COMPRESSION_TYPE_GZIP    = 2,
+  COMPRESSION_TYPE_BROTLI  = 4
+};
+
+enum transform_state {
+  transform_state_initialized,
+  transform_state_output,
+  transform_state_finished,
+};
+
+#if HAVE_BROTLI_ENCODE_H
+struct BrotliStream {
+  BrotliEncoderState *br;
+  uint8_t            *next_in;
+  size_t              avail_in;
+  uint8_t            *next_out;
+  size_t              avail_out;
+  size_t              total_in;
+  size_t              total_out;
+};
+#endif
+
+struct Data {
+  TSHttpTxn                    txn;
+  Compress::HostConfiguration *hc;
+  TSVIO                        downstream_vio;
+  TSIOBuffer                   downstream_buffer;
+  TSIOBufferReader             downstream_reader;
+  int64_t                      downstream_length;
+  z_stream                     zstrm;
+  enum transform_state         state;
+  int                          compression_type;
+  int                          compression_algorithms;
+#if HAVE_BROTLI_ENCODE_H
+  BrotliStream bstrm;
+#endif
+};
+
+void log_compression_ratio(int64_t in, int64_t out);
diff --git a/plugins/compress/configuration.cc 
b/plugins/compress/configuration.cc
index 167ea8da89..9b76ffa619 100644
--- a/plugins/compress/configuration.cc
+++ b/plugins/compress/configuration.cc
@@ -38,7 +38,7 @@
 
 #include <cctype>
 
-namespace Gzip
+namespace Compress
 {
 swoc::TextView
 extractFirstToken(swoc::TextView &view, int (*fp)(int))
@@ -410,4 +410,4 @@ Configuration::Parse(const char *path)
 
   return c;
 } // Configuration::Parse
-} // namespace Gzip
+} // namespace Compress
diff --git a/plugins/compress/configuration.h b/plugins/compress/configuration.h
index 1929130788..3af37b10c0 100644
--- a/plugins/compress/configuration.h
+++ b/plugins/compress/configuration.h
@@ -31,7 +31,7 @@
 #include "tscpp/api/noncopyable.h"
 #include "swoc/TextView.h"
 
-namespace Gzip
+namespace Compress
 {
 using StringContainer = std::vector<std::string>;
 
@@ -189,4 +189,4 @@ private:
 
 }; // class Configuration
 
-} // namespace Gzip
+} // namespace Compress
diff --git a/plugins/compress/gzip_compress.cc 
b/plugins/compress/gzip_compress.cc
new file mode 100644
index 0000000000..9de74ab072
--- /dev/null
+++ b/plugins/compress/gzip_compress.cc
@@ -0,0 +1,169 @@
+/** @file
+
+  Gzip/Deflate compression implementation
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "gzip_compress.h"
+#include "debug_macros.h"
+
+#include <zlib.h>
+#include <cinttypes>
+
+const char *dictionary = nullptr;
+
+namespace Gzip
+{
+const int ZLIB_COMPRESSION_LEVEL = 6;
+voidpf
+gzip_alloc(voidpf /* opaque ATS_UNUSED */, uInt items, uInt size)
+{
+  return static_cast<voidpf>(TSmalloc(items * size));
+}
+
+void
+gzip_free(voidpf /* opaque ATS_UNUSED */, voidpf address)
+{
+  TSfree(address);
+}
+
+void
+data_alloc(Data *data)
+{
+  int window_bits = WINDOW_BITS_GZIP;
+  if (data->compression_type & COMPRESSION_TYPE_DEFLATE) {
+    window_bits = WINDOW_BITS_DEFLATE;
+  }
+
+  data->zstrm.next_in   = Z_NULL;
+  data->zstrm.avail_in  = 0;
+  data->zstrm.total_in  = 0;
+  data->zstrm.next_out  = Z_NULL;
+  data->zstrm.avail_out = 0;
+  data->zstrm.total_out = 0;
+  data->zstrm.zalloc    = Gzip::gzip_alloc;
+  data->zstrm.zfree     = Gzip::gzip_free;
+  data->zstrm.opaque    = (voidpf) nullptr;
+  data->zstrm.data_type = Z_ASCII;
+
+  int err = deflateInit2(&data->zstrm, ZLIB_COMPRESSION_LEVEL, Z_DEFLATED, 
window_bits, ZLIB_MEMLEVEL, Z_DEFAULT_STRATEGY);
+
+  if (err != Z_OK) {
+    fatal("gzip-transform: ERROR: deflateInit (%d)!", err);
+  }
+
+  if (dictionary) {
+    err = deflateSetDictionary(&data->zstrm, reinterpret_cast<const Bytef 
*>(dictionary), strlen(dictionary));
+    if (err != Z_OK) {
+      fatal("gzip-transform: ERROR: deflateSetDictionary (%d)!", err);
+    }
+  }
+}
+
+void
+data_destroy(Data *data)
+{
+  // deflateEnd return value ignore is intentional
+  // it would spew log on every client abort
+  deflateEnd(&data->zstrm);
+}
+
+void
+transform_one(Data *data, const char *upstream_buffer, int64_t upstream_length)
+{
+  TSIOBufferBlock downstream_blkp;
+  int64_t         downstream_length;
+  int             err;
+  data->zstrm.next_in  = (unsigned char *)upstream_buffer;
+  data->zstrm.avail_in = upstream_length;
+
+  while (data->zstrm.avail_in > 0) {
+    downstream_blkp         = TSIOBufferStart(data->downstream_buffer);
+    char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, 
&downstream_length);
+
+    data->zstrm.next_out  = reinterpret_cast<unsigned char 
*>(downstream_buffer);
+    data->zstrm.avail_out = downstream_length;
+
+    if (!data->hc->flush()) {
+      err = deflate(&data->zstrm, Z_NO_FLUSH);
+    } else {
+      err = deflate(&data->zstrm, Z_SYNC_FLUSH);
+    }
+
+    if (err != Z_OK) {
+      warning("deflate() call failed: %d", err);
+    }
+
+    if (downstream_length > data->zstrm.avail_out) {
+      TSIOBufferProduce(data->downstream_buffer, downstream_length - 
data->zstrm.avail_out);
+      data->downstream_length += (downstream_length - data->zstrm.avail_out);
+    }
+
+    if (data->zstrm.avail_out > 0) {
+      if (data->zstrm.avail_in != 0) {
+        error("gzip-transform: avail_in is (%d): should be 0", 
data->zstrm.avail_in);
+      }
+    }
+  }
+}
+
+void
+transform_finish(Data *data)
+{
+  if (data->state == transform_state_output) {
+    TSIOBufferBlock downstream_blkp;
+    int64_t         downstream_length;
+
+    data->state = transform_state_finished;
+
+    for (;;) {
+      downstream_blkp = TSIOBufferStart(data->downstream_buffer);
+
+      char *downstream_buffer = TSIOBufferBlockWriteStart(downstream_blkp, 
&downstream_length);
+      data->zstrm.next_out    = reinterpret_cast<unsigned char 
*>(downstream_buffer);
+      data->zstrm.avail_out   = downstream_length;
+
+      int err = deflate(&data->zstrm, Z_FINISH);
+
+      if (downstream_length > static_cast<int64_t>(data->zstrm.avail_out)) {
+        TSIOBufferProduce(data->downstream_buffer, downstream_length - 
data->zstrm.avail_out);
+        data->downstream_length += (downstream_length - data->zstrm.avail_out);
+      }
+
+      if (err == Z_OK) { /* some more data to encode */
+        continue;
+      }
+
+      if (err != Z_STREAM_END) {
+        warning("deflate should report Z_STREAM_END");
+      }
+      break;
+    }
+
+    if (data->downstream_length != 
static_cast<int64_t>(data->zstrm.total_out)) {
+      error("gzip-transform: output lengths don't match (%" PRId64 ", %lu)", 
data->downstream_length, data->zstrm.total_out);
+    }
+
+    debug("gzip-transform: Finished gzip");
+    log_compression_ratio(data->zstrm.total_in, data->downstream_length);
+  }
+}
+
+} // namespace Gzip
diff --git a/plugins/compress/gzip_compress.h b/plugins/compress/gzip_compress.h
new file mode 100644
index 0000000000..5257bb4bb4
--- /dev/null
+++ b/plugins/compress/gzip_compress.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Gzip/Deflate compression implementation
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include "compress_common.h"
+#include <zlib.h>
+
+// zlib stuff, see [deflateInit2] at http://www.zlib.net/manual.html
+static const int ZLIB_MEMLEVEL       = 9; // min=1 (optimize for memory),max=9 
(optimized for speed)
+static const int WINDOW_BITS_DEFLATE = -15;
+static const int WINDOW_BITS_GZIP    = 31;
+
+namespace Gzip
+{
+// Initialize gzip/deflate compression context
+void data_alloc(Data *data);
+
+// Destroy gzip/deflate compression context
+void data_destroy(Data *data);
+
+// Compress one chunk of data
+void transform_one(Data *data, const char *upstream_buffer, int64_t 
upstream_length);
+
+// Finish compression and flush remaining data
+void transform_finish(Data *data);
+
+voidpf gzip_alloc(voidpf opaque, uInt items, uInt size);
+void   gzip_free(voidpf opaque, voidpf address);
+
+} // namespace Gzip
diff --git a/plugins/compress/misc.cc b/plugins/compress/misc.cc
index a1b33b79cc..9a4b7f6685 100644
--- a/plugins/compress/misc.cc
+++ b/plugins/compress/misc.cc
@@ -30,18 +30,6 @@
 #include <cinttypes>
 #include "debug_macros.h"
 
-voidpf
-gzip_alloc(voidpf /* opaque ATS_UNUSED */, uInt items, uInt size)
-{
-  return static_cast<voidpf>(TSmalloc(items * size));
-}
-
-void
-gzip_free(voidpf /* opaque ATS_UNUSED */, voidpf address)
-{
-  TSfree(address);
-}
-
 namespace
 {
 // Strips parameters from value.  Returns cleared TextView if a q=f parameter 
present, where f is less than or equal to
@@ -190,13 +178,3 @@ register_plugin()
   }
   return 1;
 }
-
-void
-log_compression_ratio(int64_t in, int64_t out)
-{
-  if (in) {
-    info("Compressed size %" PRId64 " (bytes), Original size %" PRId64 ", 
ratio: %f", out, in, ((float)(in - out) / in));
-  } else {
-    debug("Compressed size %" PRId64 " (bytes), Original size %" PRId64 ", 
ratio: %f", out, in, 0.0F);
-  }
-}
diff --git a/plugins/compress/misc.h b/plugins/compress/misc.h
index a18f1dce71..f5d37c1da4 100644
--- a/plugins/compress/misc.h
+++ b/plugins/compress/misc.h
@@ -23,74 +23,10 @@
 
 #pragma once
 
-#include <zlib.h>
 #include <ts/ts.h>
-#include <cstdlib>
-#include <cstdio>
 
-#if HAVE_BROTLI_ENCODE_H
-#include <brotli/encode.h>
-#endif
-
-#include "configuration.h"
-
-// zlib stuff, see [deflateInit2] at http://www.zlib.net/manual.html
-static const int ZLIB_MEMLEVEL       = 9; // min=1 (optimize for memory),max=9 
(optimized for speed)
-static const int WINDOW_BITS_DEFLATE = -15;
-static const int WINDOW_BITS_GZIP    = 31;
-
-// misc
-enum CompressionType {
-  COMPRESSION_TYPE_DEFAULT = 0,
-  COMPRESSION_TYPE_DEFLATE = 1,
-  COMPRESSION_TYPE_GZIP    = 2,
-  COMPRESSION_TYPE_BROTLI  = 4
-};
-
-// this one is used to rename the accept encoding header
-// it will be restored later on
-// to make it work, the name must be different then downstream proxies though
-// otherwise the downstream will restore the accept encoding header
-
-enum transform_state {
-  transform_state_initialized,
-  transform_state_output,
-  transform_state_finished,
-};
-
-#if HAVE_BROTLI_ENCODE_H
-using b_stream = struct {
-  BrotliEncoderState *br;
-  uint8_t            *next_in;
-  size_t              avail_in;
-  uint8_t            *next_out;
-  size_t              avail_out;
-  size_t              total_in;
-  size_t              total_out;
-};
-#endif
-
-using Data = struct {
-  TSHttpTxn                txn;
-  Gzip::HostConfiguration *hc;
-  TSVIO                    downstream_vio;
-  TSIOBuffer               downstream_buffer;
-  TSIOBufferReader         downstream_reader;
-  int64_t                  downstream_length;
-  z_stream                 zstrm;
-  enum transform_state     state;
-  int                      compression_type;
-  int                      compression_algorithms;
-#if HAVE_BROTLI_ENCODE_H
-  b_stream bstrm;
-#endif
-};
-
-voidpf      gzip_alloc(voidpf opaque, uInt items, uInt size);
-void        gzip_free(voidpf opaque, voidpf address);
 void        normalize_accept_encoding(TSHttpTxn txnp, TSMBuffer reqp, TSMLoc 
hdr_loc);
 void        hide_accept_encoding(TSHttpTxn txnp, TSMBuffer reqp, TSMLoc 
hdr_loc, const char *hidden_header_name);
 void        restore_accept_encoding(TSHttpTxn txnp, TSMBuffer reqp, TSMLoc 
hdr_loc, const char *hidden_header_name);
 const char *init_hidden_header_name();
 int         register_plugin();
-void        log_compression_ratio(int64_t in, int64_t out);


Reply via email to