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   @callbacks = nil
35   @options = options
36   @settings = @options.http2_settings
37   @pending = []
38   @streams = {}
39   @drains = {}
40   @pings = []
41   @streams_to_close_after_receive = []
42   @buffer = buffer
43   @handshake_completed = false
44   @wait_for_handshake = @settings.key?(:wait_for_handshake) ? @settings.delete(:wait_for_handshake) : true
45   @max_concurrent_requests = @options.max_concurrent_requests || MAX_CONCURRENT_REQUESTS
46   @max_requests = @options.max_requests
47   init_connection
48 end

Public Instance methods

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