1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/*****************************************************************************
* h2frame.h: HTTP/2 frame formatting
*****************************************************************************
* Copyright (C) 2015 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <stdbool.h>
#include <stdint.h>
/**
* \defgroup h2_frames HTTP/2 frames
* \ingroup h2
* @{
*/
struct vlc_h2_frame
{
struct vlc_h2_frame *next;
uint8_t data[];
};
size_t vlc_h2_frame_size(const struct vlc_h2_frame *);
struct vlc_h2_frame *
vlc_h2_frame_headers(uint_fast32_t stream_id, uint_fast32_t mtu, bool eos,
unsigned count, const char *const headers[][2]);
struct vlc_h2_frame *
vlc_h2_frame_data(uint_fast32_t stream_id, const void *buf, size_t len,
bool eos);
struct vlc_h2_frame *
vlc_h2_frame_rst_stream(uint_fast32_t stream_id, uint_fast32_t error_code);
struct vlc_h2_frame *vlc_h2_frame_settings(void);
struct vlc_h2_frame *vlc_h2_frame_settings_ack(void);
struct vlc_h2_frame *vlc_h2_frame_ping(uint64_t opaque);
struct vlc_h2_frame *vlc_h2_frame_pong(uint64_t opaque);
struct vlc_h2_frame *
vlc_h2_frame_goaway(uint_fast32_t last_stream_id, uint_fast32_t error_code);
struct vlc_h2_frame *
vlc_h2_frame_window_update(uint_fast32_t stream_id, uint_fast32_t credit);
void vlc_h2_frame_dump(void *, const struct vlc_h2_frame *, const char *);
enum vlc_h2_error {
VLC_H2_NO_ERROR,
VLC_H2_PROTOCOL_ERROR,
VLC_H2_INTERNAL_ERROR,
VLC_H2_FLOW_CONTROL_ERROR,
VLC_H2_SETTINGS_TIMEOUT,
VLC_H2_STREAM_CLOSED,
VLC_H2_FRAME_SIZE_ERROR,
VLC_H2_REFUSED_STREAM,
VLC_H2_CANCEL,
VLC_H2_COMPRESSION_ERROR,
VLC_H2_CONNECT_ERROR,
VLC_H2_ENHANCE_YOUR_CALM,
VLC_H2_INADEQUATE_SECURITY,
VLC_H2_HTTP_1_1_REQUIRED,
};
const char *vlc_h2_strerror(uint_fast32_t);
enum vlc_h2_setting {
VLC_H2_SETTING_HEADER_TABLE_SIZE = 0x0001,
VLC_H2_SETTING_ENABLE_PUSH,
VLC_H2_SETTING_MAX_CONCURRENT_STREAMS,
VLC_H2_SETTING_INITIAL_WINDOW_SIZE,
VLC_H2_SETTING_MAX_FRAME_SIZE,
VLC_H2_SETTING_MAX_HEADER_LIST_SIZE,
};
const char *vlc_h2_setting_name(uint_fast16_t);
/* Our settings */
#define VLC_H2_MAX_HEADER_TABLE 4096 /* Header (compression) table size */
#define VLC_H2_MAX_STREAMS 0 /* Concurrent peer-initiated streams */
#define VLC_H2_INIT_WINDOW 1048575 /* Initial congestion window size */
#define VLC_H2_MAX_FRAME 1048576 /* Frame size */
#define VLC_H2_MAX_HEADER_LIST 65536 /* Header (decompressed) list size */
/* Protocol default settings */
#define VLC_H2_DEFAULT_MAX_HEADER_TABLE 4096
#define VLC_H2_DEFAULT_INIT_WINDOW 65535
#define VLC_H2_DEFAULT_MAX_FRAME 16384
struct vlc_h2_parser;
struct vlc_h2_parser_cbs
{
void (*setting)(void *ctx, uint_fast16_t id, uint_fast32_t value);
int (*settings_done)(void *ctx);
int (*ping)(void *ctx, uint_fast64_t opaque);
void (*error)(void *ctx, uint_fast32_t code);
int (*reset)(void *ctx, uint_fast32_t last_seq, uint_fast32_t code);
void (*window_status)(void *ctx, uint32_t *rcwd);
void *(*stream_lookup)(void *ctx, uint_fast32_t id);
int (*stream_error)(void *ctx, uint_fast32_t id, uint_fast32_t code);
void (*stream_headers)(void *ctx, unsigned count,
const char *const headers[][2]);
int (*stream_data)(void *ctx, struct vlc_h2_frame *f);
void (*stream_end)(void *ctx);
int (*stream_reset)(void *ctx, uint_fast32_t code);
};
struct vlc_h2_parser *vlc_h2_parse_init(void *ctx,
const struct vlc_h2_parser_cbs *cbs);
int vlc_h2_parse(struct vlc_h2_parser *, struct vlc_h2_frame *);
void vlc_h2_parse_destroy(struct vlc_h2_parser *);
#define VLC_H2_MAX_HEADERS 255
const uint8_t *vlc_h2_frame_data_get(const struct vlc_h2_frame *f,
size_t *restrict len);
#define vlc_h2_frame_data_get(f, l) \
_Generic((f), \
const struct vlc_h2_frame *: (vlc_h2_frame_data_get)(f, l), \
struct vlc_h2_frame *: (uint8_t *)(vlc_h2_frame_data_get)(f, l))
/** @} */
|