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