Class: Quicsilver::Protocol::ResponseEncoder
- Inherits:
-
Object
- Object
- Quicsilver::Protocol::ResponseEncoder
- Defined in:
- lib/quicsilver/protocol/response_encoder.rb
Class Method Summary collapse
-
.encode_informational(status, headers, encoder: Qpack::Encoder.new) ⇒ Object
Encode an informational (1xx) response as a single HEADERS frame.
Instance Method Summary collapse
-
#encode ⇒ Object
Buffered encode - returns all frames at once.
-
#initialize(status, headers, body, encoder: Qpack::Encoder.new, head_request: false, trailers: nil) ⇒ ResponseEncoder
constructor
A new instance of ResponseEncoder.
-
#stream_encode {|build_frame(FRAME_HEADERS, @encoder.encode(all_headers)), false| ... } ⇒ Object
Streaming encode - yields frames as they’re ready.
Constructor Details
#initialize(status, headers, body, encoder: Qpack::Encoder.new, head_request: false, trailers: nil) ⇒ ResponseEncoder
Returns a new instance of ResponseEncoder.
20 21 22 23 24 25 26 27 |
# File 'lib/quicsilver/protocol/response_encoder.rb', line 20 def initialize(status, headers, body, encoder: Qpack::Encoder.new, head_request: false, trailers: nil) @status = status @headers = headers @body = body @encoder = encoder @head_request = head_request @trailers = trailers end |
Class Method Details
.encode_informational(status, headers, encoder: Qpack::Encoder.new) ⇒ Object
Encode an informational (1xx) response as a single HEADERS frame. RFC 9114 §4.1: informational responses are encoded as HEADERS with no body.
8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/quicsilver/protocol/response_encoder.rb', line 8 def self.encode_informational(status, headers, encoder: Qpack::Encoder.new) raise ArgumentError, "Informational status must be 1xx, got #{status}" unless (100..199).include?(status) pairs = [[":status", status.to_s]] headers.each { |name, value| pairs << [name.to_s.downcase, value.to_s] } encoded = encoder.encode(pairs) Protocol.encode_varint(FRAME_HEADERS) + Protocol.encode_varint(encoded.bytesize) + encoded end |
Instance Method Details
#encode ⇒ Object
Buffered encode - returns all frames at once
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/quicsilver/protocol/response_encoder.rb', line 30 def encode frames = "".b frames << build_frame(FRAME_HEADERS, @encoder.encode(all_headers)) unless @head_request @body.each do |chunk| frames << build_frame(FRAME_DATA, chunk) unless chunk.empty? end end frames << build_frame(FRAME_HEADERS, @encoder.encode(trailer_headers)) if @trailers&.any? @body.close if @body.respond_to?(:close) frames end |
#stream_encode {|build_frame(FRAME_HEADERS, @encoder.encode(all_headers)), false| ... } ⇒ Object
Streaming encode - yields frames as they’re ready
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/quicsilver/protocol/response_encoder.rb', line 44 def stream_encode yield build_frame(FRAME_HEADERS, @encoder.encode(all_headers)), false unless @head_request last_chunk = nil @body.each do |chunk| yield build_frame(FRAME_DATA, last_chunk), false if last_chunk && !last_chunk.empty? last_chunk = chunk end if @trailers&.any? yield build_frame(FRAME_DATA, last_chunk), false if last_chunk && !last_chunk.empty? yield build_frame(FRAME_HEADERS, @encoder.encode(trailer_headers)), true elsif last_chunk && !last_chunk.empty? yield build_frame(FRAME_DATA, last_chunk), true else yield "".b, true end else yield "".b, true end @body.close if @body.respond_to?(:close) end |