1#ifndef NEFORCE_NETWORK_HTTP_HTTP2_PROTOCOL_HPP__
2#define NEFORCE_NETWORK_HTTP_HTTP2_PROTOCOL_HPP__
15NEFORCE_BEGIN_NAMESPACE__
114 NEFORCE_NODISCARD
uint32_t get_length() const noexcept {
119 void set_length(
uint32_t len)
noexcept {
120 length_hi =
static_cast<uint8_t>((len >> 16) & 0xFF);
121 length_mid =
static_cast<uint8_t>((len >> 8) & 0xFF);
122 length_lo =
static_cast<uint8_t>(len & 0xFF);
125 NEFORCE_NODISCARD
uint32_t get_stream_id() const noexcept {
126 return (
static_cast<uint32_t>(sid_r & 0x7F) << 24) | (
static_cast<uint32_t>(sid_mid) << 16) |
130 void set_stream_id(uint32_t
id)
noexcept {
131 sid_r =
static_cast<uint8_t
>((
id >> 24) & 0x7F);
132 sid_mid =
static_cast<uint8_t
>((
id >> 16) & 0xFF);
133 sid_lo1 =
static_cast<uint8_t
>((
id >> 8) & 0xFF);
134 sid_lo0 =
static_cast<uint8_t
>(
id & 0xFF);
140NEFORCE_INLINE17
constexpr uint8_t HTTP2_FLAG_END_STREAM = 0x1;
141NEFORCE_INLINE17
constexpr uint8_t HTTP2_FLAG_END_HEADERS = 0x4;
142NEFORCE_INLINE17
constexpr uint8_t HTTP2_FLAG_PADDED = 0x8;
143NEFORCE_INLINE17
constexpr uint8_t HTTP2_FLAG_PRIORITY = 0x20;
144NEFORCE_INLINE17
constexpr uint8_t HTTP2_FLAG_ACK = 0x1;
263class NEFORCE_API hpack_encoder {
279 void add_to_dynamic_table(
const string& name,
const string& value);
280 void evict_for_size(
uint32_t needed);
281 NEFORCE_NODISCARD
int32_t find_in_tables(
const string& name,
const string& value)
const;
282 NEFORCE_NODISCARD
int32_t find_name_in_tables(
const string& name)
const;
290 NEFORCE_NODISCARD
uint32_t max_table_size()
const noexcept {
return max_table_size_; }
291 NEFORCE_NODISCARD
size_t table_size()
const noexcept {
return dynamic_table_.size(); }
301class NEFORCE_API hpack_decoder {
321 void add_to_dynamic_table(
const string& name,
const string& value);
322 void evict_for_size(
uint32_t needed);
330 void decode_incremental(
byte_cursor& cur, header_callback cb);
343 using frame_callback =
350 size_t expected_length_ = 0;
354 bool reading_header_ =
true;
367 void decode_frames(
const byte_t*
data,
size_t len, frame_callback cb);
390class NEFORCE_API http2_stream {
392 explicit http2_stream(
uint32_t stream_id);
394 NEFORCE_NODISCARD
uint32_t id()
const noexcept {
return stream_id_; }
397 NEFORCE_NODISCARD
bool can_send_headers()
const;
398 NEFORCE_NODISCARD
bool can_send_data()
const;
399 NEFORCE_NODISCARD
bool can_receive()
const;
400 NEFORCE_NODISCARD
bool is_closed()
const noexcept {
return state_ == http2_stream_state::CLOSED; }
402 void on_send_headers(
bool end_stream);
403 void on_send_data(
bool end_stream);
404 void on_receive_headers(
bool end_stream);
405 void on_receive_data(
bool end_stream);
406 void on_send_rst_stream();
407 void on_receive_rst_stream();
410 NEFORCE_NODISCARD
uint32_t local_window()
const noexcept {
return local_window_; }
411 NEFORCE_NODISCARD
uint32_t remote_window()
const noexcept {
return remote_window_; }
412 void consume_local_window(
uint32_t amount);
413 void consume_remote_window(
uint32_t amount);
414 void add_local_window(
uint32_t amount);
415 void add_remote_window(
uint32_t amount);
435class NEFORCE_API http2_flow_control {
445 NEFORCE_NODISCARD
uint32_t connection_window()
const noexcept {
return connection_window_; }
464class NEFORCE_API http2_settings {
471 NEFORCE_NODISCARD
uint32_t header_table_size()
const;
472 NEFORCE_NODISCARD
bool enable_push()
const;
473 NEFORCE_NODISCARD
uint32_t max_concurrent_streams()
const;
474 NEFORCE_NODISCARD
uint32_t initial_window_size()
const;
475 NEFORCE_NODISCARD
uint32_t max_frame_size()
const;
476 NEFORCE_NODISCARD
uint32_t max_header_list_size()
const;
480 static http2_settings defaults() {
return {}; }
490NEFORCE_END_NAMESPACE__
function< void(const string &name, const string &value)> header_callback
解码回调:void(const string& name, const string& value)
vector< byte_t > byte_vector
字节向量类型别名
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long uint64_t
64位无符号整数类型
unsigned char uint8_t
8位无符号整数类型
unsigned short uint16_t
16位无符号整数类型
constexpr uint32_t HTTP2_MAX_FRAME_SIZE
HTTP/2 最大帧负载大小(RFC 7540 §4.1)
constexpr uint32_t HTTP2_DEFAULT_INITIAL_WINDOW_SIZE
默认初始流控窗口
constexpr string_view HTTP2_CLIENT_PREFACE
HTTP/2 客户端连接前言(RFC 7540 §3.5)
http2_settings_id
HTTP/2 SETTINGS 参数标识符(RFC 7540 §6.5.2)
http2_stream_state
HTTP/2 流状态(RFC 7540 §5.1)
constexpr size_t HPACK_STATIC_TABLE_SIZE
HPACK 静态表条目数
http2_frame_type
HTTP/2 帧类型(RFC 7540 §6)
constexpr uint32_t HTTP2_DEFAULT_MAX_CONCURRENT_STREAMS
默认最大并发流数
http2_error
HTTP/2 错误码(RFC 7540 §7)
constexpr uint32_t HTTP2_DEFAULT_MAX_HEADER_LIST_SIZE
默认最大头部列表大小
constexpr uint32_t HTTP2_DEFAULT_HEADER_TABLE_SIZE
HPACK 默认动态表大小
@ MAX_HEADER_LIST_SIZE
最大头部列表大小
@ HEADER_TABLE_SIZE
HPACK 动态表最大大小
@ INITIAL_WINDOW_SIZE
流级初始窗口大小
@ MAX_CONCURRENT_STREAMS
最大并发流数
@ SETTINGS_TIMEOUT
SETTINGS 确认超时
@ CONNECT_ERROR
CONNECT 错误
@ HTTP_1_1_REQUIRED
需要 HTTP/1.1
@ INADEQUATE_SECURITY
安全不足
basic_string_view< char > string_view
字符字符串视图
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
CONTINUATION 帧(RFC 7540 §6.10)
byte_vector header_block
HPACK 编码的续帧头部块
uint32_t last_stream_id
最后处理的流 ID
http2_error error_code
错误码
byte_vector debug_data
调试数据
uint64_t opaque_data
不透明数据(回显)
uint32_t stream_dependency
依赖的流 ID(0 表示根)
PUSH_PROMISE 帧(RFC 7540 §6.6)
uint32_t promised_stream_id
服务器承诺的新流 ID(必须为偶数)
byte_vector header_block
请求头部块
uint32_t stream_id
关联的流 ID(父流)
RST_STREAM 帧(RFC 7540 §6.4)
http2_error error_code
错误码
http2_settings_id id
参数标识符
SETTINGS 帧(RFC 7540 §6.5)
vector< http2_settings_entry > entries
设置参数列表
WINDOW_UPDATE 帧(RFC 7540 §6.9)
uint32_t window_size_increment
窗口增量
uint32_t stream_id
流 ID(0 表示连接级)