You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2018/08/27 07:05:52 UTC

[trafficserver] 02/05: Separate out some of HPACK logic into hdrs/

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

maskit pushed a commit to branch quic-latest
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 062b8f481c5fe176f3fc73f986a275da7e3a4318
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Mon Jul 23 10:17:58 2018 +0900

    Separate out some of HPACK logic into hdrs/
    
    Primitive representations and Huffman encoding can be shared with HPACK and QPACK.
---
 .gitignore                                |   2 +-
 proxy/{http2 => hdrs}/HuffmanCodec.cc     |   0
 proxy/{http2 => hdrs}/HuffmanCodec.h      |   0
 proxy/hdrs/Makefile.am                    |  23 +++-
 proxy/hdrs/XPACK.cc                       | 193 +++++++++++++++++++++++++++
 proxy/hdrs/XPACK.h                        |  36 +++++
 proxy/{http2 => hdrs}/test_Huffmancode.cc |   0
 proxy/http2/HPACK.cc                      | 212 ++++--------------------------
 proxy/http2/HPACK.h                       |   5 +-
 proxy/http2/HTTP2.cc                      |   1 -
 proxy/http2/Makefile.am                   |  16 +--
 proxy/http2/RegressionHPACK.cc            |  18 +--
 12 files changed, 285 insertions(+), 221 deletions(-)

diff --git a/.gitignore b/.gitignore
index 33e0c16..a97b112 100644
--- a/.gitignore
+++ b/.gitignore
@@ -122,8 +122,8 @@ iocore/eventsystem/test_MIOBufferWriter
 iocore/hostdb/test_RefCountCache
 
 proxy/hdrs/test_mime
+proxy/hdrs/test_Huffmancode
 proxy/http/test_ForwardedConfig
-proxy/http2/test_Huffmancode
 proxy/http2/test_Http2DependencyTree
 proxy/http2/test_HPACK
 proxy/http2/hpack-tests/results
diff --git a/proxy/http2/HuffmanCodec.cc b/proxy/hdrs/HuffmanCodec.cc
similarity index 100%
rename from proxy/http2/HuffmanCodec.cc
rename to proxy/hdrs/HuffmanCodec.cc
diff --git a/proxy/http2/HuffmanCodec.h b/proxy/hdrs/HuffmanCodec.h
similarity index 100%
rename from proxy/http2/HuffmanCodec.h
rename to proxy/hdrs/HuffmanCodec.h
diff --git a/proxy/hdrs/Makefile.am b/proxy/hdrs/Makefile.am
index f2e5c27..930962b 100644
--- a/proxy/hdrs/Makefile.am
+++ b/proxy/hdrs/Makefile.am
@@ -43,7 +43,11 @@ libhdrs_a_SOURCES = \
 	MIME.cc \
 	MIME.h \
 	URL.cc \
-	URL.h
+	URL.h \
+	HuffmanCodec.cc \
+	HuffmanCodec.h \
+	XPACK.cc \
+	XPACK.h
 
 if BUILD_TESTS
 libhdrs_a_SOURCES += \
@@ -61,9 +65,13 @@ load_http_hdr_LDADD = -L. -lhdrs \
 	$(top_builddir)/lib/ts/libtsutil.la \
 	@LIBTCL@
 
-check_PROGRAMS = test_mime
+check_PROGRAMS = \
+	test_mime \
+	test_Huffmancode
 
-TESTS = test_mime
+TESTS = \
+	test_mime \
+	test_Huffmancode
 
 test_mime_LDADD = -L. -lhdrs \
 	$(top_builddir)/lib/ts/libtsutil.la \
@@ -76,6 +84,15 @@ test_mime_LDADD = -L. -lhdrs \
 
 test_mime_SOURCES = test_mime.cc
 
+test_Huffmancode_LDADD = \
+	$(top_builddir)/lib/ts/libtsutil.la
+
+test_Huffmancode_SOURCES = \
+	test_Huffmancode.cc \
+	HuffmanCodec.cc \
+	HuffmanCodec.h
+
+
 #test_UNUSED_SOURCES = \
 #  test_urlhash.cc
 
diff --git a/proxy/hdrs/XPACK.cc b/proxy/hdrs/XPACK.cc
new file mode 100644
index 0000000..c537872
--- /dev/null
+++ b/proxy/hdrs/XPACK.cc
@@ -0,0 +1,193 @@
+/** @file
+
+  Common functions for HPACK and QPACK
+
+  @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 "ts/Arena.h"
+#include "ts/ink_memory.h"
+#include "XPACK.h"
+#include "HuffmanCodec.h"
+
+//
+// [RFC 7541] 5.1. Integer representation
+//
+int64_t
+xpack_decode_integer(uint64_t &dst, const uint8_t *buf_start, const uint8_t *buf_end, uint8_t n)
+{
+  if (buf_start >= buf_end) {
+    return XPACK_ERROR_COMPRESSION_ERROR;
+  }
+
+  const uint8_t *p = buf_start;
+
+  dst = (*p & ((1 << n) - 1));
+  if (dst == static_cast<uint64_t>(1 << n) - 1) {
+    int m = 0;
+    do {
+      if (++p >= buf_end) {
+        return XPACK_ERROR_COMPRESSION_ERROR;
+      }
+
+      uint64_t added_value = *p & 0x7f;
+      if ((UINT64_MAX >> m) < added_value) {
+        // Excessively large integer encodings - in value or octet
+        // length - MUST be treated as a decoding error.
+        return XPACK_ERROR_COMPRESSION_ERROR;
+      }
+      dst += added_value << m;
+      m += 7;
+    } while (*p & 0x80);
+  }
+
+  return p - buf_start + 1;
+}
+
+//
+// [RFC 7541] 5.2. String Literal Representation
+// return content from String Data (Length octets) with huffman decoding if it is encoded
+//
+int64_t
+xpack_decode_string(Arena &arena, char **str, uint64_t &str_length, const uint8_t *buf_start, const uint8_t *buf_end, uint8_t n)
+{
+  if (buf_start >= buf_end) {
+    return XPACK_ERROR_COMPRESSION_ERROR;
+  }
+
+  const uint8_t *p            = buf_start;
+  bool isHuffman              = *p & (0x01 << n);
+  uint64_t encoded_string_len = 0;
+  int64_t len                 = 0;
+
+  len = xpack_decode_integer(encoded_string_len, p, buf_end, n);
+  if (len == XPACK_ERROR_COMPRESSION_ERROR) {
+    return XPACK_ERROR_COMPRESSION_ERROR;
+  }
+  p += len;
+
+  if ((p + encoded_string_len) > buf_end) {
+    return XPACK_ERROR_COMPRESSION_ERROR;
+  }
+
+  if (isHuffman) {
+    // Allocate temporary area twice the size of before decoded data
+    *str = arena.str_alloc(encoded_string_len * 2);
+
+    len = huffman_decode(*str, p, encoded_string_len);
+    if (len < 0) {
+      return XPACK_ERROR_COMPRESSION_ERROR;
+    }
+    str_length = len;
+  } else {
+    *str = arena.str_alloc(encoded_string_len);
+
+    memcpy(*str, reinterpret_cast<const char *>(p), encoded_string_len);
+
+    str_length = encoded_string_len;
+  }
+
+  return p + encoded_string_len - buf_start;
+}
+
+//
+// [RFC 7541] 5.1. Integer representation
+//
+int64_t
+xpack_encode_integer(uint8_t *buf_start, const uint8_t *buf_end, uint64_t value, uint8_t n)
+{
+  if (buf_start >= buf_end) {
+    return -1;
+  }
+
+  uint8_t *p = buf_start;
+
+  if (value < (static_cast<uint64_t>(1 << n) - 1)) {
+    *(p++) = value;
+  } else {
+    *(p++) = (1 << n) - 1;
+    value -= (1 << n) - 1;
+    while (value >= 128) {
+      if (p >= buf_end) {
+        return -1;
+      }
+      *(p++) = (value & 0x7F) | 0x80;
+      value  = value >> 7;
+    }
+    if (p + 1 >= buf_end) {
+      return -1;
+    }
+    *(p++) = value;
+  }
+  return p - buf_start;
+}
+
+int64_t
+xpack_encode_string(uint8_t *buf_start, const uint8_t *buf_end, const char *value, uint64_t value_len, uint8_t n)
+{
+  uint8_t *p       = buf_start;
+  bool use_huffman = true;
+  char *data       = nullptr;
+  int64_t data_len = 0;
+
+  // TODO Choose whether to use Huffman encoding wisely
+
+  if (use_huffman && value_len) {
+    data = static_cast<char *>(ats_malloc(value_len * 4));
+    if (data == nullptr) {
+      return -1;
+    }
+    data_len = huffman_encode(reinterpret_cast<uint8_t *>(data), reinterpret_cast<const uint8_t *>(value), value_len);
+  }
+
+  // Length
+  const int64_t len = xpack_encode_integer(p, buf_end, data_len, n);
+  if (len == -1) {
+    if (use_huffman) {
+      ats_free(data);
+    }
+
+    return -1;
+  }
+
+  if (use_huffman) {
+    *p |= 0x01 << n;
+  }
+  p += len;
+
+  if (buf_end < p || buf_end - p < data_len) {
+    if (use_huffman) {
+      ats_free(data);
+    }
+
+    return -1;
+  }
+
+  // Value
+  if (data_len) {
+    memcpy(p, data, data_len);
+    p += data_len;
+  }
+
+  if (use_huffman) {
+    ats_free(data);
+  }
+
+  return p - buf_start;
+}
diff --git a/proxy/hdrs/XPACK.h b/proxy/hdrs/XPACK.h
new file mode 100644
index 0000000..5e8eca3
--- /dev/null
+++ b/proxy/hdrs/XPACK.h
@@ -0,0 +1,36 @@
+/** @file
+ *
+ *  A brief file description
+ *
+ *  @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 <cstdint>
+
+const static int XPACK_ERROR_COMPRESSION_ERROR   = -1;
+const static int XPACK_ERROR_SIZE_EXCEEDED_ERROR = -2;
+
+// These primitives are shared with HPACK and QPACK.
+int64_t xpack_encode_integer(uint8_t *buf_start, const uint8_t *buf_end, uint64_t value, uint8_t n);
+int64_t xpack_decode_integer(uint64_t &dst, const uint8_t *buf_start, const uint8_t *buf_end, uint8_t n);
+int64_t xpack_encode_string(uint8_t *buf_start, const uint8_t *buf_end, const char *value, uint64_t value_len, uint8_t n = 7);
+int64_t xpack_decode_string(Arena &arena, char **str, uint64_t &str_length, const uint8_t *buf_start, const uint8_t *buf_end,
+                            uint8_t n = 7);
diff --git a/proxy/http2/test_Huffmancode.cc b/proxy/hdrs/test_Huffmancode.cc
similarity index 100%
rename from proxy/http2/test_Huffmancode.cc
rename to proxy/hdrs/test_Huffmancode.cc
diff --git a/proxy/http2/HPACK.cc b/proxy/http2/HPACK.cc
index 1c45d1e..fd16460 100644
--- a/proxy/http2/HPACK.cc
+++ b/proxy/http2/HPACK.cc
@@ -409,92 +409,6 @@ HpackDynamicTable::length() const
   return _headers.size();
 }
 
-//
-// [RFC 7541] 5.1. Integer representation
-//
-int64_t
-encode_integer(uint8_t *buf_start, const uint8_t *buf_end, uint32_t value, uint8_t n)
-{
-  if (buf_start >= buf_end) {
-    return -1;
-  }
-
-  uint8_t *p = buf_start;
-
-  if (value < (static_cast<uint32_t>(1 << n) - 1)) {
-    *(p++) = value;
-  } else {
-    *(p++) = (1 << n) - 1;
-    value -= (1 << n) - 1;
-    while (value >= 128) {
-      if (p >= buf_end) {
-        return -1;
-      }
-      *(p++) = (value & 0x7F) | 0x80;
-      value  = value >> 7;
-    }
-    if (p + 1 >= buf_end) {
-      return -1;
-    }
-    *(p++) = value;
-  }
-  return p - buf_start;
-}
-
-int64_t
-encode_string(uint8_t *buf_start, const uint8_t *buf_end, const char *value, size_t value_len)
-{
-  uint8_t *p       = buf_start;
-  bool use_huffman = true;
-  char *data       = nullptr;
-  int64_t data_len = 0;
-
-  // TODO Choose whether to use Huffman encoding wisely
-
-  if (use_huffman && value_len) {
-    data = static_cast<char *>(ats_malloc(value_len * 4));
-    if (data == nullptr) {
-      return -1;
-    }
-    data_len = huffman_encode(reinterpret_cast<uint8_t *>(data), reinterpret_cast<const uint8_t *>(value), value_len);
-  }
-
-  // Length
-  const int64_t len = encode_integer(p, buf_end, data_len, 7);
-  if (len == -1) {
-    if (use_huffman) {
-      ats_free(data);
-    }
-
-    return -1;
-  }
-
-  if (use_huffman) {
-    *p |= 0x80;
-  }
-  p += len;
-
-  if (buf_end < p || buf_end - p < data_len) {
-    if (use_huffman) {
-      ats_free(data);
-    }
-
-    return -1;
-  }
-
-  // Value
-  if (data_len) {
-    memcpy(p, data, data_len);
-    p += data_len;
-  }
-
-  if (use_huffman) {
-    ats_free(data);
-  }
-
-  return p - buf_start;
-}
-
 int64_t
 encode_indexed_header_field(uint8_t *buf_start, const uint8_t *buf_end, uint32_t index)
 {
@@ -505,7 +419,7 @@ encode_indexed_header_field(uint8_t *buf_start, const uint8_t *buf_end, uint32_t
   uint8_t *p = buf_start;
 
   // Index
-  const int64_t len = encode_integer(p, buf_end, index, 7);
+  const int64_t len = xpack_encode_integer(p, buf_end, index, 7);
   if (len == -1) {
     return -1;
   }
@@ -551,7 +465,7 @@ encode_literal_header_field_with_indexed_name(uint8_t *buf_start, const uint8_t
   }
 
   // Index
-  len = encode_integer(p, buf_end, index, prefix);
+  len = xpack_encode_integer(p, buf_end, index, prefix);
   if (len == -1) {
     return -1;
   }
@@ -566,7 +480,7 @@ encode_literal_header_field_with_indexed_name(uint8_t *buf_start, const uint8_t
   // Value String
   int value_len;
   const char *value = header.value_get(&value_len);
-  len               = encode_string(p, buf_end, value, value_len);
+  len               = xpack_encode_string(p, buf_end, value, value_len);
   if (len == -1) {
     return -1;
   }
@@ -616,7 +530,7 @@ encode_literal_header_field_with_new_name(uint8_t *buf_start, const uint8_t *buf
   }
 
   // Name String
-  len = encode_string(p, buf_end, lower_name, name_len);
+  len = xpack_encode_string(p, buf_end, lower_name, name_len);
   if (len == -1) {
     return -1;
   }
@@ -625,7 +539,7 @@ encode_literal_header_field_with_new_name(uint8_t *buf_start, const uint8_t *buf
   // Value String
   int value_len;
   const char *value = header.value_get(&value_len);
-  len               = encode_string(p, buf_end, value, value_len);
+  len               = xpack_encode_string(p, buf_end, value, value_len);
   if (len == -1) {
     return -1;
   }
@@ -639,7 +553,7 @@ encode_literal_header_field_with_new_name(uint8_t *buf_start, const uint8_t *buf
 int64_t
 encode_dynamic_table_size_update(uint8_t *buf_start, const uint8_t *buf_end, uint32_t size)
 {
-  const int64_t len = encode_integer(buf_start, buf_end, size, 5);
+  const int64_t len = xpack_encode_integer(buf_start, buf_end, size, 5);
   if (len == -1) {
     return -1;
   }
@@ -649,97 +563,17 @@ encode_dynamic_table_size_update(uint8_t *buf_start, const uint8_t *buf_end, uin
 }
 
 //
-// [RFC 7541] 5.1. Integer representation
-//
-int64_t
-decode_integer(uint32_t &dst, const uint8_t *buf_start, const uint8_t *buf_end, uint8_t n)
-{
-  if (buf_start >= buf_end) {
-    return HPACK_ERROR_COMPRESSION_ERROR;
-  }
-
-  const uint8_t *p = buf_start;
-
-  dst = (*p & ((1 << n) - 1));
-  if (dst == static_cast<uint32_t>(1 << n) - 1) {
-    int m = 0;
-    do {
-      if (++p >= buf_end) {
-        return HPACK_ERROR_COMPRESSION_ERROR;
-      }
-
-      uint32_t added_value = *p & 0x7f;
-      if ((UINT32_MAX >> m) < added_value) {
-        // Excessively large integer encodings - in value or octet
-        // length - MUST be treated as a decoding error.
-        return HPACK_ERROR_COMPRESSION_ERROR;
-      }
-      dst += added_value << m;
-      m += 7;
-    } while (*p & 0x80);
-  }
-
-  return p - buf_start + 1;
-}
-
-//
-// [RFC 7541] 5.2. String Literal Representation
-// return content from String Data (Length octets) with huffman decoding if it is encoded
-//
-int64_t
-decode_string(Arena &arena, char **str, uint32_t &str_length, const uint8_t *buf_start, const uint8_t *buf_end)
-{
-  if (buf_start >= buf_end) {
-    return HPACK_ERROR_COMPRESSION_ERROR;
-  }
-
-  const uint8_t *p            = buf_start;
-  bool isHuffman              = *p & 0x80;
-  uint32_t encoded_string_len = 0;
-  int64_t len                 = 0;
-
-  len = decode_integer(encoded_string_len, p, buf_end, 7);
-  if (len == HPACK_ERROR_COMPRESSION_ERROR) {
-    return HPACK_ERROR_COMPRESSION_ERROR;
-  }
-  p += len;
-
-  if ((p + encoded_string_len) > buf_end) {
-    return HPACK_ERROR_COMPRESSION_ERROR;
-  }
-
-  if (isHuffman) {
-    // Allocate temporary area twice the size of before decoded data
-    *str = arena.str_alloc(encoded_string_len * 2);
-
-    len = huffman_decode(*str, p, encoded_string_len);
-    if (len < 0) {
-      return HPACK_ERROR_COMPRESSION_ERROR;
-    }
-    str_length = len;
-  } else {
-    *str = arena.str_alloc(encoded_string_len);
-
-    memcpy(*str, reinterpret_cast<const char *>(p), encoded_string_len);
-
-    str_length = encoded_string_len;
-  }
-
-  return p + encoded_string_len - buf_start;
-}
-
-//
 // [RFC 7541] 6.1. Indexed Header Field Representation
 //
 int64_t
 decode_indexed_header_field(MIMEFieldWrapper &header, const uint8_t *buf_start, const uint8_t *buf_end,
                             HpackIndexingTable &indexing_table)
 {
-  uint32_t index = 0;
+  uint64_t index = 0;
   int64_t len    = 0;
 
-  len = decode_integer(index, buf_start, buf_end, 7);
-  if (len == HPACK_ERROR_COMPRESSION_ERROR) {
+  len = xpack_decode_integer(index, buf_start, buf_end, 7);
+  if (len == XPACK_ERROR_COMPRESSION_ERROR) {
     return HPACK_ERROR_COMPRESSION_ERROR;
   }
 
@@ -771,22 +605,22 @@ decode_literal_header_field(MIMEFieldWrapper &header, const uint8_t *buf_start,
 {
   const uint8_t *p         = buf_start;
   bool isIncremental       = false;
-  uint32_t index           = 0;
+  uint64_t index           = 0;
   int64_t len              = 0;
   HpackField ftype         = hpack_parse_field_type(*p);
   bool has_http2_violation = false;
 
   if (ftype == HpackField::INDEXED_LITERAL) {
-    len           = decode_integer(index, p, buf_end, 6);
+    len           = xpack_decode_integer(index, p, buf_end, 6);
     isIncremental = true;
   } else if (ftype == HpackField::NEVERINDEX_LITERAL) {
-    len = decode_integer(index, p, buf_end, 4);
+    len = xpack_decode_integer(index, p, buf_end, 4);
   } else {
     ink_assert(ftype == HpackField::NOINDEX_LITERAL);
-    len = decode_integer(index, p, buf_end, 4);
+    len = xpack_decode_integer(index, p, buf_end, 4);
   }
 
-  if (len == HPACK_ERROR_COMPRESSION_ERROR) {
+  if (len == XPACK_ERROR_COMPRESSION_ERROR) {
     return HPACK_ERROR_COMPRESSION_ERROR;
   }
 
@@ -799,10 +633,10 @@ decode_literal_header_field(MIMEFieldWrapper &header, const uint8_t *buf_start,
     indexing_table.get_header_field(index, header);
   } else {
     char *name_str        = nullptr;
-    uint32_t name_str_len = 0;
+    uint64_t name_str_len = 0;
 
-    len = decode_string(arena, &name_str, name_str_len, p, buf_end);
-    if (len == HPACK_ERROR_COMPRESSION_ERROR) {
+    len = xpack_decode_string(arena, &name_str, name_str_len, p, buf_end);
+    if (len == XPACK_ERROR_COMPRESSION_ERROR) {
       return HPACK_ERROR_COMPRESSION_ERROR;
     }
 
@@ -821,10 +655,10 @@ decode_literal_header_field(MIMEFieldWrapper &header, const uint8_t *buf_start,
 
   // Decode header field value
   char *value_str        = nullptr;
-  uint32_t value_str_len = 0;
+  uint64_t value_str_len = 0;
 
-  len = decode_string(arena, &value_str, value_str_len, p, buf_end);
-  if (len == HPACK_ERROR_COMPRESSION_ERROR) {
+  len = xpack_decode_string(arena, &value_str, value_str_len, p, buf_end);
+  if (len == XPACK_ERROR_COMPRESSION_ERROR) {
     return HPACK_ERROR_COMPRESSION_ERROR;
   }
 
@@ -867,9 +701,9 @@ update_dynamic_table_size(const uint8_t *buf_start, const uint8_t *buf_end, Hpac
   }
 
   // Update header table size if its required.
-  uint32_t size = 0;
-  int64_t len   = decode_integer(size, buf_start, buf_end, 5);
-  if (len == HPACK_ERROR_COMPRESSION_ERROR) {
+  uint64_t size = 0;
+  int64_t len   = xpack_decode_integer(size, buf_start, buf_end, 5);
+  if (len == XPACK_ERROR_COMPRESSION_ERROR) {
     return HPACK_ERROR_COMPRESSION_ERROR;
   }
 
diff --git a/proxy/http2/HPACK.h b/proxy/http2/HPACK.h
index c20f40f..d581749 100644
--- a/proxy/http2/HPACK.h
+++ b/proxy/http2/HPACK.h
@@ -26,6 +26,7 @@
 #include "ts/ink_platform.h"
 #include "ts/Diags.h"
 #include "HTTP.h"
+#include "../hdrs/XPACK.h"
 
 #include <vector>
 
@@ -156,10 +157,6 @@ private:
 };
 
 // Low level interfaces
-int64_t encode_integer(uint8_t *buf_start, const uint8_t *buf_end, uint32_t value, uint8_t n);
-int64_t decode_integer(uint32_t &dst, const uint8_t *buf_start, const uint8_t *buf_end, uint8_t n);
-int64_t encode_string(uint8_t *buf_start, const uint8_t *buf_end, const char *value, size_t value_len);
-int64_t decode_string(Arena &arena, char **str, uint32_t &str_length, const uint8_t *buf_start, const uint8_t *buf_end);
 int64_t encode_indexed_header_field(uint8_t *buf_start, const uint8_t *buf_end, uint32_t index);
 int64_t encode_literal_header_field_with_indexed_name(uint8_t *buf_start, const uint8_t *buf_end, const MIMEFieldWrapper &header,
                                                       uint32_t index, HpackIndexingTable &indexing_table, HpackField type);
diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc
index 4327e71..5aa80d2 100644
--- a/proxy/http2/HTTP2.cc
+++ b/proxy/http2/HTTP2.cc
@@ -23,7 +23,6 @@
 
 #include "HTTP2.h"
 #include "HPACK.h"
-#include "HuffmanCodec.h"
 #include "ts/ink_assert.h"
 #include "P_RecCore.h"
 #include "P_RecProcess.h"
diff --git a/proxy/http2/Makefile.am b/proxy/http2/Makefile.am
index 67e2f5b..747aee8 100644
--- a/proxy/http2/Makefile.am
+++ b/proxy/http2/Makefile.am
@@ -48,9 +48,7 @@ libhttp2_a_SOURCES = \
 	Http2Stream.cc \
 	Http2Stream.h \
 	Http2SessionAccept.cc \
-	Http2SessionAccept.h \
-	HuffmanCodec.cc \
-	HuffmanCodec.h
+	Http2SessionAccept.h
 
 if BUILD_TESTS
 libhttp2_a_SOURCES += \
@@ -58,23 +56,13 @@ libhttp2_a_SOURCES += \
 endif
 
 check_PROGRAMS = \
-	test_Huffmancode \
 	test_Http2DependencyTree \
 	test_HPACK
 
 TESTS = \
-	test_Huffmancode \
 	test_Http2DependencyTree \
 	test_HPACK
 
-test_Huffmancode_LDADD = \
-	$(top_builddir)/lib/ts/libtsutil.la
-
-test_Huffmancode_SOURCES = \
-	test_Huffmancode.cc \
-	HuffmanCodec.cc \
-	HuffmanCodec.h
-
 test_Http2DependencyTree_LDADD = \
 	$(top_builddir)/lib/ts/libtsutil.la
 
@@ -94,8 +82,6 @@ test_HPACK_LDADD = \
 
 test_HPACK_SOURCES = \
 	test_HPACK.cc \
-	HuffmanCodec.cc \
-	HuffmanCodec.h \
 	HPACK.cc \
 	HPACK.h
 
diff --git a/proxy/http2/RegressionHPACK.cc b/proxy/http2/RegressionHPACK.cc
index 399df34..d074561 100644
--- a/proxy/http2/RegressionHPACK.cc
+++ b/proxy/http2/RegressionHPACK.cc
@@ -326,7 +326,7 @@ REGRESSION_TEST(HPACK_EncodeInteger)(RegressionTest *t, int, int *pstatus)
   for (const auto &i : integer_test_case) {
     memset(buf, 0, BUFSIZE_FOR_REGRESSION_TEST);
 
-    int len = encode_integer(buf, buf + BUFSIZE_FOR_REGRESSION_TEST, i.raw_integer, i.prefix);
+    int len = xpack_encode_integer(buf, buf + BUFSIZE_FOR_REGRESSION_TEST, i.raw_integer, i.prefix);
 
     box.check(len == i.encoded_field_len, "encoded length was %d, expecting %d", len, i.encoded_field_len);
     box.check(len > 0 && memcmp(buf, i.encoded_field, len) == 0, "encoded value was invalid");
@@ -345,7 +345,8 @@ REGRESSION_TEST(HPACK_EncodeString)(RegressionTest *t, int, int *pstatus)
   for (unsigned int i = 2; i < sizeof(string_test_case) / sizeof(string_test_case[0]); i++) {
     memset(buf, 0, BUFSIZE_FOR_REGRESSION_TEST);
 
-    len = encode_string(buf, buf + BUFSIZE_FOR_REGRESSION_TEST, string_test_case[i].raw_string, string_test_case[i].raw_string_len);
+    len = xpack_encode_string(buf, buf + BUFSIZE_FOR_REGRESSION_TEST, string_test_case[i].raw_string,
+                              string_test_case[i].raw_string_len);
 
     box.check(len == string_test_case[i].encoded_field_len, "encoded length was %d, expecting %d", len,
               string_test_case[i].encoded_field_len);
@@ -471,13 +472,13 @@ REGRESSION_TEST(HPACK_DecodeInteger)(RegressionTest *t, int, int *pstatus)
   TestBox box(t, pstatus);
   box = REGRESSION_TEST_PASSED;
 
-  uint32_t actual;
+  uint64_t actual;
 
   for (const auto &i : integer_test_case) {
-    int len = decode_integer(actual, i.encoded_field, i.encoded_field + i.encoded_field_len, i.prefix);
+    int len = xpack_decode_integer(actual, i.encoded_field, i.encoded_field + i.encoded_field_len, i.prefix);
 
     box.check(len == i.encoded_field_len, "decoded length was %d, expecting %d", len, i.encoded_field_len);
-    box.check(actual == i.raw_integer, "decoded value was %d, expected %d", actual, i.raw_integer);
+    box.check(actual == i.raw_integer, "decoded value was %" PRIu64 ", expected %d", actual, i.raw_integer);
   }
 }
 
@@ -488,15 +489,16 @@ REGRESSION_TEST(HPACK_DecodeString)(RegressionTest *t, int, int *pstatus)
 
   Arena arena;
   char *actual        = nullptr;
-  uint32_t actual_len = 0;
+  uint64_t actual_len = 0;
 
   hpack_huffman_init();
 
   for (const auto &i : string_test_case) {
-    int len = decode_string(arena, &actual, actual_len, i.encoded_field, i.encoded_field + i.encoded_field_len);
+    int len = xpack_decode_string(arena, &actual, actual_len, i.encoded_field, i.encoded_field + i.encoded_field_len);
 
     box.check(len == i.encoded_field_len, "decoded length was %d, expecting %d", len, i.encoded_field_len);
-    box.check(actual_len == i.raw_string_len, "length of decoded string was %d, expecting %d", actual_len, i.raw_string_len);
+    box.check(actual_len == i.raw_string_len, "length of decoded string was %" PRIu64 ", expecting %d", actual_len,
+              i.raw_string_len);
     box.check(memcmp(actual, i.raw_string, actual_len) == 0, "decoded string was invalid");
   }
 }