litespeed-quic/src/liblsquic/lsquic_frame_reader.h

121 lines
4.6 KiB
C

/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */
/*
* lsquic_frame_reader.h -- Read HTTP frames from stream
*/
#ifndef LSQUIC_FRAME_READER_H
#define LSQUIC_FRAME_READER_H 1
#include <stddef.h>
#include <stdint.h>
struct lsquic_hdec;
struct lsquic_mm;
struct lsquic_stream;
struct lsquic_frame_reader;
enum frame_reader_flags
{
FRF_SERVER = (1 << 0),
FRF_HAVE_PREV = (1 << 1),
};
/* Frame reader may hit some error conditions which are reported using
* callback fc_on_error. These codes are later mapped stream- or
* connection-level errors.
*/
enum frame_reader_error
{
FR_ERR_DUPLICATE_PSEH = 1, /* Duplicate pseudo-header */
FR_ERR_INCOMPL_REQ_PSEH, /* Not all request pseudo-headers are present */
FR_ERR_UNNEC_REQ_PSEH, /* Unnecessary request pseudo-header present in
* the response.
*/
FR_ERR_INCOMPL_RESP_PSEH, /* Not all response pseudo-headers are present */
FR_ERR_UNNEC_RESP_PSEH, /* Unnecessary response pseudo-header present in
* the response.
*/
FR_ERR_UNKNOWN_PSEH, /* Unknown pseudo-header */
FR_ERR_UPPERCASE_HEADER, /* Uppercase letter in header */
FR_ERR_MISPLACED_PSEH,
FR_ERR_MISSING_PSEH,
FR_ERR_DECOMPRESS,
FR_ERR_INVALID_FRAME_SIZE, /* E.g. a SETTINGS frame length is not a multiple
* of 6 (RFC 7540, Section 6.5.1).
*/
FR_ERR_NONZERO_STREAM_ID,
FR_ERR_ZERO_STREAM_ID,
FR_ERR_SELF_DEP_STREAM, /* A stream in priority frame cannot depend on
* itself (RFC 7540, Section 5.3.1).
*/
FR_ERR_HEADERS_TOO_LARGE,
FR_ERR_UNEXPECTED_PUSH,
FR_ERR_NOMEM, /* Cannot allocate any more memory. */
FR_ERR_EXPECTED_CONTIN, /* Expected continuation frame. */
};
/* This struct is used to return decoded HEADERS and PUSH_PROMISE frames.
* Some of the fields are only used for HEADERS frames. They are marked
* with "H" comment below.
*/
struct uncompressed_headers
{
uint32_t uh_stream_id;
uint32_t uh_oth_stream_id; /* For HEADERS frame, the ID of the
* stream that this stream depends
* on. (Zero means unset.) For
* PUSH_PROMISE, the promised stream
* ID.
*/
unsigned uh_size; /* Number of characters in uh_headers, not
* counting the NUL byte.
*/
unsigned /* H */ uh_off;
unsigned short /* H */ uh_weight; /* 1 - 256; 0 means not set */
signed char /* H */ uh_exclusive; /* 0 or 1 when set; -1 means not set */
enum {
/* H */ UH_FIN = (1 << 0),
UH_PP = (1 << 1), /* Push promise */
} uh_flags:8;
char uh_headers[ /* NUL-terminated C string */
#if FRAME_READER_TESTING
FRAME_READER_TESTING
#else
0
#endif
];
};
struct frame_reader_callbacks
{
void (*frc_on_headers) (void *frame_cb_ctx, struct uncompressed_headers *);
void (*frc_on_push_promise) (void *frame_cb_ctx, struct uncompressed_headers *);
void (*frc_on_settings) (void *frame_cb_ctx, uint16_t setting_id,
uint32_t setting_value);
void (*frc_on_priority) (void *frame_cb_ctx, uint32_t stream_id,
int exclusive, uint32_t dep_stream_id,
unsigned weight);
void (*frc_on_error) (void *frame_cb_ctx, uint32_t stream_id,
enum frame_reader_error);
};
typedef ssize_t (*fr_stream_read_f)(struct lsquic_stream *, void *, size_t);
struct lsquic_frame_reader *
lsquic_frame_reader_new (enum frame_reader_flags, unsigned max_headers_sz,
struct lsquic_mm *, struct lsquic_stream *,
fr_stream_read_f, struct lsquic_hdec *,
const struct frame_reader_callbacks *,
void *fr_cb_ctx);
int
lsquic_frame_reader_read (struct lsquic_frame_reader *);
void
lsquic_frame_reader_destroy (struct lsquic_frame_reader *);
#endif