From c7cd490b73ba1d0e96b7908bafdef5e1ec986a10 Mon Sep 17 00:00:00 2001 From: HoneyryderChuck Date: Wed, 3 Jan 2018 09:51:25 +0200 Subject: [PATCH] passed more of the channel discovery logic to the client; this allows for more more transparent IO plugins, and removes the last monkey-patch --- lib/httpx/client.rb | 11 ++++++++- lib/httpx/connection.rb | 29 ++++++++---------------- lib/httpx/plugins/proxy.rb | 46 +++++++++++++++----------------------- 3 files changed, 37 insertions(+), 49 deletions(-) diff --git a/lib/httpx/client.rb b/lib/httpx/client.rb index 0435361e..7a7ba421 100644 --- a/lib/httpx/client.rb +++ b/lib/httpx/client.rb @@ -33,6 +33,12 @@ module HTTPX private + def find_channel(request) + uri = URI(request.uri) + @connection.find_channel(uri) || + @connection.build_channel(uri) + end + def __build_reqs(*args, **options) case args.size when 1 @@ -56,7 +62,10 @@ module HTTPX end def __send_reqs(*requests) - requests.each { |request| @connection << request } + requests.each do |request| + channel = find_channel(request) + channel.send(request) + end responses = [] # guarantee ordered responses diff --git a/lib/httpx/connection.rb b/lib/httpx/connection.rb index a7cb177e..0e7888cb 100644 --- a/lib/httpx/connection.rb +++ b/lib/httpx/connection.rb @@ -17,14 +17,6 @@ module HTTPX !@channels.empty? end - def send(request, **args) - channel = bind(request.uri) - raise Error, "no channel available" unless channel - - channel.send(request, **args) - end - alias :<< :send - def next_tick(timeout: @timeout.timeout) @selector.select(timeout) do |monitor| if task = monitor.value @@ -56,29 +48,26 @@ module HTTPX response end - private - - def on_response(request, response) - @responses[request] = response + def build_channel(uri) + channel = Channel.by(uri, @options, &method(:on_response)) + register_channel(channel) + channel end # opens a channel to the IP reachable through +uri+. # Many hostnames are reachable through the same IP, so we try to # maximize pipelining by opening as few channels as possible. # - def bind(uri) - uri = URI(uri) + def find_channel(uri) return @channels.find do |channel| channel.match?(uri) - end || begin - channel = build_channel(uri) - register_channel(channel) - channel end end - def build_channel(uri) - Channel.by(uri, @options, &method(:on_response)) + private + + def on_response(request, response) + @responses[request] = response end def register_channel(channel) diff --git a/lib/httpx/plugins/proxy.rb b/lib/httpx/plugins/proxy.rb index c67fb980..8da9767d 100644 --- a/lib/httpx/plugins/proxy.rb +++ b/lib/httpx/plugins/proxy.rb @@ -5,7 +5,7 @@ require "forwardable" module HTTPX module Plugins module Proxy - def self.load_dependencies(*) + def self.configure(*) require "httpx/plugins/proxy/http" require "httpx/plugins/proxy/socks" end @@ -31,49 +31,39 @@ module HTTPX end end - module ConnectionMethods - def bind(uri) - proxy = proxy_params(uri) - return super unless proxy - return @channels.find do |channel| - channel.match?(uri) - end || begin - channel = build_proxy_channel(proxy) - register_channel(channel) - channel - end + module InstanceMethods + def with_proxy(*args) + branch(default_options.with_proxy(*args)) end private - + def proxy_params(uri) - return @options.proxy if @options.proxy + return @default_options.proxy if @default_options.proxy uri = URI(uri).find_proxy return unless uri { uri: uri } end + def find_channel(request) + uri = URI(request.uri) + proxy = proxy_params(uri) + return super unless proxy + @connection.find_channel(proxy) || + build_proxy_channel(proxy) + end + def build_proxy_channel(proxy) parameters = Parameters.new(**proxy) uri = parameters.uri - io = TCP.new(uri.host, uri.port, @options) + io = TCP.new(uri.host, uri.port, @default_options) proxy_type = Parameters.registry(parameters.type) - proxy_type.new(io, parameters, @options, &method(:on_response)) + channel = proxy_type.new(io, parameters, @default_options, &@connection.method(:on_response)) + @connection.__send__(:register_channel, channel) + channel end end - module InstanceMethods - def initialize(*) - super - @connection.extend(ConnectionMethods) - end - - def with_proxy(*args) - branch(default_options.with_proxy(*args)) - end - - end - module OptionsMethods def self.included(klass) super