diff --git a/doc/03-cli.md b/doc/03-cli.md index d7d1fd136..bd05c04c2 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -1232,20 +1232,12 @@ environment variable if you use Vagrant or VirtualBox and experience issues with being found during installation even though they should be present. ### http_proxy or HTTP_PROXY +### HTTP_PROXY_REQUEST_FULLURI +### HTTPS_PROXY_REQUEST_FULLURI +### no_proxy or NO_PROXY -If you are using Composer from behind an HTTP proxy, you can use the standard -`http_proxy` or `HTTP_PROXY` env vars. Set it to the URL of your proxy. -Many operating systems already set this variable for you. - -Using `http_proxy` (lowercased) or even defining both might be preferable since -some tools like git or curl will only use the lower-cased `http_proxy` version. -Alternatively you can also define the git proxy using -`git config --global http.proxy `. - -If you are using Composer in a non-CLI context (i.e. integration into a CMS or -similar use case), and need to support proxies, please provide the `CGI_HTTP_PROXY` -environment variable instead. See [httpoxy.org](https://httpoxy.org/) for further -details. +See the [proxy documentation](faqs/how-to-use-composer-behind-a-proxy.md) for more details +on how to use proxy env vars. ### COMPOSER_AUDIT_ABANDONED @@ -1264,32 +1256,10 @@ in performance gains. Set to `4` or `6` to force IPv4 or IPv6 DNS resolution. This only works when the curl extension is used for downloads. -### HTTP_PROXY_REQUEST_FULLURI - -If you use a proxy, but it does not support the request_fulluri flag, then you -should set this env var to `false` or `0` to prevent Composer from setting the -request_fulluri option. - -### HTTPS_PROXY_REQUEST_FULLURI - -If you use a proxy, but it does not support the request_fulluri flag for HTTPS -requests, then you should set this env var to `false` or `0` to prevent Composer -from setting the request_fulluri option. - ### COMPOSER_SELF_UPDATE_TARGET If set, makes the self-update command write the new Composer phar file into that path instead of overwriting itself. Useful for updating Composer on a read-only filesystem. -### no_proxy or NO_PROXY - -If you are behind a proxy and would like to disable it for certain domains, you -can use the `no_proxy` or `NO_PROXY` env var. Set it to a comma separated list of -domains the proxy should *not* be used for. - -The env var accepts domains, IP addresses, and IP address blocks in CIDR -notation. You can restrict the filter to a particular port (e.g. `:80`). You -can also set it to `*` to ignore the proxy for all HTTP requests. - ### COMPOSER_DISABLE_NETWORK If set to `1`, disables network access (best effort). This can be used for debugging or diff --git a/doc/faqs/how-to-use-composer-behind-a-proxy.md b/doc/faqs/how-to-use-composer-behind-a-proxy.md new file mode 100644 index 000000000..58f82ebcb --- /dev/null +++ b/doc/faqs/how-to-use-composer-behind-a-proxy.md @@ -0,0 +1,118 @@ +# How to use Composer behind a proxy + +Composer, like many other tools, uses environment variables to control the use of a proxy server and +supports: + +- `http_proxy` - the proxy to use for HTTP requests +- `https_proxy` - the proxy to use for HTTPS requests +- `CGI_HTTP_PROXY` - the proxy to use for HTTP requests in a non-CLI context +- `no_proxy` - domains that do not require a proxy + +These named variables are a convention, rather than an official standard, and their evolution and +usage across different operating systems and tools is complex. Composer prefers the use of lowercase +names, but accepts uppercase names where appropriate. + +## Usage + +Composer requires specific environment variables for HTTP and HTTPS requests. For example: + +``` +http_proxy=http://proxy.com:80 +https_proxy=http://proxy.com:80 +``` + +Uppercase names can also be used. + +### Non-CLI usage + +Composer does not look for `http_proxy` or `HTTP_PROXY` in a non-CLI context. If you are running it +this way (i.e. integration into a CMS or similar use case) you must use `CGI_HTTP_PROXY` for HTTP +requests: + +``` +CGI_HTTP_PROXY=http://proxy.com:80 +https_proxy=http://proxy.com:80 + +# cgi_http_proxy can also be used +``` + +> **Note:** CGI_HTTP_PROXY was introduced by Perl in 2001 to prevent request header manipulation and +was popularized in 2016 when this vulnerability was widely reported: https://httpoxy.org + +## Syntax + +Use `scheme://host:port` as in the examples above. Although a missing scheme defaults to http and a +missing port defaults to 80/443 for http/https schemes, other tools might require these values. + +The host can be specified as an IP address using dotted quad notation for IPv4, or enclosed in +square brackets for IPv6. + +### Authorization + +Composer supports Basic authorization, using the `scheme://user:pass@host:port` syntax. Reserved url +characters in either the user name or password must be percent-encoded. For example: + +``` +user: me@company +pass: p@ssw$rd +proxy: http://proxy.com:80 + +# percent-encoded authorization +me%40company:p%40ssw%24rd + +scheme://me%40company:p%40ssw%24rd@proxy.com:80 +``` + +> **Note:** The user name and password components must be percent-encoded individually and then +combined with the colon separator. The user name cannot contain a colon (even if percent-encoded), +because the proxy will split the components on the first colon it finds. + +## HTTPS proxy servers + +Composer supports HTTPS proxy servers, where HTTPS is the scheme used to connect to the proxy, but +only from PHP 7.3 with curl version 7.52.0 and above. + +``` +http_proxy=https://proxy.com:443 +https_proxy=https://proxy.com:443 +``` + +## Bypassing the proxy for specific domains + +Use the `no_proxy` (or `NO_PROXY`) environment variable to set a comma-separated list of domains +that the proxy should **not** be used for. + +``` +no_proxy=example.com +# Bypasses the proxy for example.com and its sub-domains + +no_proxy=www.example.com +# Bypasses the proxy for www.example.com and its sub-domains, but not for example.com +``` + +A domain can be restricted to a particular port (e.g. `:80`) and can also be specified as an IP +address or an IP address block in CIDR notation. + +IPv6 addresses do not need to be enclosed in square brackets, like they are for +http_proxy/https_proxy values, although this format is accepted. + +Setting the value to `*` will bypass the proxy for all requests. + +> **Note:** A leading dot in the domain name has no significance and is removed prior to processing. + +## Deprecated environment variables + +Composer originally provided `HTTP_PROXY_REQUEST_FULLURI` and `HTTPS_PROXY_REQUEST_FULLURI` to help +mitigate issues with misbehaving proxies. These are no longer required or used. + +## Requirement changes + +Composer <2.8 used `http_proxy` for both HTTP and HTTPS requests if `https_proxy` was not set, +but as of Composer 2.8.0 it requires [scheme-specific](#usage) environment variables. + +The reason for this change is to align Composer with current practice across other popular tools. To help +with the transition, as of Composer 2.7.3 the original behaviour remains but a warning message is +shown instructing the user to add an `https_proxy` environment variable. + +To prevent the original behaviour during the transition period, set an empty environment variable +(`https_proxy=`). diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index d045bdf88..0eae431d1 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -32,6 +32,7 @@ use Seld\JsonLint\ParsingException; use Composer\Command; use Composer\Composer; use Composer\Factory; +use Composer\Downloader\TransportException; use Composer\IO\IOInterface; use Composer\IO\ConsoleIO; use Composer\Json\JsonValidationException; @@ -404,6 +405,7 @@ class Application extends BaseApplication $io->writeError('Composer now requires separate proxy environment variables for HTTP and HTTPS requests.'); $io->writeError('Please set `https_proxy` in addition to your existing proxy environment variables.'); $io->writeError('This fallback (and warning) will be removed in Composer 2.8.0.'); + $io->writeError('https://getcomposer.org/doc/faqs/how-to-use-composer-behind-a-proxy.md'); } return $result; @@ -480,6 +482,11 @@ class Application extends BaseApplication } Silencer::restore(); + if ($exception instanceof TransportException && str_contains($exception->getMessage(), 'Unable to use a proxy')) { + $io->writeError('The following exception indicates your proxy is misconfigured', true, IOInterface::QUIET); + $io->writeError('Check https://getcomposer.org/doc/faqs/how-to-use-composer-behind-a-proxy.md for details', true, IOInterface::QUIET); + } + if (Platform::isWindows() && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) { $io->writeError('The following exception may be caused by a stale entry in your cmd.exe AutoRun', true, IOInterface::QUIET); $io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details', true, IOInterface::QUIET);