class Client < Connection
- Inherits from
Connection: #id, #[], #maximum_frame_size, #maximum_concurrent_streams, #closed?, #goaway_received?, #close_if_drained!, #delete, #close, #encode_headers, #decode_headers, #next_stream_id, #ignore_frame?, #synchronize, #read_frame, #send_settings, #close!, #send_goaway, #receive_goaway, #write_frame, #write_frames, #update_local_settings, #update_remote_settings, #process_settings, #open!, #receive_settings, #send_ping, #receive_ping, #receive_data, #accept_stream, #accept_push_promise_stream, #create_stream, #receive_headers, #receive_priority_update, #client_stream_id?, #server_stream_id?, #idle_stream_id?, #closed_stream_id?, #receive_reset_stream, #consume_window, #receive_window_update, #receive_continuation, #receive_frame, #available_size, #available_frame_size, #consume_remote_window, #update_local_window, #consume_local_window, #request_window_update, #send_window_update, #window_updated
Represents an HTTP/2 client connection. Manages client-side protocol semantics including stream ID allocation, connection preface handling, and push promise processing.
Definitions
def initialize(framer)
Initialize a new HTTP/2 client connection.
Signature
-
parameter
framerFramer The frame handler for reading/writing HTTP/2 frames.
Implementation
def initialize(framer)
super(framer, 1)
end
def local_stream_id?(id)
Check if the given stream ID represents a locally-initiated stream. Client streams have odd numbered IDs.
Signature
-
parameter
idInteger The stream ID to check.
-
returns
bool True if the stream ID is locally-initiated.
Implementation
def local_stream_id?(id)
id.odd?
end
def remote_stream_id?(id)
Check if the given stream ID represents a remotely-initiated stream. Server streams have even numbered IDs.
Signature
-
parameter
idInteger The stream ID to check.
-
returns
bool True if the stream ID is remotely-initiated.
Implementation
def remote_stream_id?(id)
id.even?
end
def valid_remote_stream_id?(stream_id)
Check if the given stream ID is valid for remote initiation. Server-initiated streams must have even numbered IDs.
Signature
-
parameter
stream_idInteger The stream ID to validate.
-
returns
bool True if the stream ID is valid for remote initiation.
Implementation
def valid_remote_stream_id?(stream_id)
stream_id.even?
end
def send_connection_preface(settings = [])
Send the HTTP/2 connection preface and initial settings. This must be called once when the connection is first established.
Signature
-
parameter
settingsArray Optional settings to send with the connection preface.
-
raises
ProtocolError If called when not in the new state.
Implementation
def send_connection_preface(settings = [])
if @state == :new
@framer.write_connection_preface
send_settings(settings)
yield if block_given?
read_frame do |frame|
unless frame.is_a? SettingsFrame
raise ProtocolError, "First frame must be #{SettingsFrame}, but got #{frame.class}"
end
end
else
raise ProtocolError, "Cannot send connection preface in state #{@state}"
end
end
def create_push_promise_stream
Clients cannot create push promise streams.
Signature
-
raises
ProtocolError Always, as clients cannot initiate push promises.
Implementation
def create_push_promise_stream
raise ProtocolError, "Cannot create push promises from client!"
end
def receive_push_promise(frame)
Process a push promise frame received from the server.
Signature
-
parameter
framePushPromiseFrame The push promise frame to process.
-
returns
Array(Stream, Hash) | Nil The promised stream and request headers, or nil if no associated stream.
Implementation
def receive_push_promise(frame)
if frame.stream_id == 0
raise ProtocolError, "Cannot receive headers for stream 0!"
end
if stream = @streams[frame.stream_id]
# This is almost certainly invalid:
promised_stream, request_headers = stream.receive_push_promise(frame)
return promised_stream, request_headers
end
end