fixed a few checks around alt-svc which weren't working:

* alt-svc connection is idle, no IO available, take that into account
when matching;
* we now merge connections when alt-svc'ing, so no need to purge and
send requests, just purge;
* URI's weren't matching well for altsvc, as they were testing if the
URIs were the same, not its origins;
* do not force h2 negotiation when opening alt-svc connection; this
is a trade-off to make it all work for now, as when connecting to an
h2-enabled alt service and we don't support h2 (like in ruby 2.1), we'll
still get an SSL HTTP/1.1 alt service
This commit is contained in:
HoneyryderChuck 2019-12-22 00:29:03 +00:00
parent d6b93a233d
commit 2b6b4d66ef
4 changed files with 13 additions and 18 deletions

View File

@ -87,7 +87,7 @@ module HTTPX
# was the result of coalescing. To prevent blind trust in the case where the
# origin came from an ORIGIN frame, we're going to verify the hostname with the
# SSL certificate
(@origins.size == 1 || @origin == uri.origin || @io.verify_hostname(uri.host))
(@origins.size == 1 || @origin == uri.origin || (@io && @io.verify_hostname(uri.host)))
) || match_altsvcs?(uri)
) && @options == options
end
@ -130,7 +130,7 @@ module HTTPX
def purge_pending
[@parser.pending, @pending].each do |pending|
pending.reject! do |request, *args|
yield(request, args)
yield(request, args) if block_given?
end
end
end

View File

@ -67,10 +67,11 @@ module HTTPX
def altsvc_match?(uri)
uri = URI.parse(uri)
self == uri || begin
origin == uri.origin || begin
case scheme
when 'h2'
uri.scheme == "https" &&
when "h2"
(uri.scheme == "https" || uri.scheme == "h2") &&
host == uri.host &&
(port || default_port) == (uri.port || uri.default_port)
else

View File

@ -30,7 +30,7 @@ module HTTPX
def verify_hostname(host)
return false if @ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE
return false if @io.peer_cert.nil?
return false if !@io.respond_to?(:peer_cert) || @io.peer_cert.nil?
OpenSSL::SSL.verify_certificate_identity(@io.peer_cert, host)
end

View File

@ -93,15 +93,12 @@ module HTTPX
# incidentally, all requests will be re-routed to the first
# advertised alt-svc, which incidentally follows the spec.
existing_connection.purge_pending do |request|
is_idle = request.origin == origin &&
request.state == :idle &&
!request.headers.key?("alt-used")
if is_idle
log(level: 1) { "#{origin} alt-svc: sending #{request.uri} to #{alt_origin}" }
connection.send(request)
end
is_idle
request.origin == origin &&
request.state == :idle &&
!request.headers.key?("alt-used")
end
connection.merge(existing_connection)
rescue UnsupportedSchemeError
altsvc["noop"] = true
end
@ -137,10 +134,7 @@ module HTTPX
case uri.scheme
when "http"
"tcp"
when "https"
"ssl"
when "h2"
options = options.merge(ssl: SSL::TLS_OPTIONS)
when "https", "h2"
"ssl"
else
raise UnsupportedSchemeError, "#{uri}: #{uri.scheme}: unsupported URI scheme"