class HTTPX::Connection::HTTP2

  1. lib/httpx/connection/http2.rb
Superclass: Object

Included modules

  1. Callbacks
  2. Loggable

Constants

MAX_CONCURRENT_REQUESTS = ::HTTP2::DEFAULT_MAX_CONCURRENT_STREAMS  

Public Instance Aliases

reset -> init_connection

Attributes

pending [R]
streams [R]

Public Class methods

new(buffer, options)
[show source]
   # File lib/httpx/connection/http2.rb
33 def initialize(buffer, options)
34   @options = options
35   @settings = @options.http2_settings
36   @pending = []
37   @streams = {}
38   @drains = {}
39   @pings = []
40   @streams_to_close_after_receive = []
41   @buffer = buffer
42   @handshake_completed = false
43   @wait_for_handshake = @settings.key?(:wait_for_handshake) ? @settings.delete(:wait_for_handshake) : true
44   @max_concurrent_requests = @options.max_concurrent_requests || MAX_CONCURRENT_REQUESTS
45   @max_requests = @options.max_requests
46   init_connection
47 end

Public Instance methods

<<(data)
[show source]
    # File lib/httpx/connection/http2.rb
112 def <<(data)
113   @connection << data
114 
115   while (stream, request, error = @streams_to_close_after_receive.shift)
116     # these streams were marked for cancellation due to errors found while processing the
117     # data received by the peer.
118     emit_stream_error(stream, request, error)
119   end
120 end
close()
[show source]
    # File lib/httpx/connection/http2.rb
 96 def close
 97   unless @connection.state == :closed
 98     @connection.goaway
 99     emit(:timeout, @options.timeout[:close_handshake_timeout])
100   end
101   emit(:close)
102 end
consume()
[show source]
    # File lib/httpx/connection/http2.rb
142 def consume
143   @streams.each do |request, stream|
144     next unless request.can_buffer?
145 
146     handle(request, stream)
147   end
148 end
empty?()
[show source]
    # File lib/httpx/connection/http2.rb
104 def empty?
105   @connection.state == :closed || @streams.empty?
106 end
exhausted?()
[show source]
    # File lib/httpx/connection/http2.rb
108 def exhausted?
109   !@max_requests.positive?
110 end
handle_error(ex, request = nil)
[show source]
    # File lib/httpx/connection/http2.rb
150 def handle_error(ex, request = nil)
151   if ex.is_a?(OperationTimeoutError) && !@handshake_completed && @connection.state != :closed
152     @connection.goaway(:settings_timeout, "closing due to settings timeout")
153     emit(:close_handshake)
154     settings_ex = SettingsTimeoutError.new(ex.timeout, ex.message)
155     settings_ex.set_backtrace(ex.backtrace)
156     ex = settings_ex
157   end
158   while (req, _ = @streams.shift)
159     next if request && request == req
160 
161     emit(:error, req, ex)
162   end
163   while (req = @pending.shift)
164     next if request && request == req
165 
166     emit(:error, req, ex)
167   end
168 end
interests()
[show source]
   # File lib/httpx/connection/http2.rb
55 def interests
56   if @connection.state == :closed
57     return unless @handshake_completed
58 
59     return if @buffer.empty?
60 
61     # HTTP/2 GOAWAY frame buffered.
62     return :w
63   end
64 
65   unless @connection.state == :connected && @handshake_completed
66     # HTTP/2 in intermediate state or still completing initialization-
67     return @buffer.empty? ? :r : :rw
68   end
69 
70   unless @connection.send_buffer.empty?
71     # HTTP/2 connection is buffering data chunks and failing to emit DATA frames,
72     # most likely because the flow control window is exhausted.
73     return :rw unless @buffer.empty?
74 
75     # waiting for WINDOW_UPDATE frames
76     return :r
77   end
78 
79   # there are pending bufferable requests
80   return :w if !@pending.empty? && can_buffer_more_requests?
81 
82   # there are pending frames from the last run
83   return :w unless @drains.empty?
84 
85   if @buffer.empty?
86     # skip if no more requests or pings to process
87     return if @streams.empty? && @pings.empty?
88 
89     :r
90   else
91     # buffered frames
92     :w
93   end
94 end
ping()
[show source]
    # File lib/httpx/connection/http2.rb
170 def ping
171   ping = SecureRandom.gen_random(8)
172   @connection.ping(ping.dup)
173 ensure
174   @pings << ping
175 end
reset_requests()
[show source]
    # File lib/httpx/connection/http2.rb
181 def reset_requests; end
send(request, head = false)
[show source]
    # File lib/httpx/connection/http2.rb
122 def send(request, head = false)
123   unless can_buffer_more_requests?
124     head ? @pending.unshift(request) : @pending << request
125     return false
126   end
127   unless (stream = @streams[request])
128     stream = @connection.new_stream(**request.http2_stream_options)
129     handle_stream(stream, request)
130     @streams[request] = stream
131     @max_requests -= 1
132   end
133   handle(request, stream)
134   true
135 rescue ::HTTP2::Error::StreamLimitExceeded
136   @pending.unshift(request)
137   false
138 rescue ::HTTP2::Error::Error, ArgumentError => e
139   emit(:error, request, e)
140 end
timeout()
[show source]
   # File lib/httpx/connection/http2.rb
49 def timeout
50   return @options.timeout[:operation_timeout] if @handshake_completed
51 
52   @options.timeout[:settings_timeout]
53 end
waiting_for_ping?()
[show source]
    # File lib/httpx/connection/http2.rb
177 def waiting_for_ping?
178   @pings.any?
179 end