lsquic_frame_reader.h revision 50aadb33
150aadb33SDmitri Tikhonov/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov/* 350aadb33SDmitri Tikhonov * lsquic_frame_reader.h -- Read HTTP frames from stream 450aadb33SDmitri Tikhonov */ 550aadb33SDmitri Tikhonov 650aadb33SDmitri Tikhonov#ifndef LSQUIC_FRAME_READER_H 750aadb33SDmitri Tikhonov#define LSQUIC_FRAME_READER_H 1 850aadb33SDmitri Tikhonov 950aadb33SDmitri Tikhonov#include <stddef.h> 1050aadb33SDmitri Tikhonov#include <stdint.h> 1150aadb33SDmitri Tikhonov 1250aadb33SDmitri Tikhonovstruct lsquic_hdec; 1350aadb33SDmitri Tikhonovstruct lsquic_mm; 1450aadb33SDmitri Tikhonovstruct lsquic_stream; 1550aadb33SDmitri Tikhonovstruct lsquic_frame_reader; 1650aadb33SDmitri Tikhonov 1750aadb33SDmitri Tikhonov 1850aadb33SDmitri Tikhonovenum frame_reader_flags 1950aadb33SDmitri Tikhonov{ 2050aadb33SDmitri Tikhonov FRF_SERVER = (1 << 0), 2150aadb33SDmitri Tikhonov FRF_HAVE_PREV = (1 << 1), 2250aadb33SDmitri Tikhonov}; 2350aadb33SDmitri Tikhonov 2450aadb33SDmitri Tikhonov 2550aadb33SDmitri Tikhonov/* Frame reader may hit some error conditions which are reported using 2650aadb33SDmitri Tikhonov * callback fc_on_error. These codes are later mapped stream- or 2750aadb33SDmitri Tikhonov * connection-level errors. 2850aadb33SDmitri Tikhonov */ 2950aadb33SDmitri Tikhonovenum frame_reader_error 3050aadb33SDmitri Tikhonov{ 3150aadb33SDmitri Tikhonov FR_ERR_DUPLICATE_PSEH = 1, /* Duplicate pseudo-header */ 3250aadb33SDmitri Tikhonov FR_ERR_INCOMPL_REQ_PSEH, /* Not all request pseudo-headers are present */ 3350aadb33SDmitri Tikhonov FR_ERR_UNNEC_REQ_PSEH, /* Unnecessary request pseudo-header present in 3450aadb33SDmitri Tikhonov * the response. 3550aadb33SDmitri Tikhonov */ 3650aadb33SDmitri Tikhonov FR_ERR_INCOMPL_RESP_PSEH, /* Not all response pseudo-headers are present */ 3750aadb33SDmitri Tikhonov FR_ERR_UNNEC_RESP_PSEH, /* Unnecessary response pseudo-header present in 3850aadb33SDmitri Tikhonov * the response. 3950aadb33SDmitri Tikhonov */ 4050aadb33SDmitri Tikhonov FR_ERR_UNKNOWN_PSEH, /* Unknown pseudo-header */ 4150aadb33SDmitri Tikhonov FR_ERR_UPPERCASE_HEADER, /* Uppercase letter in header */ 4250aadb33SDmitri Tikhonov FR_ERR_MISPLACED_PSEH, 4350aadb33SDmitri Tikhonov FR_ERR_MISSING_PSEH, 4450aadb33SDmitri Tikhonov FR_ERR_DECOMPRESS, 4550aadb33SDmitri Tikhonov FR_ERR_INVALID_FRAME_SIZE, /* E.g. a SETTINGS frame length is not a multiple 4650aadb33SDmitri Tikhonov * of 6 (RFC 7540, Section 6.5.1). 4750aadb33SDmitri Tikhonov */ 4850aadb33SDmitri Tikhonov FR_ERR_NONZERO_STREAM_ID, 4950aadb33SDmitri Tikhonov FR_ERR_ZERO_STREAM_ID, 5050aadb33SDmitri Tikhonov FR_ERR_SELF_DEP_STREAM, /* A stream in priority frame cannot depend on 5150aadb33SDmitri Tikhonov * itself (RFC 7540, Section 5.3.1). 5250aadb33SDmitri Tikhonov */ 5350aadb33SDmitri Tikhonov FR_ERR_HEADERS_TOO_LARGE, 5450aadb33SDmitri Tikhonov FR_ERR_UNEXPECTED_PUSH, 5550aadb33SDmitri Tikhonov FR_ERR_NOMEM, /* Cannot allocate any more memory. */ 5650aadb33SDmitri Tikhonov FR_ERR_EXPECTED_CONTIN, /* Expected continuation frame. */ 5750aadb33SDmitri Tikhonov}; 5850aadb33SDmitri Tikhonov 5950aadb33SDmitri Tikhonov 6050aadb33SDmitri Tikhonov/* This struct is used to return decoded HEADERS and PUSH_PROMISE frames. 6150aadb33SDmitri Tikhonov * Some of the fields are only used for HEADERS frames. They are marked 6250aadb33SDmitri Tikhonov * with "H" comment below. 6350aadb33SDmitri Tikhonov */ 6450aadb33SDmitri Tikhonovstruct uncompressed_headers 6550aadb33SDmitri Tikhonov{ 6650aadb33SDmitri Tikhonov uint32_t uh_stream_id; 6750aadb33SDmitri Tikhonov uint32_t uh_oth_stream_id; /* For HEADERS frame, the ID of the 6850aadb33SDmitri Tikhonov * stream that this stream depends 6950aadb33SDmitri Tikhonov * on. (Zero means unset.) For 7050aadb33SDmitri Tikhonov * PUSH_PROMISE, the promised stream 7150aadb33SDmitri Tikhonov * ID. 7250aadb33SDmitri Tikhonov */ 7350aadb33SDmitri Tikhonov unsigned uh_size; /* Number of characters in uh_headers, not 7450aadb33SDmitri Tikhonov * counting the NUL byte. 7550aadb33SDmitri Tikhonov */ 7650aadb33SDmitri Tikhonov unsigned /* H */ uh_off; 7750aadb33SDmitri Tikhonov unsigned short /* H */ uh_weight; /* 1 - 256; 0 means not set */ 7850aadb33SDmitri Tikhonov signed char /* H */ uh_exclusive; /* 0 or 1 when set; -1 means not set */ 7950aadb33SDmitri Tikhonov enum { 8050aadb33SDmitri Tikhonov /* H */ UH_FIN = (1 << 0), 8150aadb33SDmitri Tikhonov UH_PP = (1 << 1), /* Push promise */ 8250aadb33SDmitri Tikhonov } uh_flags:8; 8350aadb33SDmitri Tikhonov char uh_headers[ /* NUL-terminated C string */ 8450aadb33SDmitri Tikhonov#if FRAME_READER_TESTING 8550aadb33SDmitri Tikhonov FRAME_READER_TESTING 8650aadb33SDmitri Tikhonov#else 8750aadb33SDmitri Tikhonov 0 8850aadb33SDmitri Tikhonov#endif 8950aadb33SDmitri Tikhonov ]; 9050aadb33SDmitri Tikhonov}; 9150aadb33SDmitri Tikhonov 9250aadb33SDmitri Tikhonovstruct frame_reader_callbacks 9350aadb33SDmitri Tikhonov{ 9450aadb33SDmitri Tikhonov void (*frc_on_headers) (void *frame_cb_ctx, struct uncompressed_headers *); 9550aadb33SDmitri Tikhonov void (*frc_on_push_promise) (void *frame_cb_ctx, struct uncompressed_headers *); 9650aadb33SDmitri Tikhonov void (*frc_on_settings) (void *frame_cb_ctx, uint16_t setting_id, 9750aadb33SDmitri Tikhonov uint32_t setting_value); 9850aadb33SDmitri Tikhonov void (*frc_on_priority) (void *frame_cb_ctx, uint32_t stream_id, 9950aadb33SDmitri Tikhonov int exclusive, uint32_t dep_stream_id, 10050aadb33SDmitri Tikhonov unsigned weight); 10150aadb33SDmitri Tikhonov void (*frc_on_error) (void *frame_cb_ctx, uint32_t stream_id, 10250aadb33SDmitri Tikhonov enum frame_reader_error); 10350aadb33SDmitri Tikhonov}; 10450aadb33SDmitri Tikhonov 10550aadb33SDmitri Tikhonovtypedef ssize_t (*fr_stream_read_f)(struct lsquic_stream *, void *, size_t); 10650aadb33SDmitri Tikhonov 10750aadb33SDmitri Tikhonovstruct lsquic_frame_reader * 10850aadb33SDmitri Tikhonovlsquic_frame_reader_new (enum frame_reader_flags, unsigned max_headers_sz, 10950aadb33SDmitri Tikhonov struct lsquic_mm *, struct lsquic_stream *, 11050aadb33SDmitri Tikhonov fr_stream_read_f, struct lsquic_hdec *, 11150aadb33SDmitri Tikhonov const struct frame_reader_callbacks *, 11250aadb33SDmitri Tikhonov void *fr_cb_ctx); 11350aadb33SDmitri Tikhonov 11450aadb33SDmitri Tikhonovint 11550aadb33SDmitri Tikhonovlsquic_frame_reader_read (struct lsquic_frame_reader *); 11650aadb33SDmitri Tikhonov 11750aadb33SDmitri Tikhonovvoid 11850aadb33SDmitri Tikhonovlsquic_frame_reader_destroy (struct lsquic_frame_reader *); 11950aadb33SDmitri Tikhonov 12050aadb33SDmitri Tikhonov#endif 121