I’m trying to set up WordPress on a server that requires a proxy connection to connect to the internet. Here’s what I put in wp-config.php:
/* Configure HTTP Proxy Server */
define('WP_PROXY_HOST', 'xx.xx.xx.xx');
define('WP_PROXY_PORT', '8080');
define('WP_PROXY_USERNAME', 'xxxxx');
define('WP_PROXY_PASSWORD', 'xxxxx');
define('WP_PROXY_BYPASS_HOSTS', 'localhost');
(I replaced real IP, username and password with xxx here for privacy reasons)
Unfortunately, WordPress still can’t connect to the internet. The Site Health page displays this error:
Your site is unable to reach WordPress.org at 198.143.164.251, and returned the error: cURL error 56: Received HTTP code 407 from proxy after CONNECT
407 is a Proxy Authentication Required error.
I checked the proxy’s IP, username and password many times, and it’s definitely correct. The same settings work when I use
export http_proxy="http://xxxxx:[email protected]:8080"
in the command line, and then download something using wget. It connects via proxy, and downloads the file correctly.
I tried using a packet capture program to see what the connection between WordPress and the proxy looks like, and the headers look like this:
CONNECT api.wordpress.org:443 HTTP/1.1
Host: api.wordpress.org:443
User-Agent: WordPress/5.2.4; http://xx.xx.xx.xx/
Proxy-Connection: Keep-Alive
Connection: close
The reply from the proxy server is this:
HTTP/1.1 407 authenticationrequired
Date: Fri, 18 Oct 2019 11:31:00 GMT
Content-Type: text/html
Cache-Control: no-cache
Content-Length: 4365
Proxy-Connection: Keep-Alive
Proxy-Authenticate: Negotiate
Proxy-Authenticate: NTLM
Proxy-Authenticate: Basic realm="McAfee Web Gateway"
I think that there should have been a
Proxy-Authorization: Basic xxxxxxxxxxxxxxx
header in the first packet, but for some reason there isn’t anything like it. What should I do? Am I missing something obvious here?
1 Answer
Not sure if this helps, but you can try..
So WordPress’ default HTTP transport is using cURL, and the HTTP class sets the proxy authorization method to CURLAUTH_ANY
(see source), which might explain why the Proxy-Authorization: Basic xxxxx...
header is missing from the request.
And there’s a hook you can try to change the proxy authorization method to CURLAUTH_BASIC
(which is widely supported, but also very insecure), CURLAUTH_NTLM
or one of the other available methods.
So add this to your theme functions.php
file.. (or put the code into a Must-Use plugin):
add_action( 'http_api_curl', function ( $handle, $r, $url ) {
$proxy = new WP_HTTP_Proxy();
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) {
curl_setopt( $handle, CURLOPT_PROXYAUTH, CURLAUTH_BASIC );
}
}, 10, 3 );
Alternatively, you can set PHP Streams as the default HTTP transport…
add_filter( 'http_api_transports', function ( $transports ) {
return [ 'streams', 'curl' ];
} );
See the hook’s reference and WP_Http_Streams
for more information. But basically, the hook allows you to use a custom class, and WP_Http_Streams
would always set the Proxy-Authorization: Basic xxxxx...
header when necessary.