Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

fix for issue 195 https://github.com/rubygems/rubygems/issues/195 (honor NO_PROXY env) #199

Closed
wants to merge 2 commits into from

5 participants

@svoynow

I'm not entirely sure that I've gotten the hostname matching done exactly as everybody would want it, but it should work for most purposes.

@svoynow

A little more explanation to hopefully increase the chances of this being pulled.
The gem command reference (http://docs.rubygems.org/read/chapter/13#page51) says:

Command-line applications typically set an environment variable to specify an HTTP proxy through which to access the Internet. gem respects the following variables:

http_proxy
HTTP_PROXY
NO_PROXY

I've added a couple of tests that fail involving setting NO_PROXY in the environment which fail with the current rubygems, but which pass with my changes.

@drbrain drbrain was assigned
@darrin-wortlehock

I can confirm that this patch solves the issue for me, specifically the situation where I want to use a local gem server behind a firewall (therefore requiring no_proxy) to install private gems which have dependencies on public gems hosted on rubygems.org

@j3p0uk

The following is needed to ensure the tests pass if a no_proxy environment variable is in existence outside of the test environment:

jonp@ubuntu-vmware:~/git/rubygems$ git diff
diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb
index 9222ba8..de472bb 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -85,6 +85,8 @@ gems:
ENV.delete 'HTTP_PROXY_USER'
ENV.delete 'http_proxy_pass'
ENV.delete 'HTTP_PROXY_PASS'

  • ENV.delete 'no_proxy'
  • ENV.delete 'NO_PROXY'

    base_server_uri = "http://localhost:#{SERVER_PORT}"
    @proxy_uri = "http://localhost:#{PROXY_PORT}"

Good catch. I've checked this in.
68f1109

@drbrain drbrain referenced this pull request from a commit
@drbrain drbrain Use http_proxy to avoid warnings.
Stop restoring already empty http proxy ENV variables

Finished #199
54fc13b
@drbrain
Owner

Committed, thanks!

@drbrain drbrain closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 27, 2011
  1. honor no_proxy env variable

    Vounow authored
Commits on Apr 18, 2012
  1. unset no_proxy environment variable before running tests, in case it'…

    Vounow authored
    …s been set from outside.
This page is out of date. Refresh to see the latest.
View
24 lib/rubygems/remote_fetcher.rb
@@ -77,6 +77,7 @@ def initialize(proxy = nil)
else URI.parse(proxy)
end
@user_agent = user_agent
+ @env_no_proxy = get_no_proxy_from_env
end
##
@@ -239,7 +240,6 @@ def fetch_path(uri, mtime = nil, head = false)
end
data = send "fetch_#{uri.scheme}", uri, mtime, head
-
if data and !head and uri.to_s =~ /gz$/
begin
data = Gem.gunzip data
@@ -330,12 +330,32 @@ def get_proxy_from_env
end
##
+ # Returns list of no_proxy entries (if any) from the environment
+
+ def get_no_proxy_from_env
+ env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
+
+ return [] if env_no_proxy.nil? or env_no_proxy.empty?
+
+ env_no_proxy_list = env_no_proxy.split(/\s*,\s*/)
+ end
+
+ ##
# Normalize the URI by adding "http://" if it is missing.
def normalize_uri(uri)
(uri =~ /^(https?|ftp|file):/) ? uri : "http://#{uri}"
end
+ def no_proxy?(host)
+ host = host.downcase
+ @env_no_proxy.each do |pattern|
+ pattern = pattern.downcase
+ return true if host[-pattern.length, pattern.length ] == pattern
+ end
+ return false
+ end
+
##
# Creates or an HTTP connection based on +uri+, or retrieves an existing
# connection, using a proxy if needed.
@@ -343,7 +363,7 @@ def normalize_uri(uri)
def connection_for(uri)
net_http_args = [uri.host, uri.port]
- if @proxy_uri then
+ if @proxy_uri && !no_proxy?(uri.host) then
net_http_args += [
@proxy_uri.host,
@proxy_uri.port,
View
46 test/rubygems/test_gem_remote_fetcher.rb
@@ -84,6 +84,8 @@ def setup
ENV.delete 'HTTP_PROXY_USER'
ENV.delete 'http_proxy_pass'
ENV.delete 'HTTP_PROXY_PASS'
+ ENV.delete 'no_proxy'
+ ENV.delete 'NO_PROXY'
base_server_uri = "http://localhost:#{SERVER_PORT}"
@proxy_uri = "http://localhost:#{PROXY_PORT}"
@@ -572,6 +574,50 @@ def test_implicit_proxy_no_env
end
end
+ def test_observe_no_proxy_env_single_host
+ orig_env_HTTP_PROXY = ENV['HTTP_PROXY']
+
+ orig_env_NO_PROXY = ENV["NO_PROXY"]
+ orig_env_no_proxy = ENV["no_proxy"]
+
+ use_ui @ui do
+ ENV["HTTP_PROXY"] = @proxy_uri
+ ENV["NO_PROXY"] = "#{URI::parse(@server_uri).host}"
+ fetcher = Gem::RemoteFetcher.new nil
+ assert_data_from_server fetcher.fetch_path(@server_uri)
+ end
+
+ ensure
+ orig_env_HTTP_PROXY.nil? ? ENV.delete('HTTP_PROXY') :
+ ENV['HTTP_PROXY'] = orig_env_HTTP_PROXY
+ orig_env_NO_PROXY.nil? ? ENV.delete('NO_PROXY') :
+ ENV['NO_PROXY'] = orig_env_NO_PROXY
+ orig_env_no_proxy.nil? ? ENV.delete('no_proxy') :
+ ENV['no_proxy'] = orig_env_no_proxy
+ end
+
+ def test_observe_no_proxy_env_list
+ orig_env_HTTP_PROXY = ENV['HTTP_PROXY']
+
+ orig_env_NO_PROXY = ENV["NO_PROXY"]
+ orig_env_no_proxy = ENV["no_proxy"]
+
+ use_ui @ui do
+ ENV["HTTP_PROXY"] = @proxy_uri
+ ENV["NO_PROXY"] = "fakeurl.com, #{URI::parse(@server_uri).host}"
+ fetcher = Gem::RemoteFetcher.new nil
+ assert_data_from_server fetcher.fetch_path(@server_uri)
+ end
+
+ ensure
+ orig_env_HTTP_PROXY.nil? ? ENV.delete('HTTP_PROXY') :
+ ENV['HTTP_PROXY'] = orig_env_HTTP_PROXY
+ orig_env_NO_PROXY.nil? ? ENV.delete('NO_PROXY') :
+ ENV['NO_PROXY'] = orig_env_NO_PROXY
+ orig_env_no_proxy.nil? ? ENV.delete('no_proxy') :
+ ENV['no_proxy'] = orig_env_no_proxy
+ end
+
def test_fetch_http
fetcher = Gem::RemoteFetcher.new nil
url = 'http://gems.example.com/redirect'
Something went wrong with that request. Please try again.