find_proxy(env=ENV)
public
returns a proxy URI. The proxy URI is obtained from environment variables such as
http_proxy, ftp_proxy, no_proxy, etc. If there is no proper proxy, nil is
returned.
If the optional parameter, env, is specified, it is used instead
of ENV.
Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) are
examined too.
But http_proxy and HTTP_PROXY is treated specially under CGI environment. It’s because HTTP_PROXY may be set
by Proxy: header. So HTTP_PROXY is not used. http_proxy is not used too if
the variable is case insensitive. CGI_HTTP_PROXY can be used instead.
Show source
def find_proxy(env=ENV)
raise BadURIError, "relative URI: #{self}" if self.relative?
name = self.scheme.downcase + '_proxy'
proxy_uri = nil
if name == 'http_proxy' && env.include?('REQUEST_METHOD')
pairs = env.reject {|k, v| /\Ahttp_proxy\z/ !~ k }
case pairs.length
when 0
proxy_uri = nil
when 1
k, _ = pairs.shift
if k == 'http_proxy' && env[k.upcase] == nil
proxy_uri = env[name]
else
proxy_uri = nil
end
else
proxy_uri = env.to_hash[name]
end
if !proxy_uri
proxy_uri = env["CGI_#{name.upcase}"]
end
elsif name == 'http_proxy'
unless proxy_uri = env[name]
if proxy_uri = env[name.upcase]
warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.', uplevel: 1
end
end
else
proxy_uri = env[name] || env[name.upcase]
end
if proxy_uri.nil? || proxy_uri.empty?
return nil
end
if self.hostname
begin
addr = IPSocket.getaddress(self.hostname)
return nil if /\A127\.|\A::1\z/ =~ addr
rescue SocketError
end
end
name = 'no_proxy'
if no_proxy = env[name] || env[name.upcase]
return nil unless URI::Generic.use_proxy?(self.hostname, addr, self.port, no_proxy)
end
URI.parse(proxy_uri)
end