[wp-trac] [WordPress Trac] #17251: Determine if any WP_HTTP transport can be used before making the request
WordPress Trac
wp-trac at lists.automattic.com
Wed Apr 27 07:02:56 UTC 2011
#17251: Determine if any WP_HTTP transport can be used before making the request
-------------------------+-----------------------------
Reporter: mdawaffe | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: HTTP | Version: 3.2
Severity: normal | Keywords: has-patch
-------------------------+-----------------------------
It can be useful to know if any WP_HTTP transport passes its
{{{::test()}}} before making the corresponding request.
For example, consider OAuth.
Some OAuth providers (servers) offer both HTTP and HTTPS APIs (say
http://api.example.com/ and https://api.example.com/) and leave it up to
the Consumer (client) to decide which to use. The same request, however,
cannot be made to both http://api.example.com/ and
https://api.example.com/ because of the way the OAuth signature is
calculated: the request URL is part of the hash. To calculate the
signature, you have to know whether you will make an HTTP or an HTTPS
request.
Some WordPress installations cannot make outgoing HTTPS requests because
their hosts have disabled the OpenSSL extension. On such hosts, plugins
would ideally use the HTTPS API and fallback to the HTTP API. It is not
currently convenient to use WP_HTTP's {{{::test()}}}s to determine ahead
of time if outgoing HTTPS requests are possible.
Currently, plugins can do something like the following.
{{{
list( $url_signed, $args_signed ) = oauth_sign_request( $url, $args );
$request = wp_remote_request( $url_signed, $args_signed );
if ( is_wp_error( $request ) && 'http_failure' ==
$request->get_error_code() ) {
// HTTPS -> HTTP
$url = substr_replace( $url, '', 4, 1 );
list( $url_signed, $args_signed ) = oauth_sign_request( $url, $args );
$request = wp_remote_request( $url_signed, $args_signed );
}
}}}
The above is inefficient since the OAuth signature must be calculated
twice and the {{{::test()}}}s must be run twice.
Attached:
* Adds new {{{WP_Http::get_first_available_transport( $url, $args )}}}
method which returns the first transport to pass its {{{::test( $args,
$url )}}}.
* Adds a new {{{transport_class}}} option to {{{WP_Http::request()}}} so
that the {{{::test()}}}s don't have to be run multiple times.
The patch allows the following:
{{{
$http = _wp_http_get_object();
$args['ssl'] = true;
if ( $transport_class = $http->get_first_available_transport( $url, $args
) ) {
// We already know which one to use
$args['transport_class'] = $transport_class;
} else {
// HTTPS -> HTTP
$url = substr_replace( $url, '', 4, 1 );
$args['ssl'] = false;
}
list( $url_signed, $args_signed ) = oauth_sign_request( $url, $args );
$request = wp_remote_request( $url_signed, $args_signed );
}}}
In this snip, both the {{{::test()}}}s and the OAuth signature are only
run once. There's a few extra lines in this snip than in the previous
one. Those lines could be removed with a couple straightforward tweaks to
the patch.
See #16606, which also deals with making the WP_HTTP transports and their
{{{::test()}}}s more useful.
--
Ticket URL: <http://core.trac.wordpress.org/ticket/17251>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list