lib/httpx/plugins/proxy.rb in httpx-0.0.5 vs lib/httpx/plugins/proxy.rb in httpx-0.1.0
- old
+ new
@@ -32,14 +32,19 @@
end
private
def proxy_params(uri)
- return @options.proxy if @options.proxy
- uri = URI(uri).find_proxy
- return unless uri
- { uri: uri }
+ @_proxy_uris ||= begin
+ uris = @options.proxy ? Array(@options.proxy[:uri]) : []
+ if uris.empty?
+ uri = URI(uri).find_proxy
+ uris << uri if uri
+ end
+ uris
+ end
+ @options.proxy.merge(uri: @_proxy_uris.shift) unless @_proxy_uris.empty?
end
def find_channel(request, **options)
uri = URI(request.uri)
proxy = proxy_params(uri)
@@ -53,16 +58,31 @@
def build_proxy_channel(proxy, **options)
parameters = Parameters.new(**proxy)
uri = parameters.uri
log { "proxy: #{uri}" }
- io = TCP.new(uri.host, uri.port, @options)
+ io = TCP.new(uri, @options)
proxy_type = Parameters.registry(parameters.uri.scheme)
channel = proxy_type.new(io, parameters, @options.merge(options), &method(:on_response))
@connection.__send__(:register_channel, channel)
channel
end
+
+ def fetch_response(request)
+ response = super
+ if response.is_a?(ErrorResponse) &&
+ # either it was a timeout error connecting, or it was a proxy error
+ (((response.error.is_a?(TimeoutError) || response.error.is_a?(IOError)) && request.state == :idle) ||
+ response.error.is_a?(Error)) &&
+ !@_proxy_uris.empty?
+ log { "failed connecting to proxy, trying next..." }
+ channel = find_channel(request)
+ channel.send(request)
+ return
+ end
+ response
+ end
end
module OptionsMethods
def self.included(klass)
super
@@ -89,10 +109,14 @@
def match?(*)
true
end
+ def send(request, **args)
+ @pending << [request, args]
+ end
+
def to_io
case @state
when :idle
transition(:connecting)
when :connected
@@ -106,15 +130,22 @@
case @state
when :connecting
consume
end
end
+
+ def reset
+ @state = :open
+ transition(:closing)
+ transition(:closed)
+ emit(:close)
+ end
end
class ProxySSL < SSL
def initialize(tcp, request_uri, options)
@io = tcp.to_io
- super(tcp.ip, tcp.port, options)
+ super(tcp, options)
@hostname = request_uri.host
@state = :connected
end
end
end