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