lib/httpx/connection/http2.rb in httpx-0.8.1 vs lib/httpx/connection/http2.rb in httpx-0.8.2
- old
+ new
@@ -1,7 +1,8 @@
# frozen_string_literal: true
+require "securerandom"
require "io/wait"
require "http/2/next"
module HTTPX
class Connection::HTTP2
@@ -23,10 +24,11 @@
@max_concurrent_requests = @options.max_concurrent_requests || MAX_CONCURRENT_REQUESTS
@max_requests = @options.max_requests || 0
@pending = []
@streams = {}
@drains = {}
+ @pings = []
@buffer = buffer
@handshake_completed = false
init_connection
end
@@ -51,12 +53,12 @@
def reset
init_connection
end
- def close
- @connection.goaway unless @connection.state == :closed
+ def close(*args)
+ @connection.goaway(*args) unless @connection.state == :closed
emit(:close)
end
def empty?
@connection.state == :closed || @streams.empty?
@@ -107,10 +109,17 @@
@pending.each do |request|
emit(:error, request, ex)
end
end
+ def ping
+ ping = SecureRandom.gen_random(8)
+ @connection.ping(ping)
+ ensure
+ @pings << ping
+ end
+
private
def send_pending
while (request = @pending.shift)
break unless send(request)
@@ -141,10 +150,11 @@
@connection.on(:frame_received, &method(:on_frame_received))
@connection.on(:origin, &method(:on_origin))
@connection.on(:promise, &method(:on_promise))
@connection.on(:altsvc) { |frame| on_altsvc(frame[:origin], frame) }
@connection.on(:settings_ack, &method(:on_settings))
+ @connection.on(:ack, &method(:on_pong))
@connection.on(:goaway, &method(:on_close))
#
# Some servers initiate HTTP/2 negotiation right away, some don't.
# As such, we have to check the socket buffer. If there is something
# to read, the server initiated the negotiation. If not, we have to
@@ -302,9 +312,17 @@
emit(:promise, @streams.key(stream.parent), stream)
end
def on_origin(origin)
emit(:origin, origin)
+ end
+
+ def on_pong(ping)
+ if !@pings.delete(ping)
+ close(:protocol_error, "ping payload did not match")
+ else
+ emit(:pong)
+ end
end
def respond_to_missing?(meth, *args)
@connection.respond_to?(meth, *args) || super
end