passed more of the channel discovery logic to the client; this allows for more more transparent IO plugins, and removes the last monkey-patch

This commit is contained in:
HoneyryderChuck 2018-01-03 09:51:25 +02:00
parent 2d79aa3673
commit c7cd490b73
3 changed files with 37 additions and 49 deletions

View File

@ -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

View File

@ -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)

View File

@ -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