handleHttp3StreamChunk method
void
handleHttp3StreamChunk(})
Implementation
void handleHttp3StreamChunk(
int streamId,
int streamOffset,
Uint8List streamData, {
required bool fin,
}) {
final chunks = h3.streamChunks.putIfAbsent(
streamId,
() => <int, Uint8List>{},
);
chunks[streamOffset] = streamData;
String kind = h3.streamKinds[streamId] ?? 'unknown';
// ----------------------------------------------------------
// 1) Determine stream kind
// ----------------------------------------------------------
if (kind == 'unknown') {
if (_isClientInitiatedBidi(streamId)) {
kind = 'request';
h3.streamKinds[streamId] = kind;
h3.streamTypePrefixLen[streamId] = 0;
} else if (_isClientInitiatedUni(streamId)) {
final zeroChunk = chunks[0];
if (zeroChunk == null) {
return; // need stream type prefix first
}
final typeInfo = readVarInt(zeroChunk, 0);
if (typeInfo == null) {
return;
}
final streamType = typeInfo.value as int;
final prefixLen = typeInfo.byteLength as int;
h3.streamTypePrefixLen[streamId] = prefixLen;
if (streamType == H3_STREAM_TYPE_CONTROL) {
kind = 'client_control';
h3.peerControlStreamSeen = true;
print('â
Saw client HTTP/3 control stream on stream $streamId');
// đ´ ADD THIS LINE
// sendHttp3SettingsPing();
} else if (streamType == H3_STREAM_TYPE_QPACK_ENCODER) {
kind = 'qpack_encoder';
print('â
Saw client QPACK encoder stream on stream $streamId');
} else if (streamType == H3_STREAM_TYPE_QPACK_DECODER) {
kind = 'qpack_decoder';
print('â
Saw client QPACK decoder stream on stream $streamId');
} else if (streamType == WT_STREAM_TYPE_UNI) {
kind = 'wt_uni';
print('â
Saw client WebTransport uni stream on stream $streamId');
} else {
kind = 'other_client_uni';
print(
'âšī¸ Ignoring unknown client uni stream type '
'0x${streamType.toRadixString(16)} on stream $streamId',
);
}
h3.streamKinds[streamId] = kind;
} else {
kind = 'other';
h3.streamKinds[streamId] = kind;
h3.streamTypePrefixLen[streamId] = 0;
}
}
final prefixLen = h3.streamTypePrefixLen[streamId] ?? 0;
// ----------------------------------------------------------
// 2) Handle request streams directly as HTTP/3 frame streams
// ----------------------------------------------------------
if (kind == 'request' || kind == 'client_control') {
final rawStart = streamOffset;
final rawEnd = streamOffset + streamData.length;
if (rawEnd <= prefixLen) {
return;
}
int sliceStartInChunk = 0;
int h3Offset = rawStart - prefixLen;
if (rawStart < prefixLen) {
sliceStartInChunk = prefixLen - rawStart;
h3Offset = 0;
}
final h3Bytes = streamData.sublist(sliceStartInChunk);
final frameChunks = h3.h3FrameChunks.putIfAbsent(
streamId,
() => <int, Uint8List>{},
);
frameChunks[h3Offset] = h3Bytes;
final readOffset = h3.h3FrameReadOffsets[streamId] ?? 0;
final extracted = extract_h3_frames_from_chunks(frameChunks, readOffset);
h3.h3FrameReadOffsets[streamId] = extracted['new_from_offset'] as int;
for (final frame in extracted['frames']) {
final int type = frame['frame_type'] as int;
final Uint8List payload = frame['payload'] as Uint8List;
if (kind == 'request') {
if (type == H3_FRAME_HEADERS) {
_handleHttp3HeadersFrame(streamId, payload);
} else if (type == H3_FRAME_DATA) {
print('đĻ HTTP/3 DATA on stream=$streamId len=${payload.length}');
} else {
print(
'âšī¸ Ignoring unsupported request-stream frame '
'0x${type.toRadixString(16)} on stream=$streamId',
);
}
} else if (kind == 'client_control') {
if (type == H3_FRAME_SETTINGS) {
final settings = parse_h3_settings_frame(payload);
print('â
Parsed client HTTP/3 SETTINGS: $settings');
} else {
print(
'âšī¸ Ignoring client control-frame type '
'0x${type.toRadixString(16)}',
);
}
}
}
if (fin) {
print('â
QUIC stream $streamId FIN received');
}
return;
}
// ----------------------------------------------------------
// 3) QPACK streams (currently just recognize and ignore)
// ----------------------------------------------------------
if (kind == 'qpack_encoder' || kind == 'qpack_decoder') {
if (fin) {
print('â
QPACK stream $streamId FIN received');
}
return;
}
// ----------------------------------------------------------
// 4) WebTransport unidirectional streams
// ----------------------------------------------------------
if (kind == 'wt_uni') {
_handleWebTransportUniStreamChunk(
streamId,
streamOffset,
streamData,
fin: fin,
);
return;
}
if (fin) {
print('â
QUIC stream $streamId FIN received');
}
}