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