Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions lib/uri/generic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1570,7 +1570,23 @@ def find_proxy(env=ENV)
def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc:
hostname = hostname.downcase
dothostname = ".#{hostname}"
no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) {|p_host, p_port|
no_proxy.split(/[,\s]+/).each {|entry|
next if entry.empty?
# Bracketed IPv6: [addr] or [addr]:port
if entry =~ /\A\[([^\]]+)\](?::(\d+))?\z/
p_port = $2 # read $2 before sub() clobbers global match variables
p_host = $1.sub(/%.*\z/, '') # strip zone ID (e.g. [::1%eth0] -> ::1)
# Bare IPv6: address contains more than one colon (e.g. 2001:db8::1 or 2001:db8::/32)
elsif entry.count(':') > 1
p_host = entry.sub(/%.*\z/, '') # strip zone ID (e.g. ::1%eth0 -> ::1)
p_port = nil
# IPv4 or hostname with optional port (trailing colon treated as no port)
elsif entry =~ /\A([^:]+)(?::(\d+)?)?\z/
p_host = $1
p_port = ($2 && !$2.empty?) ? $2 : nil
else
next
end
if !p_port || port == p_port.to_i
if p_host.start_with?('.')
return false if hostname.end_with?(p_host.downcase)
Expand All @@ -1581,7 +1597,6 @@ def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc:
begin
return false if IPAddr.new(p_host).include?(addr)
rescue IPAddr::InvalidAddressError
next
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next in the rescue IPAddr::InvalidAddressError clause was removed as it is redundant. Falling off the end of the block body advances to the next iteration identically to calling next explicitly. No behavioral change.

end
end
end
Expand Down
20 changes: 20 additions & 0 deletions test/uri/test_generic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,26 @@ def test_use_proxy_p
['127.0.0.1', '127.0.0.1', 80, '10.224.0.0/22', true],
['10.224.1.1', '10.224.1.1', 80, '10.224.1.1', false],
['10.224.1.1', '10.224.1.1', 80, '10.224.0.0/22', false],
# IPv6: bare address in no_proxy
['2001:db8::1', '2001:db8::1', 80, '2001:db8::1', false],
# IPv6: bracketed address in no_proxy
['2001:db8::1', '2001:db8::1', 80, '[2001:db8::1]', false],
# IPv6: bracketed address with matching port
['2001:db8::1', '2001:db8::1', 80, '[2001:db8::1]:80', false],
# IPv6: bracketed address with non-matching port
['2001:db8::1', '2001:db8::1', 80, '[2001:db8::1]:443', true],
# IPv6: CIDR notation
['2001:db8::1', '2001:db8::1', 80, '2001:db8::/32', false],
# IPv6: address not in no_proxy
['2001:db8::2', '2001:db8::2', 80, '2001:db8::1', true],
# IPv6: multiple entries including IPv6
['2001:db8::1', '2001:db8::1', 80, 'example.com,2001:db8::1', false],
# IPv6: zone ID stripped before matching (::1%eth0 should match ::1)
['::1', '::1', 80, '::1%eth0', false],
# IPv6: zone ID stripped from bracketed form too ([::1%eth0]:80 should match ::1 on port 80)
['::1', '::1', 80, '[::1%eth0]:80', false],
# Trailing colon treated as no-port (regression guard)
['example.com', nil, 80, 'example.com:', false],
].each do |hostname, addr, port, no_proxy, expected|
assert_equal expected, URI::Generic.use_proxy?(hostname, addr, port, no_proxy),
"use_proxy?('#{hostname}', '#{addr}', #{port}, '#{no_proxy}')"
Expand Down