diff --git a/lib/bundler/fetcher/connection_pools.rb b/lib/bundler/fetcher/connection_pools.rb index a2e72af74b80..09514b610cb3 100644 --- a/lib/bundler/fetcher/connection_pools.rb +++ b/lib/bundler/fetcher/connection_pools.rb @@ -72,6 +72,9 @@ def proxy_for(uri) env_proxy_for(uri) end return unless proxy + # NO_PROXY="*" bypasses the proxy for every host, which + # Gem::URI::Generic.use_proxy? does not understand. + return if no_proxy_env.strip == "*" return unless Gem::URI::Generic.use_proxy?(uri.hostname, nil, uri.port, no_proxy_env) proxy end @@ -90,6 +93,10 @@ def build_connection(uri, proxy_uri) # :nodoc: configure_ssl(connection) if uri.scheme == "https" connection.open_timeout = @timeout connection.read_timeout = @timeout + # Stale connections are already resent by Gem::Request#perform_request, + # and Bundler::Retry retries whole requests, so the Gem::Net::HTTP + # level retry would only multiply the time spent on a timing out host. + connection.max_retries = 0 connection.start connection end diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index 8cf56c9a1306..88f7f67b4bcc 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -179,7 +179,7 @@ Cooldown filtering depends on the gem server providing a per\-version \fBcreated .IP "\(bu" 4 \fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR): The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\. .IP "\(bu" 4 -\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\. +\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests, applied to each request individually\. A network operation retried by Bundler may wait a multiple of this value in total\. Defaults to \fB10\fR\. .IP "\(bu" 4 \fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\. .IP "\(bu" 4 @@ -330,6 +330,12 @@ Any \fB\.\fR characters in a host name are mapped to a double underscore (\fB__\ .IP "" 0 .P This means that if you have a gem server named \fBmy\.gem\-host\.com\fR, you'll need to use the \fBBUNDLE_MY__GEM___HOST__COM\fR variable to configure credentials for it through ENV\. +.SH "PROXY SUPPORT" +Bundler reads the proxy for a gem source from the \fB:http_proxy\fR key in the RubyGems configuration file (\fB~/\.gemrc\fR), falling back to the environment\. For an \fBhttps\fR source, \fBhttps_proxy\fR (or \fBHTTPS_PROXY\fR) takes precedence over \fBhttp_proxy\fR (or \fBHTTP_PROXY\fR), which is only used when no https\-specific proxy is set\. Proxy credentials that are not embedded in the proxy URL are read from \fBHTTP_PROXY_USER\fR and \fBHTTP_PROXY_PASS\fR, or from \fBHTTPS_PROXY_USER\fR and \fBHTTPS_PROXY_PASS\fR when the https proxy is used\. +.P +Setting \fB:http_proxy: :no_proxy\fR in the RubyGems configuration file disables proxies entirely, including any proxy environment variables\. To keep using a proxy from the environment, remove that line\. To configure a proxy in the file, replace \fB:no_proxy\fR with an explicit proxy URL\. +.P +The \fBNO_PROXY\fR (or \fBno_proxy\fR) environment variable lists hosts that are reached directly, bypassing the proxy\. An entry matches the host itself and its subdomains, so \fBNO_PROXY=example\.com\fR bypasses both \fBexample\.com\fR and \fBsub\.example\.com\fR, but not \fBmyexample\.com\fR\. An entry starting with a dot matches only subdomains\. A value of \fB*\fR bypasses the proxy for every host\. .SH "CONFIGURE BUNDLER DIRECTORIES" Bundler's home, cache and plugin directories and config file can be configured through environment variables\. The default location for Bundler's home directory is \fB~/\.bundle\fR, which all directories inherit from by default\. The following outlines the available environment variables and their default values .IP "" 4 diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index 27fd5e040b5a..6e9fedd109af 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -293,7 +293,9 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). * `system_bindir` (`BUNDLE_SYSTEM_BINDIR`): The location where RubyGems installs binstubs. Defaults to `Gem.bindir`. * `timeout` (`BUNDLE_TIMEOUT`): - The seconds allowed before timing out for network requests. Defaults to `10`. + The seconds allowed before timing out for network requests, applied to each + request individually. A network operation retried by Bundler may wait a + multiple of this value in total. Defaults to `10`. * `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`): Require passing `--all` to `bundle update` when everything should be updated, and disallow passing no options to `bundle update`. @@ -452,6 +454,27 @@ This means that if you have a gem server named `my.gem-host.com`, you'll need to use the `BUNDLE_MY__GEM___HOST__COM` variable to configure credentials for it through ENV. +## PROXY SUPPORT + +Bundler reads the proxy for a gem source from the `:http_proxy` key in the +RubyGems configuration file (`~/.gemrc`), falling back to the environment. +For an `https` source, `https_proxy` (or `HTTPS_PROXY`) takes precedence over +`http_proxy` (or `HTTP_PROXY`), which is only used when no https-specific +proxy is set. Proxy credentials that are not embedded in the proxy URL are +read from `HTTP_PROXY_USER` and `HTTP_PROXY_PASS`, or from `HTTPS_PROXY_USER` +and `HTTPS_PROXY_PASS` when the https proxy is used. + +Setting `:http_proxy: :no_proxy` in the RubyGems configuration file disables +proxies entirely, including any proxy environment variables. To keep using a +proxy from the environment, remove that line. To configure a proxy in the +file, replace `:no_proxy` with an explicit proxy URL. + +The `NO_PROXY` (or `no_proxy`) environment variable lists hosts that are +reached directly, bypassing the proxy. An entry matches the host itself and +its subdomains, so `NO_PROXY=example.com` bypasses both `example.com` and +`sub.example.com`, but not `myexample.com`. An entry starting with a dot +matches only subdomains. A value of `*` bypasses the proxy for every host. + ## CONFIGURE BUNDLER DIRECTORIES Bundler's home, cache and plugin directories and config file can be configured diff --git a/spec/bundler/fetcher_spec.rb b/spec/bundler/fetcher_spec.rb index 87a49ea6fc78..8bac5548b924 100644 --- a/spec/bundler/fetcher_spec.rb +++ b/spec/bundler/fetcher_spec.rb @@ -82,6 +82,11 @@ expect(fetcher.http_proxy).to be_nil end end + it "bypass proxy for every host when no_proxy is '*'" do + with_env_vars("HTTP_PROXY" => "http://proxy-example5.com", "NO_PROXY" => "*") do + expect(fetcher.http_proxy).to be_nil + end + end end def configured_connection