module HTTPX::AltSvc

  1. lib/httpx/altsvc.rb
  2. lib/httpx/connection.rb
  3. show all

Classes and Modules

  1. HTTPX::AltSvc::ConnectionMixin

Public Instance methods

cached_altsvc(origin)
[show source]
   # File lib/httpx/altsvc.rb
68 def cached_altsvc(origin)
69   now = Utils.now
70   @altsvc_mutex.synchronize do
71     lookup(origin, now)
72   end
73 end
cached_altsvc_set(origin, entry)
[show source]
   # File lib/httpx/altsvc.rb
75 def cached_altsvc_set(origin, entry)
76   now = Utils.now
77   @altsvc_mutex.synchronize do
78     return if @altsvcs[origin].any? { |altsvc| altsvc["origin"] == entry["origin"] }
79 
80     entry["TTL"] = Integer(entry["ma"]) + now if entry.key?("ma")
81     @altsvcs[origin] << entry
82     entry
83   end
84 end
emit(request, response)
[show source]
    # File lib/httpx/altsvc.rb
 95 def emit(request, response)
 96   return unless response.respond_to?(:headers)
 97   # Alt-Svc
 98   return unless response.headers.key?("alt-svc")
 99 
100   origin = request.origin
101   host = request.uri.host
102 
103   altsvc = response.headers["alt-svc"]
104 
105   # https://datatracker.ietf.org/doc/html/rfc7838#section-3
106   # A field value containing the special value "clear" indicates that the
107   # origin requests all alternatives for that origin to be invalidated
108   # (including those specified in the same response, in case of an
109   # invalid reply containing both "clear" and alternative services).
110   if altsvc == "clear"
111     @altsvc_mutex.synchronize do
112       @altsvcs[origin].clear
113     end
114 
115     return
116   end
117 
118   parse(altsvc) do |alt_origin, alt_params|
119     alt_origin.host ||= host
120     yield(alt_origin, origin, alt_params)
121   end
122 end
lookup(origin, ttl)
[show source]
   # File lib/httpx/altsvc.rb
86 def lookup(origin, ttl)
87   return [] unless @altsvcs.key?(origin)
88 
89   @altsvcs[origin] = @altsvcs[origin].select do |entry|
90     !entry.key?("TTL") || entry["TTL"] > ttl
91   end
92   @altsvcs[origin].reject { |entry| entry["noop"] }
93 end
parse(altsvc)
[show source]
    # File lib/httpx/altsvc.rb
124 def parse(altsvc)
125   return enum_for(__method__, altsvc) unless block_given?
126 
127   scanner = StringScanner.new(altsvc)
128   until scanner.eos?
129     alt_service = scanner.scan(/[^=]+=("[^"]+"|[^;,]+)/)
130 
131     alt_params = []
132     loop do
133       alt_param = scanner.scan(/[^=]+=("[^"]+"|[^;,]+)/)
134       alt_params << alt_param.strip if alt_param
135       scanner.skip(/;/)
136       break if scanner.eos? || scanner.scan(/ *, */)
137     end
138     alt_params = Hash[alt_params.map { |field| field.split("=", 2) }]
139 
140     alt_proto, alt_authority = alt_service.split("=", 2)
141     alt_origin = parse_altsvc_origin(alt_proto, alt_authority)
142     return unless alt_origin
143 
144     yield(alt_origin, alt_params.merge("proto" => alt_proto))
145   end
146 end
parse_altsvc_origin(alt_proto, alt_origin)
[show source]
    # File lib/httpx/altsvc.rb
157 def parse_altsvc_origin(alt_proto, alt_origin)
158   alt_scheme = parse_altsvc_scheme(alt_proto)
159 
160   return unless alt_scheme
161 
162   alt_origin = alt_origin[1..-2] if alt_origin.start_with?("\"") && alt_origin.end_with?("\"")
163 
164   URI.parse("#{alt_scheme}://#{alt_origin}")
165 end
parse_altsvc_scheme(alt_proto)
[show source]
    # File lib/httpx/altsvc.rb
148 def parse_altsvc_scheme(alt_proto)
149   case alt_proto
150   when "h2c"
151     "http"
152   when "h2"
153     "https"
154   end
155 end