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