Project

General

Profile

Feature #6546 » net.http.proxy_from_env.2.patch

drbrain (Eric Hodel), 06/12/2012 09:17 AM

View differences:

lib/net/http.rb (working copy)
# === Proxies
#
# Net::HTTP::Proxy has the same methods as Net::HTTP but its instances always
# connect via the proxy instead of directly to the given host.
# connect via the proxy instead of directly to the given host. Net::HTTP
# will automatically create a proxy from the +HTTP_PROXY+ environment
# variable if it is present. To disable use of +HTTP_PROXY+, pass +nil+ for
# the proxy address. Net::HTTP will be returned when no proxy is configured
# so there is no need for conditional code.
#
# You may also create a custom proxy:
#
# proxy_addr = 'your.proxy.host'
# proxy_port = 8080
......
# # always connect to your.proxy.addr:8080
# }
#
# Net::HTTP::Proxy returns a Net::HTTP instance when proxy_addr is nil so
# there is no need for conditional code.
#
# See Net::HTTP::Proxy for further details and examples such as proxies that
# require a username and password.
#
......
# HTTP session.
# The +address+ should be a DNS hostname or IP address.
# If +p_addr+ is given, creates a Net::HTTP object with proxy support.
def HTTP.new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil)
Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)
end
......
# Creates an HTTP proxy class which behaves like Net::HTTP, but
# performs all access via the specified proxy.
#
# The arguments are the DNS name or IP address of the proxy host,
# the port to use to access the proxy, and a username and password
# if authorization is required to use the proxy.
# If no arguments are given, the proxy host and port are taken from the
# +HTTP_PROXY+ environment variable (or its lowercase equivalent) if
# present. If the proxy requires authentication you must supply it by
# hand.
#
# If you are connecting to a custom proxy, the arguments are the DNS name
# or IP address of the proxy host, the port to use to access the proxy,
# and a username and password if authorization is required to use the
# proxy.
#
# If +p_addr+ is nil, this method returns self (a Net::HTTP object). If
# +p_addr+ is +:ENV+ the proxy is constructed from +HTTP_PROXY+ and +p_addr+
# is determined automatically. You may use +:ENV+ with +p_user+ and
# +p_pass+ to provide authentication for +HTTP_PROXY+.
#
# You can replace any use of the Net::HTTP class with use of the
# proxy class created.
#
# If +p_addr+ is nil, this method returns self (a Net::HTTP object).
#
# # Example
# proxy_class = Net::HTTP::Proxy('proxy.example.com', 8080)
#
......
# # and password
# }
#
# Note that net/http does not use the HTTP_PROXY environment variable.
# If you want to use a proxy, you must set it explicitly.
#
def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil)
def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil)
return self unless p_addr
delta = ProxyDelta
proxyclass = Class.new(self)
proxyclass.module_eval {
include delta
if p_addr == :ENV then
env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
return self unless env_proxy
env_proxy =~ /:([^\]]+)\z/ # handle IPv6 address like [::1]:8000
p_addr = $` || env_proxy
p_port = $1.to_i if $1
end
Class.new(self) {
include Net::HTTP::ProxyDelta
# with proxy
@is_proxy_class = true
@proxy_address = p_addr
......
@proxy_user = p_user
@proxy_pass = p_pass
}
proxyclass
end
class << HTTP
test/net/http/test_http.rb (working copy)
require 'stringio'
require_relative 'utils'
class TestNetHTTP < Test::Unit::TestCase
def test_class_Proxy
no_proxy_class = Net::HTTP.Proxy nil
assert_equal Net::HTTP, no_proxy_class
proxy_class = Net::HTTP.Proxy 'proxy.example', 8000, 'user', 'pass'
refute_equal Net::HTTP, proxy_class
assert_operator proxy_class, :<, Net::HTTP
assert_equal 'proxy.example', proxy_class.proxy_address
assert_equal 8000, proxy_class.proxy_port
assert_equal 'user', proxy_class.proxy_user
assert_equal 'pass', proxy_class.proxy_pass
end
def test_class_Proxy_from_ENV
clean_http_proxy_env do
ENV['HTTP_PROXY'] = 'proxy.example:8000'
# These are ignored on purpose. See Bug 4388 and Feature 6546
ENV['HTTP_PROXY_USER'] = 'user'
ENV['HTTP_PROXY_PASS'] = 'pass'
proxy_class = Net::HTTP.Proxy :ENV
refute_equal Net::HTTP, proxy_class
assert_operator proxy_class, :<, Net::HTTP
assert_equal 'proxy.example', proxy_class.proxy_address
assert_equal 8000, proxy_class.proxy_port
assert_nil proxy_class.proxy_user
assert_nil proxy_class.proxy_pass
end
end
def test_class_Proxy_from_ENV_ipv6
clean_http_proxy_env do
ENV['HTTP_PROXY'] = '[::1]:8000'
proxy_class = Net::HTTP.Proxy :ENV
refute_equal Net::HTTP, proxy_class
assert_operator proxy_class, :<, Net::HTTP
assert_equal '[::1]', proxy_class.proxy_address
assert_equal 8000, proxy_class.proxy_port
assert_nil proxy_class.proxy_user
assert_nil proxy_class.proxy_pass
end
end
def test_class_Proxy_from_ENV_lowercase
clean_http_proxy_env do
ENV['http_proxy'] = 'proxy.example:8000'
# These are ignored on purpose. See Bug 4388 and Feature 6546
ENV['http_proxy_user'] = 'user'
ENV['http_proxy_pass'] = 'pass'
proxy_class = Net::HTTP.Proxy :ENV
refute_equal Net::HTTP, proxy_class
assert_operator proxy_class, :<, Net::HTTP
assert_equal 'proxy.example', proxy_class.proxy_address
assert_equal 8000, proxy_class.proxy_port
assert_nil proxy_class.proxy_user
assert_nil proxy_class.proxy_pass
end
end
def test_class_Proxy_from_ENV_none
clean_http_proxy_env do
no_proxy_class = Net::HTTP.Proxy :ENV
assert_equal Net::HTTP, no_proxy_class
end
end
def test_class_Proxy_from_ENV_no_port
clean_http_proxy_env do
ENV['HTTP_PROXY'] = 'proxy.example'
proxy_class = Net::HTTP.Proxy :ENV
refute_equal Net::HTTP, proxy_class
assert_operator proxy_class, :<, Net::HTTP
assert_equal 'proxy.example', proxy_class.proxy_address
assert_equal 80, proxy_class.proxy_port
assert_nil proxy_class.proxy_user
assert_nil proxy_class.proxy_pass
end
end
def clean_http_proxy_env
orig = {
'HTTP_PROXY' => ENV['HTTP_PROXY'],
'http_proxy' => ENV['HTTP_PROXY'],
'HTTP_PROXY_USER' => ENV['HTTP_PROXY_USER'],
'http_proxy_user' => ENV['http_proxy_user'],
'HTTP_PROXY_PASS' => ENV['HTTP_PROXY_PASS'],
'http_proxy_pass' => ENV['http_proxy_pass'],
}
orig.each_key do |key|
ENV.delete key
end
yield
ensure
orig.each do |key, value|
ENV[key] = value
end
end
end
module TestNetHTTP_version_1_1_methods
def test_s_get
(2-2/4)