lib/httpx/client.rb in httpx-0.2.1 vs lib/httpx/client.rb in httpx-0.3.0

- old
+ new

@@ -45,11 +45,10 @@ end def on_promise(_, stream) log(level: 2, label: "#{stream.id}: ") { "refusing stream!" } stream.refuse - # TODO: policy for handling promises end def fetch_response(request) @responses.delete(request) end @@ -64,15 +63,47 @@ channel.on(:promise, &method(:on_promise)) channel.on(:uncoalesce) do |uncoalesced_uri| other_channel = build_channel(uncoalesced_uri, options) channel.unmerge(other_channel) end + channel.on(:altsvc) do |alt_origin, origin, alt_params| + build_altsvc_channel(channel, alt_origin, origin, alt_params, options) + end end def build_channel(uri, options) channel = @connection.build_channel(uri, **options) set_channel_callbacks(channel, options) channel + end + + def build_altsvc_channel(existing_channel, alt_origin, origin, alt_params, options) + altsvc = AltSvc.cached_altsvc_set(origin, alt_params.merge("origin" => alt_origin)) + + # altsvc already exists, somehow it wasn't advertised, probably noop + return unless altsvc + + channel = @connection.find_channel(alt_origin) || build_channel(alt_origin, options) + # advertised altsvc is the same origin being used, ignore + return if channel == existing_channel + + log(level: 1) { "#{origin} alt-svc: #{alt_origin}" } + + # get uninitialized requests + # incidentally, all requests will be re-routed to the first + # advertised alt-svc, which incidentally follows the spec. + existing_channel.purge_pending do |request, args| + is_idle = request.origin == origin && + request.state == :idle && + !request.headers.key?("alt-used") + if is_idle + log(level: 1) { "#{origin} alt-svc: sending #{request.uri} to #{alt_origin}" } + channel.send(request, args) + end + is_idle + end + rescue UnsupportedSchemeError + altsvc["noop"] = true end def __build_reqs(*args, **options) requests = case args.size when 1