[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