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