sendPushResponse method

Future<int> sendPushResponse(
  1. int pushId,
  2. Http3Response response
)

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;
}