Methods
Public Instance
Classes and Modules
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, host: host) 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, host: nil)
[show source]
# File lib/httpx/altsvc.rb 124 def parse(altsvc, host: nil) 125 return enum_for(__method__, altsvc, host: host) unless block_given? 126 127 scanner = StringScanner.new(altsvc) 128 until scanner.eos? 129 alt_services = [] #: Array[String] 130 131 while (alt_service = scanner.scan(/[^=]+=("[^"]+")/)) 132 alt_services << alt_service 133 scanner.skip(/[, ]+/) 134 end 135 136 scanner.skip(/;/) 137 138 alt_params = [] #: Array[String] 139 loop do 140 alt_param = scanner.scan(/[^=]+=("[^"]+"|[^;,]+)/) 141 alt_params << alt_param.strip if alt_param 142 scanner.skip(/;/) 143 break if scanner.eos? || scanner.scan(/ *, */) 144 end 145 alt_params = Hash[alt_params.map do |field| 146 field.split("=", 2) 147 end] 148 149 alt_services.each do |alt_service| 150 alt_proto, alt_authority = alt_service.split("=", 2) 151 alt_origin = parse_altsvc_origin(alt_proto, alt_authority, host: host) 152 153 next unless alt_origin 154 155 yield(alt_origin, alt_params.merge("proto" => alt_proto)) 156 end 157 end 158 end
parse_altsvc_origin(alt_proto, alt_origin, host: nil)
[show source]
# File lib/httpx/altsvc.rb 169 def parse_altsvc_origin(alt_proto, alt_origin, host: nil) 170 alt_scheme = parse_altsvc_scheme(alt_proto) 171 172 return unless alt_scheme 173 174 alt_origin = alt_origin[1..-2] if alt_origin.start_with?("\"") && alt_origin.end_with?("\"") 175 176 uri = URI.parse("#{alt_scheme}://#{alt_origin}") 177 uri.host = host if uri.host.nil? || uri.host.empty? 178 uri 179 end
parse_altsvc_scheme(alt_proto)
[show source]
# File lib/httpx/altsvc.rb 160 def parse_altsvc_scheme(alt_proto) 161 case alt_proto 162 when "h2c" 163 "http" 164 when "h2", "quic", /^h3/ 165 "https" 166 end 167 end