litespeed-quic/include/lsxpack_header.h
2023-05-31 16:37:47 -04:00

170 lines
5.1 KiB
C

/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
#ifndef LSXPACK_HEADER_H_v208
#define LSXPACK_HEADER_H_v208
#ifdef __cplusplus
extern "C" {
#endif
#include <assert.h>
#include <stdint.h>
#include <string.h>
#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