Class: Quicsilver::Protocol::StreamOutput

Inherits:
Object
  • Object
show all
Defined in:
lib/quicsilver/protocol/stream_output.rb

Overview

Reads from a Protocol::HTTP::Body::Readable response body and writes HTTP/3 DATA frames to the transport.

Transport-agnostic: takes a writer block/callable that handles the actual sending. Works with msquic, kernel QUIC sockets, or any transport that can send bytes with a FIN flag.

Instance Method Summary collapse

Constructor Details

#initialize(body, &writer) ⇒ StreamOutput

Returns a new instance of StreamOutput.

Parameters:

  • body (Protocol::HTTP::Body::Readable)

    The response body to stream.

  • writer (#call)

    A callable that accepts (data, fin) — sends bytes to the transport. ‘fin: true` signals end of stream.



17
18
19
20
# File 'lib/quicsilver/protocol/stream_output.rb', line 17

def initialize(body, &writer)
  @body = body
  @writer = writer
end

Instance Method Details

#stream(send_fin: true) ⇒ void

This method returns an undefined value.

Stream all chunks from the response body as HTTP/3 DATA frames.

Each chunk is wrapped in an HTTP/3 DATA frame (type 0x00) and sent via the writer. The final chunk is sent with fin=true.

Parameters:

  • send_fin (Boolean) (defaults to: true)

    Whether to send FIN after the last chunk. Set to false when trailers will follow.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/quicsilver/protocol/stream_output.rb', line 30

def stream(send_fin: true)
  last_chunk = nil

  while (chunk = @body.read)
    if last_chunk
      @writer.call(build_data_frame(last_chunk), false)
    end
    last_chunk = chunk
  end

  if last_chunk
    @writer.call(build_data_frame(last_chunk), send_fin)
  elsif send_fin
    @writer.call("".b, true)
  end
ensure
  @body.close if @body.respond_to?(:close)
end