Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::protocols::http2::hpack_encoder Class Reference

HPACK header encoder (RFC 7541) More...

#include <hpack.h>

Collaboration diagram for kcenon::network::protocols::http2::hpack_encoder:
Collaboration graph

Public Member Functions

 hpack_encoder (size_t max_table_size=4096)
 Construct encoder with max table size.
 
auto encode (const std::vector< http_header > &headers) -> std::vector< uint8_t >
 Encode headers to HPACK binary format.
 
auto set_max_table_size (size_t size) -> void
 Set maximum dynamic table size.
 
auto table_size () const -> size_t
 Get current dynamic table size.
 

Private Member Functions

auto encode_integer (uint64_t value, uint8_t prefix_bits) -> std::vector< uint8_t >
 
auto encode_string (std::string_view str, bool huffman=false) -> std::vector< uint8_t >
 
auto encode_indexed (size_t index) -> std::vector< uint8_t >
 
auto encode_literal_with_indexing (std::string_view name, std::string_view value) -> std::vector< uint8_t >
 
auto encode_literal_with_indexing (size_t name_index, std::string_view value) -> std::vector< uint8_t >
 
auto encode_literal_without_indexing (std::string_view name, std::string_view value) -> std::vector< uint8_t >
 
auto encode_literal_without_indexing (size_t name_index, std::string_view value) -> std::vector< uint8_t >
 

Private Attributes

dynamic_table table_
 

Detailed Description

HPACK header encoder (RFC 7541)

Encodes HTTP headers using HPACK compression with dynamic table.

Definition at line 158 of file hpack.h.

Constructor & Destructor Documentation

◆ hpack_encoder()

kcenon::network::protocols::http2::hpack_encoder::hpack_encoder ( size_t max_table_size = 4096)
explicit

Construct encoder with max table size.

Parameters
max_table_sizeMaximum dynamic table size (default 4096)

Definition at line 192 of file hpack.cpp.

193 : table_(max_table_size)
194 {
195 }

Member Function Documentation

◆ encode()

auto kcenon::network::protocols::http2::hpack_encoder::encode ( const std::vector< http_header > & headers) -> std::vector<uint8_t>

Encode headers to HPACK binary format.

Parameters
headersHeaders to encode
Returns
Encoded bytes

Definition at line 197 of file hpack.cpp.

199 {
200 std::vector<uint8_t> result;
201
202 for (const auto& header : headers)
203 {
204 // Try to find in static table first
205 size_t static_index = static_table::find(header.name, header.value);
206 if (static_index > 0)
207 {
208 // Indexed header field representation
209 auto encoded = encode_indexed(static_index);
210 result.insert(result.end(), encoded.begin(), encoded.end());
211 continue;
212 }
213
214 // Try to find in dynamic table
215 auto dynamic_index = table_.find(header.name, header.value);
216 if (dynamic_index.has_value())
217 {
218 // Indexed header field representation
219 size_t index = static_table::size() + 1 + dynamic_index.value();
220 auto encoded = encode_indexed(index);
221 result.insert(result.end(), encoded.begin(), encoded.end());
222 continue;
223 }
224
225 // Check if name is in static table
226 size_t name_index = static_table::find(header.name, "");
227 if (name_index > 0)
228 {
229 // Literal with incremental indexing - indexed name
230 auto encoded = encode_literal_with_indexing(name_index, header.value);
231 result.insert(result.end(), encoded.begin(), encoded.end());
232 table_.insert(header.name, header.value);
233 }
234 else
235 {
236 // Check if name is in dynamic table
237 auto dynamic_name_index = table_.find(header.name, "");
238 if (dynamic_name_index.has_value())
239 {
240 size_t index = static_table::size() + 1 + dynamic_name_index.value();
241 auto encoded = encode_literal_with_indexing(index, header.value);
242 result.insert(result.end(), encoded.begin(), encoded.end());
243 table_.insert(header.name, header.value);
244 }
245 else
246 {
247 // Literal with incremental indexing - new name
248 auto encoded = encode_literal_with_indexing(header.name, header.value);
249 result.insert(result.end(), encoded.begin(), encoded.end());
250 table_.insert(header.name, header.value);
251 }
252 }
253 }
254
255 return result;
256 }
auto find(std::string_view name, std::string_view value="") const -> std::optional< size_t >
Find header in dynamic table.
Definition hpack.cpp:138
auto insert(std::string_view name, std::string_view value) -> void
Insert header at beginning of table.
Definition hpack.cpp:116
auto encode_literal_with_indexing(std::string_view name, std::string_view value) -> std::vector< uint8_t >
Definition hpack.cpp:329
auto encode_indexed(size_t index) -> std::vector< uint8_t >
Definition hpack.cpp:322
static constexpr auto size() -> size_t
Get static table size.
Definition hpack.h:72
static auto find(std::string_view name, std::string_view value="") -> size_t
Find index of header in static table.
Definition hpack.cpp:93

References kcenon::network::protocols::http2::static_table::find(), kcenon::network::protocols::http2::headers, and kcenon::network::protocols::http2::static_table::size().

Here is the call graph for this function:

◆ encode_indexed()

auto kcenon::network::protocols::http2::hpack_encoder::encode_indexed ( size_t index) -> std::vector<uint8_t>
private

Definition at line 322 of file hpack.cpp.

323 {
324 auto result = encode_integer(index, 7);
325 result[0] |= 0x80; // Set indexed bit
326 return result;
327 }
auto encode_integer(uint64_t value, uint8_t prefix_bits) -> std::vector< uint8_t >
Definition hpack.cpp:268

◆ encode_integer()

auto kcenon::network::protocols::http2::hpack_encoder::encode_integer ( uint64_t value,
uint8_t prefix_bits ) -> std::vector<uint8_t>
private

Definition at line 268 of file hpack.cpp.

270 {
271 std::vector<uint8_t> result;
272 uint8_t max_prefix = (1 << prefix_bits) - 1;
273
274 if (value < max_prefix)
275 {
276 result.push_back(static_cast<uint8_t>(value));
277 }
278 else
279 {
280 result.push_back(max_prefix);
281 value -= max_prefix;
282
283 while (value >= 128)
284 {
285 result.push_back(static_cast<uint8_t>((value % 128) + 128));
286 value /= 128;
287 }
288 result.push_back(static_cast<uint8_t>(value));
289 }
290
291 return result;
292 }

◆ encode_literal_with_indexing() [1/2]

auto kcenon::network::protocols::http2::hpack_encoder::encode_literal_with_indexing ( size_t name_index,
std::string_view value ) -> std::vector<uint8_t>
private

Definition at line 349 of file hpack.cpp.

352 {
353 std::vector<uint8_t> result;
354
355 // Encode name index with 6-bit prefix
356 auto index_bytes = encode_integer(name_index, 6);
357 index_bytes[0] |= 0x40; // Set literal with indexing bit
358 result.insert(result.end(), index_bytes.begin(), index_bytes.end());
359
360 // Encode value
361 auto value_bytes = encode_string(value);
362 result.insert(result.end(), value_bytes.begin(), value_bytes.end());
363
364 return result;
365 }
auto encode_string(std::string_view str, bool huffman=false) -> std::vector< uint8_t >
Definition hpack.cpp:294

◆ encode_literal_with_indexing() [2/2]

auto kcenon::network::protocols::http2::hpack_encoder::encode_literal_with_indexing ( std::string_view name,
std::string_view value ) -> std::vector<uint8_t>
private

Definition at line 329 of file hpack.cpp.

332 {
333 std::vector<uint8_t> result;
334
335 // First byte: 01xxxxxx (literal with incremental indexing, new name)
336 result.push_back(0x40);
337
338 // Encode name
339 auto name_bytes = encode_string(name);
340 result.insert(result.end(), name_bytes.begin(), name_bytes.end());
341
342 // Encode value
343 auto value_bytes = encode_string(value);
344 result.insert(result.end(), value_bytes.begin(), value_bytes.end());
345
346 return result;
347 }

◆ encode_literal_without_indexing() [1/2]

auto kcenon::network::protocols::http2::hpack_encoder::encode_literal_without_indexing ( size_t name_index,
std::string_view value ) -> std::vector<uint8_t>
private

Definition at line 387 of file hpack.cpp.

390 {
391 std::vector<uint8_t> result;
392
393 // Encode name index with 4-bit prefix
394 auto index_bytes = encode_integer(name_index, 4);
395 // First byte already has 0000 prefix for literal without indexing
396 result.insert(result.end(), index_bytes.begin(), index_bytes.end());
397
398 // Encode value
399 auto value_bytes = encode_string(value);
400 result.insert(result.end(), value_bytes.begin(), value_bytes.end());
401
402 return result;
403 }

◆ encode_literal_without_indexing() [2/2]

auto kcenon::network::protocols::http2::hpack_encoder::encode_literal_without_indexing ( std::string_view name,
std::string_view value ) -> std::vector<uint8_t>
private

Definition at line 367 of file hpack.cpp.

370 {
371 std::vector<uint8_t> result;
372
373 // First byte: 0000xxxx (literal without indexing, new name)
374 result.push_back(0x00);
375
376 // Encode name
377 auto name_bytes = encode_string(name);
378 result.insert(result.end(), name_bytes.begin(), name_bytes.end());
379
380 // Encode value
381 auto value_bytes = encode_string(value);
382 result.insert(result.end(), value_bytes.begin(), value_bytes.end());
383
384 return result;
385 }

◆ encode_string()

auto kcenon::network::protocols::http2::hpack_encoder::encode_string ( std::string_view str,
bool huffman = false ) -> std::vector<uint8_t>
private

Definition at line 294 of file hpack.cpp.

296 {
297 std::vector<uint8_t> result;
298
299 if (huffman)
300 {
301 // Only use Huffman coding when it actually shrinks the string;
302 // RFC 7541 5.2 lets the encoder choose per string.
303 auto encoded = huffman::encode(str);
304 if (encoded.size() < str.size())
305 {
306 auto length_bytes = encode_integer(encoded.size(), 7);
307 length_bytes[0] |= 0x80; // Set H bit
308 result.insert(result.end(), length_bytes.begin(), length_bytes.end());
309 result.insert(result.end(), encoded.begin(), encoded.end());
310 return result;
311 }
312 }
313
314 // Raw literal: length with the H bit clear, then the octets verbatim.
315 auto length_bytes = encode_integer(str.size(), 7);
316 result.insert(result.end(), length_bytes.begin(), length_bytes.end());
317 result.insert(result.end(), str.begin(), str.end());
318
319 return result;
320 }
Huffman coding for HPACK string compression.
auto encode(std::string_view input) -> std::vector< uint8_t >
Encode string using Huffman coding.
Definition hpack.cpp:775

References kcenon::network::protocols::http2::huffman::encode().

Here is the call graph for this function:

◆ set_max_table_size()

auto kcenon::network::protocols::http2::hpack_encoder::set_max_table_size ( size_t size) -> void

Set maximum dynamic table size.

Parameters
sizeNew maximum size

Definition at line 258 of file hpack.cpp.

259 {
260 table_.set_max_size(size);
261 }
auto set_max_size(size_t size) -> void
Set maximum table size.
Definition hpack.cpp:155

◆ table_size()

auto kcenon::network::protocols::http2::hpack_encoder::table_size ( ) const -> size_t

Get current dynamic table size.

Returns
Current size in bytes

Definition at line 263 of file hpack.cpp.

264 {
265 return table_.current_size();
266 }
auto current_size() const -> size_t
Get current table size.
Definition hpack.cpp:161

References kcenon::network::protocols::http2::dynamic_table::current_size(), and table_.

Here is the call graph for this function:

Member Data Documentation

◆ table_

dynamic_table kcenon::network::protocols::http2::hpack_encoder::table_
private

Definition at line 199 of file hpack.h.

Referenced by table_size().


The documentation for this class was generated from the following files: