Debugging WordPress HTTP API Remote Requests

If you’re writing WordPress code that makes remote requests and need to easily debug the requests, here’s some helper code to do it. This requires that you’re using WordPress’s HTTP API which you should already be doing — directly using cURL or other methods is wrong and a great way to make your code not cross-server compatible.

add_action( 'http_api_debug', 'viper_http_api_debug', 10, 5 );

function viper_http_api_debug( $response, $type, $class, $args, $url ) {
	// You can change this from error_log() to var_dump() but it can break AJAX requests
	error_log( 'Request URL: ' . var_export( $url, true ) );
	error_log( 'Request Args: ' . var_export( $args, true ) );
	error_log( 'Request Response : ' . var_export( $response, true ) );
}

That will log the request URL, the request arguments, and the whole response HTTP_API object to your error log file. The last message one will be pretty long/spammy but it’ll give you headers, the body, and everything else. Since it’s an instance of HTTP_API, you can also do things like this if you want to:

error_log( 'Response Code: ' . wp_remote_retrieve_response_code( $response ) );

Tracking WordPress Remote HTTP Requests

UPDATE: You can find improved code in this newer blog post. Use that instead.

I thought I’d share a bit of code that I run on my local WordPress test install to see when WordPress is contacting another website. I originally wrote this to help debug my oEmbed code, but it’s useful for a wide variety of purposes. :)

<?php

if ( !defined('DOING_AJAX') )
	add_filter( 'http_request_args', 'debug_http_api', 10, 2 );

function debug_http_api( $r, $url ) {
	echo '<p style="text-align:left">HTTP API was used to fetch <code>' . esc_html( $url ) . '</code></p>';

	return $r;
}

?>

The above code will output something like this any time a HTTP request is made using the HTTP API, but only if the request was not made from an AJAX handling script (as it will break the AJAX response):

HTTP API was used to fetch http://www.google.com/

While I’m using a filter to do this, I’m actually using the filter much like an action as I’m not modifying the passed data but merely using the filter as a place to hook in and catch the URL.