libhttppp ..

Loading...
Searching...
No Matches
hpack.h
1/*******************************************************************************
2 * Copyright (c) 2014, Jan Koester jan.koester@gmx.net
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * Neither the name of the <organization> nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *******************************************************************************/
27
28#pragma once
29
30#include <cstddef>
31#include <cstdint>
32#include <deque>
33#include <string>
34#include <vector>
35
36 namespace libhttppp::hpack {
37
38 struct HeaderField {
39 std::string name;
40 std::string value;
41 bool incremental_index = false;
42};
43
44 class Encoder {
45 public:
46 static std::string encodeResponseHeaders(uint16_t status_code,
47 const std::string &content_type,
48 size_t content_length,
49 const std::vector<HeaderField> &extra = {});
50
51 static std::string encodeRequestHeaders(const std::string &method,
52 const std::string &path,
53 const std::string &scheme,
54 const std::string &authority,
55 const std::vector<HeaderField> &extra = {});
56
57 private:
58 static void appendLiteral(std::string &out,
59 const std::string &name,
60 const std::string &value,
61 bool incremental_index);
62 static void appendLiteralWithNameIndex(std::string &out,
63 uint8_t name_index,
64 const std::string &value,
65 bool incremental_index);
66};
67
68 class Decoder {
69 public:
70 Decoder() = default;
71 ~Decoder() = default;
72
73 // Non-copyable / non-movable — the dynamic table must not be
74 // accidentally shared or left in a moved-from state.
75 Decoder(const Decoder &) = delete;
76 Decoder &operator=(const Decoder &) = delete;
77 Decoder(Decoder &&) = delete;
78 Decoder &operator=(Decoder &&) = delete;
79
80 void reset() { _dynTable.clear(); _dynTableSize = 0; }
81
82 // Instance method: decode using (and updating) the dynamic table
83 std::vector<HeaderField> decode(const uint8_t *data, size_t len);
84 std::vector<HeaderField> decode(const std::string &data);
85
86 // Static convenience (stateless, no dynamic table — for one-shot use)
87 static std::vector<HeaderField> decodeStateless(const uint8_t *data, size_t len);
88
89 // Shared utilities (also used by QPACK decoder)
90 static uint32_t decodeInt(const uint8_t *data, size_t len, uint8_t prefix_bits, size_t &bytes_read);
91 static std::string decodeString(const uint8_t *data, size_t len, size_t &bytes_read);
92 static std::string huffmanDecode(const uint8_t *data, size_t len);
93
94 private:
95 // Dynamic table (RFC 7541 §2.3.2): newest entry at front
96 struct DynEntry { std::string name; std::string value; };
97 std::deque<DynEntry> _dynTable;
98 size_t _dynTableSize = 0; // current size in octets
99 size_t _dynTableMaxSize = 4096; // default per RFC 7541 §6.5.2
100
101 // Look up an index across static + dynamic tables
102 bool lookupIndex(uint32_t idx, std::string &name, std::string &value) const;
103 bool lookupIndexName(uint32_t idx, std::string &name) const;
104
105 // Add an entry to the dynamic table, evicting as necessary
106 void addEntry(const std::string &name, const std::string &value);
107 void evict(size_t required);
108
109 struct StaticEntry { const char *name; const char *value; };
110 static const StaticEntry STATIC_TABLE[];
111 static const size_t STATIC_TABLE_SIZE;
112};
113
114} // namespace libhttppp::hpack
libhttppp::hpack::Decoder
Definition hpack.h:68
libhttppp::hpack::Encoder
Definition hpack.h:44
libhttppp::hpack::HeaderField
Definition hpack.h:38