lib/httpx/altsvc.rb in httpx-1.1.5 vs lib/httpx/altsvc.rb in httpx-1.2.0

- old
+ new

@@ -2,10 +2,62 @@ require "strscan" module HTTPX module AltSvc + # makes connections able to accept requests destined to primary service. + module ConnectionMixin + using URIExtensions + + def send(request) + request.headers["alt-used"] = @origin.authority if @parser && !@write_buffer.full? && match_altsvcs?(request.uri) + + super + end + + def match?(uri, options) + return false if !used? && (@state == :closing || @state == :closed) + + match_altsvcs?(uri) && match_altsvc_options?(uri, options) + end + + private + + # checks if this is connection is an alternative service of + # +uri+ + def match_altsvcs?(uri) + @origins.any? { |origin| altsvc_match?(uri, origin) } || + AltSvc.cached_altsvc(@origin).any? do |altsvc| + origin = altsvc["origin"] + altsvc_match?(origin, uri.origin) + end + end + + def match_altsvc_options?(uri, options) + return @options == options unless @options.ssl.all? do |k, v| + v == (k == :hostname ? uri.host : options.ssl[k]) + end + + @options.options_equals?(options, Options::REQUEST_BODY_IVARS + %i[@ssl]) + end + + def altsvc_match?(uri, other_uri) + other_uri = URI(other_uri) + + uri.origin == other_uri.origin || begin + case uri.scheme + when "h2" + (other_uri.scheme == "https" || other_uri.scheme == "h2") && + uri.host == other_uri.host && + uri.port == other_uri.port + else + false + end + end + end + end + @altsvc_mutex = Thread::Mutex.new @altsvcs = Hash.new { |h, k| h[k] = [] } module_function @@ -44,11 +96,11 @@ origin = request.origin host = request.uri.host altsvc = response.headers["alt-svc"] - # https://tools.ietf.org/html/rfc7838#section-3 + # https://datatracker.ietf.org/doc/html/rfc7838#section-3 # A field value containing the special value "clear" indicates that the # origin requests all alternatives for that origin to be invalidated # (including those specified in the same response, in case of an # invalid reply containing both "clear" and alternative services). if altsvc == "clear" @@ -97,10 +149,13 @@ "https" end end def parse_altsvc_origin(alt_proto, alt_origin) - alt_scheme = parse_altsvc_scheme(alt_proto) or return + alt_scheme = parse_altsvc_scheme(alt_proto) + + return unless alt_scheme + alt_origin = alt_origin[1..-2] if alt_origin.start_with?("\"") && alt_origin.end_with?("\"") URI.parse("#{alt_scheme}://#{alt_origin}") end end