Protocol::HTTP2SourceProtocolHTTP2Client

class Client

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 framer Framer

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 id Integer

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 id Integer

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_id Integer

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 settings Array

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 frame PushPromiseFrame

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