Outgoing proxy connection problem

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
1

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.

Leave a Comment