sendPushResponse method
Send a push response for pushId by creating a server-initiated push
stream and transmitting the response as HEADERS (and optional DATA)
frames on it.
Per RFC 9114 §4.4 and §6.2.2, a push stream is a unidirectional stream
whose first bytes are the stream type varint 0x01 (push) followed by a
varint-encoded push ID. The push response is then carried as a sequence
of HTTP/3 frames (HEADERS, then DATA if the response has a body).
A PUSH_PROMISE for pushId must have been previously sent via
sendPushPromise (i.e. hasPushPromise must return true).
Returns the QUIC stream ID allocated for the push stream, or -1 if the
underlying transport could not allocate a unidirectional stream (in which
case the raw push-stream bytes are queued in pendingQuicPackets).
Implementation
Future<int> sendPushResponse(int pushId, Http3Response response) async {
if (!hasPushPromise(pushId)) {
throw StateError(
'No push promise registered for pushId $pushId; '
'call sendPushPromise first',
);
}
// Build the push-stream body: VarInt(pushId) + HEADERS frame [+ DATA frame].
final pushIdBytes = VarInt.encode(pushId);
final headersFrame = Http3HeadersFrame(
encodedFieldSection: response.encodeHeaders(encoder: qpackEncoder),
).toFrame();
final builder = BytesBuilder();
builder.add(pushIdBytes);
builder.add(headersFrame.serialize());
if (response.body != null && response.body!.isNotEmpty) {
final dataFrame = Http3DataFrame(data: response.body!).toFrame();
builder.add(dataFrame.serialize());
}
final pushStreamBody = builder.toBytes();
final streamId = await _openUnidirectionalStream(
StreamType.push,
Uint8List.fromList(pushStreamBody),
);
if (streamId >= 0) {
_pushStreamIds[pushId] = streamId;
}
return streamId;
}