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