1 /* 2 MIT License 3 4 Copyright (c) 2018 - 2021 LiteSpeed Technologies Inc 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in all 14 copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 SOFTWARE. 23 */ 24 25 #ifndef LITESPEED_HPACK_H 26 #define LITESPEED_HPACK_H 1 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #include <limits.h> 33 #include <stdint.h> 34 #include "lsxpack_header.h" 35 36 #define LSHPACK_MAJOR_VERSION 2 37 #define LSHPACK_MINOR_VERSION 3 38 #define LSHPACK_PATCH_VERSION 0 39 40 #define lshpack_strlen_t lsxpack_strlen_t 41 #define LSHPACK_MAX_STRLEN LSXPACK_MAX_STRLEN 42 43 /*(lighttpd customization)*/ 44 /* decoder provides "field-name: value\r\n"; define to 0 to omit ": ", "\r\n" */ 45 #define LSHPACK_DEC_HTTP1X_OUTPUT 0 46 /* decoder provides hash values for request fields; define to 0 to skip */ 47 /* (future: might be useful to lighttpd if lighttpd reverse-proxy (mod_proxy) 48 * were to support HTTP/2 requests to backends, which is not currently done) */ 49 #define LSHPACK_DEC_CALC_HASH 0 50 51 #ifndef LSHPACK_DEC_HTTP1X_OUTPUT 52 #define LSHPACK_DEC_HTTP1X_OUTPUT 1 53 #endif 54 #ifndef LSHPACK_DEC_CALC_HASH 55 #define LSHPACK_DEC_CALC_HASH 1 56 #endif 57 58 struct lshpack_enc; 59 struct lshpack_dec; 60 61 enum lshpack_static_hdr_idx 62 { 63 LSHPACK_HDR_UNKNOWN, 64 LSHPACK_HDR_AUTHORITY, 65 LSHPACK_HDR_METHOD_GET, 66 LSHPACK_HDR_METHOD_POST, 67 LSHPACK_HDR_PATH, 68 LSHPACK_HDR_PATH_INDEX_HTML, 69 LSHPACK_HDR_SCHEME_HTTP, 70 LSHPACK_HDR_SCHEME_HTTPS, 71 LSHPACK_HDR_STATUS_200, 72 LSHPACK_HDR_STATUS_204, 73 LSHPACK_HDR_STATUS_206, 74 LSHPACK_HDR_STATUS_304, 75 LSHPACK_HDR_STATUS_400, 76 LSHPACK_HDR_STATUS_404, 77 LSHPACK_HDR_STATUS_500, 78 LSHPACK_HDR_ACCEPT_CHARSET, 79 LSHPACK_HDR_ACCEPT_ENCODING, 80 LSHPACK_HDR_ACCEPT_LANGUAGE, 81 LSHPACK_HDR_ACCEPT_RANGES, 82 LSHPACK_HDR_ACCEPT, 83 LSHPACK_HDR_ACCESS_CONTROL_ALLOW_ORIGIN, 84 LSHPACK_HDR_AGE, 85 LSHPACK_HDR_ALLOW, 86 LSHPACK_HDR_AUTHORIZATION, 87 LSHPACK_HDR_CACHE_CONTROL, 88 LSHPACK_HDR_CONTENT_DISPOSITION, 89 LSHPACK_HDR_CONTENT_ENCODING, 90 LSHPACK_HDR_CONTENT_LANGUAGE, 91 LSHPACK_HDR_CONTENT_LENGTH, 92 LSHPACK_HDR_CONTENT_LOCATION, 93 LSHPACK_HDR_CONTENT_RANGE, 94 LSHPACK_HDR_CONTENT_TYPE, 95 LSHPACK_HDR_COOKIE, 96 LSHPACK_HDR_DATE, 97 LSHPACK_HDR_ETAG, 98 LSHPACK_HDR_EXPECT, 99 LSHPACK_HDR_EXPIRES, 100 LSHPACK_HDR_FROM, 101 LSHPACK_HDR_HOST, 102 LSHPACK_HDR_IF_MATCH, 103 LSHPACK_HDR_IF_MODIFIED_SINCE, 104 LSHPACK_HDR_IF_NONE_MATCH, 105 LSHPACK_HDR_IF_RANGE, 106 LSHPACK_HDR_IF_UNMODIFIED_SINCE, 107 LSHPACK_HDR_LAST_MODIFIED, 108 LSHPACK_HDR_LINK, 109 LSHPACK_HDR_LOCATION, 110 LSHPACK_HDR_MAX_FORWARDS, 111 LSHPACK_HDR_PROXY_AUTHENTICATE, 112 LSHPACK_HDR_PROXY_AUTHORIZATION, 113 LSHPACK_HDR_RANGE, 114 LSHPACK_HDR_REFERER, 115 LSHPACK_HDR_REFRESH, 116 LSHPACK_HDR_RETRY_AFTER, 117 LSHPACK_HDR_SERVER, 118 LSHPACK_HDR_SET_COOKIE, 119 LSHPACK_HDR_STRICT_TRANSPORT_SECURITY, 120 LSHPACK_HDR_TRANSFER_ENCODING, 121 LSHPACK_HDR_USER_AGENT, 122 LSHPACK_HDR_VARY, 123 LSHPACK_HDR_VIA, 124 LSHPACK_HDR_WWW_AUTHENTICATE, 125 LSHPACK_HDR_TOBE_INDEXED = 255 126 }; 127 128 #define LSHPACK_MAX_INDEX 61 129 130 #define LSHPACK_ERR_MORE_BUF (-3) 131 #define LSHPACK_ERR_TOO_LARGE (-2) 132 #define LSHPACK_ERR_BAD_DATA (-1) 133 #define LSHPACK_OK (0) 134 135 /** 136 * Initialization routine allocates memory. -1 is returned if memory 137 * could not be allocated. 0 is returned on success. 138 */ 139 int 140 lshpack_enc_init (struct lshpack_enc *); 141 142 /** 143 * Clean up HPACK encoder, freeing all allocated memory. 144 */ 145 void 146 lshpack_enc_cleanup (struct lshpack_enc *); 147 148 /** 149 * @brief Encode one name/value pair 150 * 151 * @param[in,out] henc - A pointer to a valid HPACK API struct 152 * @param[out] dst - A pointer to destination buffer 153 * @param[out] dst_end - A pointer to end of destination buffer 154 * @param[in] input - Header to encode 155 * 156 * @return The (possibly advanced) dst pointer. If the destination 157 * pointer was not advanced, an error must have occurred. 158 */ 159 unsigned char * 160 lshpack_enc_encode (struct lshpack_enc *henc, unsigned char *dst, 161 unsigned char *dst_end, struct lsxpack_header *input); 162 163 void 164 lshpack_enc_set_max_capacity (struct lshpack_enc *, unsigned); 165 166 /** 167 * Turn history on or off. Turning history on may fail (malloc), in 168 * which case -1 is returned. 169 */ 170 int 171 lshpack_enc_use_hist (struct lshpack_enc *, int on); 172 173 /** 174 * Return true if history is used, false otherwise. By default, 175 * history is off. 176 */ 177 int 178 lshpack_enc_hist_used (const struct lshpack_enc *); 179 180 /** 181 * Initialize HPACK decoder structure. 182 */ 183 void 184 lshpack_dec_init (struct lshpack_dec *); 185 186 /** 187 * Clean up HPACK decoder structure, freeing all allocated memory. 188 */ 189 void 190 lshpack_dec_cleanup (struct lshpack_dec *); 191 192 /* 193 * Returns 0 on success, a negative value on failure. 194 * 195 * If 0 is returned, `src' is advanced. Calling with a zero-length input 196 * buffer results in an error. 197 * 198 * To calculate number of bytes written to the output buffer: 199 * output->name_len + output->val_len + lshpack_dec_extra_bytes(dec) 200 */ 201 int 202 lshpack_dec_decode (struct lshpack_dec *dec, 203 const unsigned char **src, const unsigned char *src_end, 204 struct lsxpack_header *output); 205 206 /* Return number of extra bytes per header */ 207 #if LSHPACK_DEC_HTTP1X_OUTPUT 208 #define LSHPACK_DEC_HTTP1X_EXTRA (2) 209 #define lshpack_dec_extra_bytes(dec_) (4) 210 #else 211 #define LSHPACK_DEC_HTTP1X_EXTRA (0) 212 #define lshpack_dec_extra_bytes(dec_) (0) 213 #endif 214 215 void 216 lshpack_dec_set_max_capacity (struct lshpack_dec *, unsigned); 217 218 /* Some internals follow. Struct definitions are exposed to save a malloc. 219 * These structures are not very complicated. 220 */ 221 222 #include <sys/queue.h> 223 224 #ifdef __OpenBSD__ 225 #define STAILQ_HEAD SIMPLEQ_HEAD 226 #define STAILQ_ENTRY SIMPLEQ_ENTRY 227 #define STAILQ_INIT SIMPLEQ_INIT 228 #define STAILQ_INSERT_TAIL SIMPLEQ_INSERT_TAIL 229 #define STAILQ_EMPTY SIMPLEQ_EMPTY 230 #define STAILQ_FIRST SIMPLEQ_FIRST 231 #define STAILQ_NEXT SIMPLEQ_NEXT 232 #define STAILQ_REMOVE_HEAD SIMPLEQ_REMOVE_HEAD 233 #define STAILQ_FOREACH SIMPLEQ_FOREACH 234 #endif 235 236 struct lshpack_enc_table_entry; 237 238 STAILQ_HEAD(lshpack_enc_head, lshpack_enc_table_entry); 239 struct lshpack_double_enc_head; 240 241 struct lshpack_enc 242 { 243 unsigned hpe_cur_capacity; 244 unsigned hpe_max_capacity; 245 246 /* Each new dynamic table entry gets the next number. It is used to 247 * calculate the entry's position in the decoder table without having 248 * to maintain an actual array. 249 */ 250 unsigned hpe_next_id; 251 252 /* Dynamic table entries (struct enc_table_entry) live in two hash 253 * tables: name/value hash table and name hash table. These tables 254 * are the same size. 255 */ 256 unsigned hpe_nelem; 257 unsigned hpe_nbits; 258 struct lshpack_enc_head 259 hpe_all_entries; 260 struct lshpack_double_enc_head 261 *hpe_buckets; 262 263 uint32_t *hpe_hist_buf; 264 unsigned hpe_hist_size, hpe_hist_idx; 265 int hpe_hist_wrapped; 266 enum { 267 LSHPACK_ENC_USE_HIST = 1 << 0, 268 } hpe_flags; 269 }; 270 271 struct lshpack_arr 272 { 273 unsigned nalloc, 274 nelem, 275 off; 276 uintptr_t *els; 277 }; 278 279 struct lshpack_dec 280 { 281 struct lshpack_arr hpd_dyn_table; 282 unsigned hpd_max_capacity; /* Maximum set by caller */ 283 unsigned hpd_cur_max_capacity; /* Adjusted at runtime */ 284 unsigned hpd_cur_capacity; 285 unsigned hpd_state; 286 }; 287 288 /* This function may update hash values and flags */ 289 unsigned 290 lshpack_enc_get_stx_tab_id (struct lsxpack_header *); 291 292 #ifdef __cplusplus 293 } 294 #endif 295 296 #endif 297