-
Notifications
You must be signed in to change notification settings - Fork 26
/
lsxpack_header.h
169 lines (143 loc) · 5.06 KB
/
lsxpack_header.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#ifndef LSXPACK_HEADER_H_v208
#define LSXPACK_HEADER_H_v208
#include <assert.h>
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef LSXPACK_MAX_STRLEN
#define LSXPACK_MAX_STRLEN UINT16_MAX
#endif
typedef int32_t lsxpack_offset_t;
#if LSXPACK_MAX_STRLEN == UINT16_MAX
typedef uint16_t lsxpack_strlen_t;
#elif LSXPACK_MAX_STRLEN == UINT32_MAX
typedef uint32_t lsxpack_strlen_t;
#else
#error unexpected LSXPACK_MAX_STRLEN
#endif
#define LSXPACK_DEL ((char *)NULL)
enum lsxpack_flag
{
LSXPACK_HPACK_VAL_MATCHED = 1,
LSXPACK_QPACK_IDX = 2,
LSXPACK_APP_IDX = 4,
LSXPACK_NAME_HASH = 8,
LSXPACK_NAMEVAL_HASH = 16,
LSXPACK_VAL_MATCHED = 32,
LSXPACK_NEVER_INDEX = 64,
};
/**
* When header are decoded, it should be stored to @buf starting from @name_offset,
* <name>: <value>\r\n
* So, it can be used directly as HTTP/1.1 header. there are 4 extra characters
* added.
*
* limitation: we currently does not support total header size > 64KB.
*/
struct lsxpack_header
{
char *buf; /* the buffer for headers */
uint32_t name_hash; /* hash value for name */
uint32_t nameval_hash; /* hash value for name + value */
lsxpack_offset_t name_offset; /* the offset for name in the buffer */
lsxpack_offset_t val_offset; /* the offset for value in the buffer */
lsxpack_strlen_t name_len; /* the length of name */
lsxpack_strlen_t val_len; /* the length of value */
uint16_t chain_next_idx; /* mainly for cookie value chain */
uint8_t hpack_index; /* HPACK static table index */
uint8_t qpack_index; /* QPACK static table index */
uint8_t app_index; /* APP header index */
enum lsxpack_flag flags:8; /* combination of lsxpack_flag */
uint8_t indexed_type; /* control to disable index or not */
uint8_t dec_overhead; /* num of extra bytes written to decoded buffer */
};
typedef struct lsxpack_header lsxpack_header_t;
static inline void
lsxpack_header_set_idx(lsxpack_header_t *hdr, int hpack_idx,
const char *val, size_t val_len)
{
memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)val;
hdr->hpack_index = (uint8_t)hpack_idx;
assert(hpack_idx != 0);
assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = (lsxpack_strlen_t)val_len;
}
static inline void
lsxpack_header_set_qpack_idx(lsxpack_header_t *hdr, int qpack_idx,
const char *val, size_t val_len)
{
memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)val;
hdr->qpack_index = (uint8_t)qpack_idx;
assert(qpack_idx != -1);
hdr->flags = LSXPACK_QPACK_IDX;
assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = (lsxpack_strlen_t)val_len;
}
static inline void
lsxpack_header_set_offset(lsxpack_header_t *hdr, const char *buf,
size_t name_offset, size_t name_len,
size_t val_len)
{
memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)buf;
hdr->name_offset = (lsxpack_offset_t)name_offset;
assert(name_len <= LSXPACK_MAX_STRLEN);
hdr->name_len = (lsxpack_strlen_t)name_len;
assert(name_offset + name_len + 2 <= LSXPACK_MAX_STRLEN);
hdr->val_offset = (lsxpack_offset_t)(name_offset + name_len + 2);
assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = (lsxpack_strlen_t)val_len;
}
static inline void
lsxpack_header_set_offset2(lsxpack_header_t *hdr, const char *buf,
size_t name_offset, size_t name_len,
size_t val_offset, size_t val_len)
{
memset(hdr, 0, sizeof(*hdr));
hdr->buf = (char *)buf;
hdr->name_offset = (lsxpack_offset_t)name_offset;
assert(name_len <= LSXPACK_MAX_STRLEN);
hdr->name_len = (lsxpack_strlen_t)name_len;
assert(val_offset <= LSXPACK_MAX_STRLEN);
hdr->val_offset = (lsxpack_offset_t)val_offset;
assert(val_len <= LSXPACK_MAX_STRLEN);
hdr->val_len = (lsxpack_strlen_t)val_len;
}
static inline void
lsxpack_header_prepare_decode(lsxpack_header_t *hdr,
char *out, size_t offset, size_t len)
{
memset(hdr, 0, sizeof(*hdr));
hdr->buf = out;
assert(offset <= LSXPACK_MAX_STRLEN);
hdr->name_offset = (lsxpack_offset_t)offset;
if (len > LSXPACK_MAX_STRLEN)
hdr->val_len = LSXPACK_MAX_STRLEN;
else
hdr->val_len = (lsxpack_strlen_t)len;
}
static inline const char *
lsxpack_header_get_name(const lsxpack_header_t *hdr)
{
return (hdr->name_len)? hdr->buf + hdr->name_offset : NULL;
}
static inline const char *
lsxpack_header_get_value(const lsxpack_header_t *hdr)
{ return hdr->buf + hdr->val_offset; }
static inline size_t
lsxpack_header_get_dec_size(const lsxpack_header_t *hdr)
{ return hdr->name_len + hdr->val_len + hdr->dec_overhead; }
static inline void
lsxpack_header_mark_val_changed(lsxpack_header_t *hdr)
{
hdr->flags = (enum lsxpack_flag)(hdr->flags &
~(LSXPACK_HPACK_VAL_MATCHED|LSXPACK_VAL_MATCHED|LSXPACK_NAMEVAL_HASH));
}
#ifdef __cplusplus
}
#endif
#endif //LSXPACK_HEADER_H_v208