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