Module: HTTPX::AltSvc
- Defined in:
- lib/httpx/altsvc.rb
Class Method Summary collapse
- .cached_altsvc(origin) ⇒ Object
- .cached_altsvc_set(origin, entry) ⇒ Object
- .emit(request, response) ⇒ Object
- .lookup(origin, ttl) ⇒ Object
- .parse(altsvc) ⇒ Object
- .parse_altsvc_scheme(alt_proto) ⇒ Object
Instance Method Summary collapse
Class Method Details
.cached_altsvc(origin) ⇒ Object
12 13 14 15 16 17 |
# File 'lib/httpx/altsvc.rb', line 12 def cached_altsvc(origin) now = Utils.now @altsvc_mutex.synchronize do lookup(origin, now) end end |
.cached_altsvc_set(origin, entry) ⇒ Object
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/httpx/altsvc.rb', line 19 def cached_altsvc_set(origin, entry) now = Utils.now @altsvc_mutex.synchronize do return if @altsvcs[origin].any? { |altsvc| altsvc["origin"] == entry["origin"] } entry["TTL"] = Integer(entry["ma"]) + now if entry.key?("ma") @altsvcs[origin] << entry entry end end |
.emit(request, response) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/httpx/altsvc.rb', line 39 def emit(request, response) return unless response.respond_to?(:headers) # Alt-Svc return unless response.headers.key?("alt-svc") origin = request.origin host = request.uri.host altsvc = response.headers["alt-svc"] # https://tools.ietf.org/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" @altsvc_mutex.synchronize do @altsvcs[origin].clear end return end parse(altsvc) do |alt_origin, alt_params| alt_origin.host ||= host yield(alt_origin, origin, alt_params) end end |
.lookup(origin, ttl) ⇒ Object
30 31 32 33 34 35 36 37 |
# File 'lib/httpx/altsvc.rb', line 30 def lookup(origin, ttl) return [] unless @altsvcs.key?(origin) @altsvcs[origin] = @altsvcs[origin].select do |entry| !entry.key?("TTL") || entry["TTL"] > ttl end @altsvcs[origin].reject { |entry| entry["noop"] } end |
.parse(altsvc) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/httpx/altsvc.rb', line 68 def parse(altsvc) return enum_for(__method__, altsvc) unless block_given? scanner = StringScanner.new(altsvc) until scanner.eos? alt_service = scanner.scan(/[^=]+=("[^"]+"|[^;,]+)/) alt_params = [] loop do alt_param = scanner.scan(/[^=]+=("[^"]+"|[^;,]+)/) alt_params << alt_param.strip if alt_param scanner.skip(/;/) break if scanner.eos? || scanner.scan(/ *, */) end alt_params = Hash[alt_params.map { |field| field.split("=") }] alt_proto, = alt_service.split("=") alt_origin = parse_altsvc_origin(alt_proto, ) return unless alt_origin yield(alt_origin, alt_params.merge("proto" => alt_proto)) end end |
.parse_altsvc_scheme(alt_proto) ⇒ Object
92 93 94 95 96 97 98 99 |
# File 'lib/httpx/altsvc.rb', line 92 def parse_altsvc_scheme(alt_proto) case alt_proto when "h2c" "http" when "h2" "https" end end |
Instance Method Details
#parse_altsvc_origin(alt_proto, alt_origin) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/httpx/altsvc.rb', line 103 def parse_altsvc_origin(alt_proto, alt_origin) alt_scheme = parse_altsvc_scheme(alt_proto) or return alt_origin = alt_origin[1..-2] if alt_origin.start_with?("\"") && alt_origin.end_with?("\"") if alt_origin.start_with?(":") alt_origin = "#{alt_scheme}://dummy#{alt_origin}" uri = URI.parse(alt_origin) uri.host = nil uri else URI.parse("#{alt_scheme}://#{alt_origin}") end end |