Filter any HTTP request URI?

Less than an answer, but just a list of things straight from my experience with it – maybe you’ve overlooked something.

Debugging the request & its results

Without diggin’ too deep into the update process, but the WP HTTP API uses the WP_HTTP class. It also offers a nice thing: A debug hook.

do_action( 'http_api_debug', $response, 'response', $class, $args, $url );

Where $response can also be a WP_Error object that maybe tells you more.

Note: From a brief test, this filter seems to only (for some reason) work if you place it as close to where you’re actually doing the request. So maybe you need to call it from within a callback on one of the below filters.

WP_HTTP Class arguments

The Classes arguments itself are filterable, but afaik some get reset by the methods internals back to what WP assumes that is needed.

apply_filters( 'http_request_args', $r, $url );

One of the arguments is ssl_verify, which is true by default (but for me causes massive problems when updating from – for example – GitHub). Edit: After debugging a test request, I found another argument that is set to verify if SSL is set to true. It’s called sslverify (without separating underscore). No idea where this came into the game, if it is actually in use or abandoned and if you have a chance to influence its value. I found it using the 'http_api_debug' filter.

Completely custom

You can also “simply” override the whole internals and go with a custom setup. There’s a filter for that.

apply_filters( 'pre_http_request', false, $r, $url );

The first arg needs to be set to true. Than you can interact with the arguments inside $r and the result from parse_url( $url );.

Proxy

Another thing that might work could be running everything through a custom Proxy. This needs some settings in your wp-config.php. I’ve never tried this before, but I ran through the constants a while back and summed up some examples that should work and included some comments in case I need it one day. You have to define WP_PROXY_HOST and WP_PROXY_PORT as a min. setting. Else nothing will work and it will simply bypass your proxy.

# HTTP Proxies
# Used for e.g. in Intranets
# Fixes Feeds as well
# Defines the proxy adresse.
define( 'WP_PROXY_HOST',          '127.0.84.1' );
# Defines the proxy port.
define( 'WP_PROXY_PORT',          '8080' );
# Defines the proxy username.
define( 'WP_PROXY_USERNAME',      'my_user_name' );
# Defines the proxy password.
define( 'WP_PROXY_PASSWORD',      'my_password' );
# Allows you to define some adresses which
# shouldn't be passed through a proxy.
define( 'WP_PROXY_BYPASS_HOSTS',  'localhost, www.example.com' );

EDIT

The WP_HTTP Class normally acts as base class (will be extended for different scenarios). The extending WP_HTTP_* classes are Fsockopen, Streams, Curl, Proxy, Cookie, Encoding. If you hook a callback to the 'http_api_debug'-action, then the third argument will tell you which class was used for your request.

Inside the WP_HTTP_curl Class, you’ll find the request() method. This method offers two filters to intercept the SSL behavior: One for local requests 'https_local_ssl_verify' and one for remote requests 'https_ssl_verify'. WP will likely define local as localhost and what you get in return from get_option( 'siteurl' );.

So what I’d do is to try the following right before you do that request (or from a callback that’s hooked to the closest request:

add_filter( 'https_ssl_verify', '__return_true' );

# Local requests should be checked with something like
# 'localhost' === $_SERVER['HTTP_HOST'] or similar
# add_filter( 'https_local_ssl_verify', '__return_true' );

Sidenote: In most cases WP_HTTP_curl will be used to handle Proxies.

Leave a Comment