Merge branch 'proxy-fixes' into 'master'

Proxy fixes

See merge request honeyryderchuck/httpx!26
This commit is contained in:
HoneyryderChuck 2018-06-29 17:15:25 +00:00
commit a95cfe94c1
9 changed files with 43 additions and 27 deletions

View File

@ -29,7 +29,7 @@ Naming/FileName:
- Gemfile
- Rakefile
Lint/EndAlignment:
Layout/EndAlignment:
EnforcedStyleAlignWith: variable
Lint/HandleExceptions:

View File

@ -1,9 +1,9 @@
SimpleCov.start do
command_name "Minitest"
add_filter "/.bundle/"
add_filter "/test/"
command_name "Minitest"
add_filter "/.bundle/"
add_filter "/test/"
add_filter "/lib/httpx/extensions.rb"
add_filter "/lib/httpx/loggable.rb"
coverage_dir "www/coverage"
minimum_coverage 85
minimum_coverage 85
end

View File

@ -7,7 +7,7 @@ gemspec
gem "hanna-nouveau", require: false
gem "rake", "~> 12.3"
gem "rubocop", "~> 0.54.0", require: false
gem "rubocop", "~> 0.55.0", require: false
gem "simplecov", require: false
platform :mri do

View File

@ -154,7 +154,9 @@ module HTTPX
loop do
siz = @io.read(wsize, @read_buffer)
unless siz
emit(:close)
ex = EOFError.new("descriptor closed")
ex.set_backtrace(caller)
on_error(ex)
return
end
return if siz.zero?
@ -168,7 +170,9 @@ module HTTPX
return if @write_buffer.empty?
siz = @io.write(@write_buffer)
unless siz
emit(:close)
ex = EOFError.new("descriptor closed")
ex.set_backtrace(caller)
on_error(ex)
return
end
log { "WRITE: #{siz} bytes..." }
@ -247,7 +251,7 @@ module HTTPX
end
def handle_error(e)
parser.handle_error(e)
parser.handle_error(e) if parser.respond_to?(:handle_error)
response = ErrorResponse.new(e, @options)
@pending.each do |request, _|
emit(:response, request, response)

View File

@ -24,7 +24,10 @@ module HTTPX
end
monitor.interests = channel.interests
end
rescue TimeoutError => ex
rescue TimeoutError,
Errno::ECONNRESET,
Errno::ECONNABORTED,
Errno::EPIPE => ex
@channels.each do |ch|
ch.emit(:error, ex)
end

View File

@ -71,7 +71,7 @@ module HTTPX
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) && request.state == :idle) ||
(((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..." }
@ -132,6 +132,13 @@ module HTTPX
consume
end
end
def reset
@state = :open
transition(:closing)
transition(:closed)
emit(:close)
end
end
class ProxySSL < SSL

View File

@ -30,11 +30,7 @@ module HTTPX
transition(:connected)
throw(:called)
else
response = ErrorResponse.new(Error.new("socks error: #{status}"), @options)
until @pending.empty?
req, _ = @pending.shift
emit(:response, req, response)
end
on_socks_error("socks error: #{status}")
end
end
@ -56,6 +52,13 @@ module HTTPX
log(level: 1, label: "SOCKS4: ") { "#{nextstate}: #{@write_buffer.to_s.inspect}" } unless nextstate == :open
super
end
def on_socks_error(message)
ex = Error.new(message)
ex.set_backtrace(caller)
on_error(ex)
throw(:called)
end
end
Parameters.register("socks4", Socks4ProxyChannel)
Parameters.register("socks4a", Socks4ProxyChannel)

View File

@ -45,7 +45,7 @@ module HTTPX
transition(:authenticating)
return
when NONE
on_error_response("no supported authorization methods")
on_socks_error("no supported authorization methods")
else
transition(:negotiating)
end
@ -53,11 +53,11 @@ module HTTPX
version, status = packet.unpack("CC")
check_version(version)
return transition(:negotiating) if status == SUCCESS
on_error_response("socks authentication error: #{status}")
on_socks_error("socks authentication error: #{status}")
when :negotiating
version, reply, = packet.unpack("CC")
check_version(version)
return on_error_response("socks5 negotiation error: #{reply}") unless reply == SUCCESS
on_socks_error("socks5 negotiation error: #{reply}") unless reply == SUCCESS
req, _ = @pending.first
request_uri = req.uri
@io = ProxySSL.new(@io, request_uri, @options) if request_uri.scheme == "https"
@ -91,17 +91,17 @@ module HTTPX
end
def check_version(version)
raise Error, "invalid SOCKS version (#{version})" if version != 5
on_socks_error("invalid SOCKS version (#{version})") if version != 5
end
def on_error_response(error)
response = ErrorResponse.new(Error.new(error), @options)
until @pending.empty?
req, _ = @pending.shift
emit(:response, req, response)
end
def on_socks_error(message)
ex = Error.new(message)
ex.set_backtrace(caller)
on_error(ex)
throw(:called)
end
end
Parameters.register("socks5", Socks5ProxyChannel)
class SocksParser

View File

@ -222,7 +222,6 @@ module HTTPX
@error = error
@options = Options.new(options)
log { "#{error.class}: #{error}" }
log { caller.join("\n") }
end
def status