Files
proxypin/lib/network/http/h2/setting.dart
2025-05-09 22:19:04 +08:00

88 lines
3.5 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'package:proxypin/network/channel/channel_context.dart';
import 'package:proxypin/network/http/h2/frame.dart';
import 'package:proxypin/network/util/byte_buf.dart';
class StreamSetting {
/// 允许发送方通知远程端点用于解码头块的头压缩表的最大大小(以八位字节为单位)。
/// 初始值为4096个八位字节。
int headTableSize = 4096;
///如果一个端点接收到的这个参数设置为0它就不能发送PUSH_PROMISE帧。
///初始值为1表示允许服务器推送。
bool enablePush = true;
///指示发送方允许的最大并发流数。这个限制是定向的它适用于发送方允许接收方创建的流的数量。最初对该值没有限制。建议此值不小于100以免不必要地限制并行性。
int? maxConcurrentStreams;
/// 指示发送方用于流级流控制的初始窗口大小以八位字节为单位。初始值为216-165535个八位字节。
int initialWindowSize = 65535;
///表示发送方愿意接收的最大帧有效负载的大小(以八位字节为单位)。
int maxFrameSize = 16384;
///建议设置通知对等方发送方准备接受的头列表的最大大小(以八位字节为单位)。
///该值基于头字段的未压缩大小包括名称和值的长度以八位字节为单位加上每个头字段32个八位字节的开销。
int? maxHeaderListSize;
}
class SettingHandler {
static void handleSettingsFrame(ChannelContext channelContext, FrameHeader frameHeader, ByteBuf payload) {
// SETTINGS frames must have a length that is a multiple of 6 bytes
if (frameHeader.length % 6 != 0) {
throw Exception("Invalid SETTINGS frame length");
}
// If the SETTINGS frame has the ACK flag set, then it is an acknowledgement
if (frameHeader.hasAckFlag) {
// Handle SETTINGS ACK
return;
}
var setting = channelContext.setting ??= StreamSetting();
// Otherwise, it is a SETTINGS frame that carries settings
while (payload.isReadable()) {
int identifier = payload.readShort();
int value = payload.readInt();
// print("SettingHandler.handleSettingsFrame identifier=$identifier value=$value");
// Handle the setting based on its identifier
switch (identifier) {
case 1: // SETTINGS_HEADER_TABLE_SIZE
setting.headTableSize = value;
break;
case 2: // SETTINGS_ENABLE_PUSH
setting.enablePush = value == 1;
break;
case 3: // SETTINGS_MAX_CONCURRENT_STREAMS
setting.maxConcurrentStreams = value;
break;
case 4: // SETTINGS_INITIAL_WINDOW_SIZE
setting.initialWindowSize = value;
break;
case 5: // SETTINGS_MAX_FRAME_SIZE
setting.maxFrameSize = value;
break;
case 6: // SETTINGS_MAX_HEADER_LIST_SIZE
setting.maxHeaderListSize = value;
default:
break;
}
}
}
}