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:xxxxx@xx.xx.xx.xx: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?

Answers 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.


Related Questions