Class: Protocol::HTTP2::Client

Inherits:
Connection show all
Defined in:
lib/protocol/http2/client.rb

Overview

Represents an HTTP/2 client connection. Manages client-side protocol semantics including stream ID allocation, connection preface handling, and push promise processing.

Instance Attribute Summary

Attributes inherited from Connection

#dependencies, #dependency, #framer, #local_settings, #local_window, #remote_settings, #remote_stream_id, #remote_window, #state, #streams

Instance Method Summary collapse

Methods inherited from Connection

#[], #accept_push_promise_stream, #accept_stream, #client_stream_id?, #close, #close!, #closed?, #closed_stream_id?, #consume_window, #create_stream, #decode_headers, #delete, #encode_headers, #id, #idle_stream_id?, #ignore_frame?, #maximum_concurrent_streams, #maximum_frame_size, #next_stream_id, #open!, #process_settings, #read_frame, #receive_continuation, #receive_data, #receive_frame, #receive_goaway, #receive_headers, #receive_ping, #receive_priority_update, #receive_reset_stream, #receive_settings, #receive_window_update, #send_goaway, #send_ping, #send_settings, #server_stream_id?, #synchronize, #update_local_settings, #update_remote_settings, #write_frame, #write_frames

Methods included from FlowControlled

#available_frame_size, #available_size, #consume_local_window, #consume_remote_window, #receive_window_update, #request_window_update, #send_window_update, #update_local_window, #window_updated

Constructor Details

#initialize(framer) ⇒ Client

Initialize a new HTTP/2 client connection.



16
17
18
# File 'lib/protocol/http2/client.rb', line 16

def initialize(framer)
  super(framer, 1)
end

Instance Method Details

#create_push_promise_streamObject

Clients cannot create push promise streams.

Raises:



69
70
71
# File 'lib/protocol/http2/client.rb', line 69

def create_push_promise_stream
  raise ProtocolError, "Cannot create push promises from client!"
end

#local_stream_id?(id) ⇒ Boolean

Check if the given stream ID represents a locally-initiated stream. Client streams have odd numbered IDs.

Returns:

  • (Boolean)


24
25
26
# File 'lib/protocol/http2/client.rb', line 24

def local_stream_id?(id)
  id.odd?
end

#receive_push_promise(frame) ⇒ Object

Process a push promise frame received from the server.



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/protocol/http2/client.rb', line 76

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

#remote_stream_id?(id) ⇒ Boolean

Check if the given stream ID represents a remotely-initiated stream. Server streams have even numbered IDs.

Returns:

  • (Boolean)


32
33
34
# File 'lib/protocol/http2/client.rb', line 32

def remote_stream_id?(id)
  id.even?
end

#send_connection_preface(settings = []) ⇒ Object

Send the HTTP/2 connection preface and initial settings. This must be called once when the connection is first established.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/protocol/http2/client.rb', line 49

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

#valid_remote_stream_id?(stream_id) ⇒ Boolean

Check if the given stream ID is valid for remote initiation. Server-initiated streams must have even numbered IDs.

Returns:

  • (Boolean)


40
41
42
# File 'lib/protocol/http2/client.rb', line 40

def valid_remote_stream_id?(stream_id)
  stream_id.even?
end