Make WordPress Core

Ticket #13777: 13777.patch

File 13777.patch, 23.5 KB (added by jacobsantos, 14 years ago)

Initial request for comment on argument processing class.

  • class-http.php

     
    170170        /**
    171171         * Send a HTTP request to a URI.
    172172         *
    173          * The body and headers are part of the arguments. The 'body' argument is for the body and will
    174          * accept either a string or an array. The 'headers' argument should be an array, but a string
    175          * is acceptable. If the 'body' argument is an array, then it will automatically be escaped
    176          * using http_build_query().
     173         * See {@link WP_Http_Config::process} for more on the arguments for requests.
    177174         *
    178          * The only URI that are supported in the HTTP Transport implementation are the HTTP and HTTPS
    179          * protocols. HTTP and HTTPS are assumed so the server might not know how to handle the send
    180          * headers. Other protocols are unsupported and most likely will fail.
     175         * The only URI that should be used are those that are for the HTTP protocol. Any other URI
     176         * scheme will fail. HTTPS is supported, provided that PHP supports SSL and has the extensions
     177         * installed.
    181178         *
    182          * The defaults are 'method', 'timeout', 'redirection', 'httpversion', 'blocking' and
    183          * 'user-agent'.
    184          *
    185          * Accepted 'method' values are 'GET', 'POST', and 'HEAD', some transports technically allow
    186          * others, but should not be assumed. The 'timeout' is used to sent how long the connection
    187          * should stay open before failing when no response. 'redirection' is used to track how many
    188          * redirects were taken and used to sent the amount for other transports, but not all transports
    189          * accept setting that value.
    190          *
    191          * The 'httpversion' option is used to sent the HTTP version and accepted values are '1.0', and
    192          * '1.1' and should be a string. Version 1.1 is not supported, because of chunk response. The
    193          * 'user-agent' option is the user-agent and is used to replace the default user-agent, which is
    194          * 'WordPress/WP_Version', where WP_Version is the value from $wp_version.
    195          *
    196          * 'blocking' is the default, which is used to tell the transport, whether it should halt PHP
    197          * while it performs the request or continue regardless. Actually, that isn't entirely correct.
    198          * Blocking mode really just means whether the fread should just pull what it can whenever it
    199          * gets bytes or if it should wait until it has enough in the buffer to read or finishes reading
    200          * the entire content. It doesn't actually always mean that PHP will continue going after making
    201          * the request.
    202          *
    203179         * @access public
    204180         * @since 2.7.0
    205          * @todo Refactor this code. The code in this method extends the scope of its original purpose
    206          *              and should be refactored to allow for cleaner abstraction and reduce duplication of the
    207          *              code. One suggestion is to create a class specifically for the arguments, however
    208          *              preliminary refactoring to this affect has affect more than just the scope of the
    209          *              arguments. Something to ponder at least.
    210181         *
    211182         * @param string $url URI resource.
    212183         * @param str|array $args Optional. Override the defaults.
    213184         * @return array containing 'headers', 'body', 'response', 'cookies'
    214185         */
    215186        function request( $url, $args = array() ) {
    216                 global $wp_version;
     187                $config = new WP_Http_Config($url);
     188                $config->process($args);
    217189
    218                 $defaults = array(
    219                         'method' => 'GET',
    220                         'timeout' => apply_filters( 'http_request_timeout', 5),
    221                         'redirection' => apply_filters( 'http_request_redirection_count', 5),
    222                         'httpversion' => apply_filters( 'http_request_version', '1.0'),
    223                         'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )  ),
    224                         'blocking' => true,
    225                         'headers' => array(),
    226                         'cookies' => array(),
    227                         'body' => null,
    228                         'compress' => false,
    229                         'decompress' => true,
    230                         'sslverify' => true
    231                 );
     190                $transports = $config->get_transports();
     191                $r = $config->get_arguments();
    232192
    233                 $r = wp_parse_args( $args, $defaults );
    234                 $r = apply_filters( 'http_request_args', $r, $url );
    235 
    236                 // Allow plugins to short-circuit the request
    237                 $pre = apply_filters( 'pre_http_request', false, $r, $url );
    238                 if ( false !== $pre )
    239                         return $pre;
    240 
    241                 $arrURL = parse_url($url);
    242 
    243                 if ( empty( $url ) || empty($url['scheme'] ) )
    244                         return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
    245 
    246                 if ( $this->block_request( $url ) )
    247                         return new WP_Error('http_request_failed', __('User has blocked requests through HTTP.'));
    248 
    249                 // Determine if this is a https call and pass that on to the transport functions
    250                 // so that we can blacklist the transports that do not support ssl verification
    251                 $r['ssl'] = $arrURL['scheme'] == 'https' || $arrURL['scheme'] == 'ssl';
    252 
    253                 // Determine if this request is to OUR install of WordPress
    254                 $homeURL = parse_url( get_bloginfo('url') );
    255                 $r['local'] = $homeURL['host'] == $arrURL['host'] || 'localhost' == $arrURL['host'];
    256                 unset($homeURL);
    257 
    258                 if ( is_null( $r['headers'] ) )
    259                         $r['headers'] = array();
    260 
    261                 if ( ! is_array($r['headers']) ) {
    262                         $processedHeaders = WP_Http::processHeaders($r['headers']);
    263                         $r['headers'] = $processedHeaders['headers'];
    264                 }
    265 
    266                 if ( isset($r['headers']['User-Agent']) ) {
    267                         $r['user-agent'] = $r['headers']['User-Agent'];
    268                         unset($r['headers']['User-Agent']);
    269                 }
    270 
    271                 if ( isset($r['headers']['user-agent']) ) {
    272                         $r['user-agent'] = $r['headers']['user-agent'];
    273                         unset($r['headers']['user-agent']);
    274                 }
    275 
    276                 // Construct Cookie: header if any cookies are set
    277                 WP_Http::buildCookieHeader( $r );
    278 
    279                 if ( WP_Http_Encoding::is_available() )
    280                         $r['headers']['Accept-Encoding'] = WP_Http_Encoding::accept_encoding();
    281 
    282                 if ( empty($r['body']) ) {
    283                         // Some servers fail when sending content without the content-length header being set.
    284                         // Also, to fix another bug, we only send when doing POST and PUT and the content-length
    285                         // header isn't already set.
    286                         if( ($r['method'] == 'POST' || $r['method'] == 'PUT') && ! isset($r['headers']['Content-Length']) )
    287                                 $r['headers']['Content-Length'] = 0;
    288 
    289                         // The method is ambiguous, because we aren't talking about HTTP methods, the "get" in
    290                         // this case is simply that we aren't sending any bodies and to get the transports that
    291                         // don't support sending bodies along with those which do.
    292                         $transports = WP_Http::_getTransport($r);
    293                 } else {
    294                         if ( is_array( $r['body'] ) || is_object( $r['body'] ) ) {
    295                                 if ( ! version_compare(phpversion(), '5.1.2', '>=') )
    296                                         $r['body'] = _http_build_query($r['body'], null, '&');
    297                                 else
    298                                         $r['body'] = http_build_query($r['body'], null, '&');
    299                                 $r['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset');
    300                                 $r['headers']['Content-Length'] = strlen($r['body']);
    301                         }
    302 
    303                         if ( ! isset( $r['headers']['Content-Length'] ) && ! isset( $r['headers']['content-length'] ) )
    304                                 $r['headers']['Content-Length'] = strlen($r['body']);
    305 
    306                         // The method is ambiguous, because we aren't talking about HTTP methods, the "post" in
    307                         // this case is simply that we are sending HTTP body and to get the transports that do
    308                         // support sending the body. Not all do, depending on the limitations of the PHP core
    309                         // limitations.
    310                         $transports = WP_Http::_postTransport($r);
    311                 }
    312 
    313193                do_action( 'http_api_debug', $transports, 'transports_list' );
    314194
    315195                $response = array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
     
    549429         * @return bool True to block, false to allow.
    550430         */
    551431        function block_request($uri) {
     432                $config = new WP_Http_Config($uri);
     433                return $config->block_request();
     434        }
     435}
     436
     437/**
     438 * Consolidates the argument processing for all of the transports and main WP_Http class.
     439 *
     440 * Since the beginning the argument processing was handled in both {@link WP_Http::request()} and in
     441 * the individual transports. As more arguments and features were added, it became that
     442 * {@link WP_Http::request()} was getting all of the support and the rest of the transports were
     443 * becoming stagnate with argument processing.
     444 *
     445 * The individual transports appear to be used more individually, which would cause problems with
     446 * argument processing or require duplication of {@link WP_Http::request()} code.
     447 *
     448 * @since {unknown}
     449 * @package WordPress
     450 * @subpackage HTTP
     451 */
     452class WP_Http_Config {
     453
     454        /**
     455         * The request URL.
     456         *
     457         * @since {unknown}
     458         * @var string
     459         */
     460        var $uri = '';
     461
     462        /**
     463         * Processed arguments cache.
     464         *
     465         * @since {unknown}
     466         * @var array
     467         */
     468        var $args = array();
     469
     470        /**
     471         * PHP4 constructor calls PHP5 constructor.
     472         *
     473         * @since {unknown}
     474         *
     475         * @param String $uri Request URI.
     476         */
     477        function WP_Http_Config( $uri = '' ) {
     478                $this->__construct($uri);
     479        }
     480
     481        /**
     482         * PHP5 constructor - Initialize class properties.
     483         *
     484         * @since {unknown}
     485         *
     486         * @param String $uri Request URI.
     487         */
     488        function __construct( $uri = '' ) {
     489                $this->uri = $uri;
     490        }
     491
     492        /**
     493         * Process arguments for sending requests.
     494         *
     495         * The 'body' argument is for the body and will accept either a string or an array. If the
     496         * 'body' argument is an array, then it will automatically be escaped using http_build_query().
     497         * The 'content-type' header will automatically be set as well as 'content-length' to the size
     498         * of the body, if the 'body' argument is an array.
     499         *
     500         * The 'headers' argument should be an array, but a string will be accepted and then converted
     501         * to an array. The recommendation for headers to be an array is for optimization purposes. The
     502         * header array should have the header (or field) name as the array key (or indicies) and the
     503         * header value as the array value.
     504         *
     505         * The defaults are 'method', 'timeout', 'redirection', 'httpversion', 'blocking' and
     506         * 'user-agent'.
     507         *
     508         * Accepted 'method' values are 'GET', 'POST', and 'HEAD', some transports technically allow
     509         * others, but should not be assumed. The 'timeout' is used to sent how long the connection
     510         * should stay open before failing when no response. 'redirection' is used to track how many
     511         * redirects were taken and used to sent the amount for other transports, but not all transports
     512         * accept setting that value.
     513         *
     514         * The 'httpversion' option is used to sent the HTTP version and accepted values are '1.0', and
     515         * '1.1' and should be a string. Version 1.1 is supported, since chunked responses are
     516         * supported. The 'user-agent' option is the user-agent and is used to replace the default
     517         * user-agent, which is 'WordPress/WP_Version', where WP_Version is the value from $wp_version.
     518         *
     519         * 'blocking' is the default, which is used to tell the transport, whether it should halt PHP
     520         * while it performs the request or continue regardless. Actually, that isn't entirely correct.
     521         * Blocking mode really just means whether the fread should just pull what it can whenever it
     522         * gets bytes or if it should wait until it has enough in the buffer to read or finishes reading
     523         * the entire content. It doesn't actually always mean that PHP will continue going after making
     524         * the request.
     525         *
     526         * @access public
     527         * @since {unknown}
     528         *
     529         * @param str|array $args Optional. Override the defaults.
     530         * @return array Transports for either sending body or for get requests.
     531         */
     532        function process( $args = array() ) {
     533                global $wp_version;
     534
     535                $defaults = array(
     536                        'method' => 'GET',
     537                        'timeout' => apply_filters( 'http_request_timeout', 5),
     538                        'redirection' => apply_filters( 'http_request_redirection_count', 5),
     539                        'httpversion' => apply_filters( 'http_request_version', '1.0'),
     540                        'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )  ),
     541                        'blocking' => true,
     542                        'headers' => array(),
     543                        'cookies' => array(),
     544                        'body' => null,
     545                        'compress' => false,
     546                        'decompress' => true,
     547                        'sslverify' => true
     548                );
     549
     550                $r = wp_parse_args( $args, $defaults );
     551                $r = apply_filters( 'http_request_args', $r, $this->uri );
     552
     553                // Allow plugins to short-circuit the request
     554                $pre = apply_filters( 'pre_http_request', false, $r, $this->uri );
     555                if ( false !== $pre )
     556                        return $pre;
     557
     558                $arrURL = parse_url($this->uri);
     559
     560                if ( empty( $arrURL ) || empty($arrURL['scheme'] ) )
     561                        return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
     562
     563                if ( $this->block_request() )
     564                        return new WP_Error('http_request_failed', __('User has blocked requests through HTTP.'));
     565
     566                // Determine if this is a https call and pass that on to the transport functions
     567                // so that we can blacklist the transports that do not support ssl verification
     568                $r['ssl'] = $arrURL['scheme'] == 'https' || $arrURL['scheme'] == 'ssl';
     569
     570                // Determine if this request is to OUR install of WordPress
     571                $homeURL = parse_url( get_bloginfo('url') );
     572                $r['local'] = $homeURL['host'] == $arrURL['host'] || 'localhost' == $arrURL['host'];
     573                unset($homeURL);
     574
     575                if ( is_null( $r['headers'] ) )
     576                        $r['headers'] = array();
     577
     578                // Convert string to an array, if needed.
     579                if ( ! is_array($r['headers']) ) {
     580                        $processedHeaders = WP_Http::processHeaders($r['headers']);
     581                        $r['headers'] = $processedHeaders['headers'];
     582                }
     583
     584                // Change all headers to lowercase to standardize header checks.
     585                // RFC 1945 section 4.2 states that "Field names are case-insensitive."
     586                $r['headers'] = array_change_key_case($r['headers']);
     587
     588                // Most transports do not support setting user-agent by header value alone. Therefore,
     589                // to prevent possible problems, we change it to an argument
     590                if ( isset($r['headers']['user-agent']) ) {
     591                        $r['user-agent'] = $r['headers']['user-agent'];
     592                        unset($r['headers']['user-agent']);
     593                }
     594
     595                // Construct Cookie: header if any cookies are set
     596                WP_Http::buildCookieHeader( $r );
     597
     598                if ( WP_Http_Encoding::is_available() )
     599                        $r['headers']['accept-encoding'] = WP_Http_Encoding::accept_encoding();
     600
     601                if ( empty($r['body']) ) {
     602                        // Some servers fail when sending content without the content-length header being set.
     603                        // Also, to fix another bug, we only send when doing POST and PUT and the content-length
     604                        // header isn't already set.
     605                        if( ($r['method'] == 'POST' || $r['method'] == 'PUT') && ! isset($r['headers']['content-length']) )
     606                                $r['headers']['content-length'] = 0;
     607                } else {
     608                        if ( is_array( $r['body'] ) || is_object( $r['body'] ) ) {
     609                                if ( ! version_compare(phpversion(), '5.1.2', '>=') )
     610                                        $r['body'] = _http_build_query($r['body'], null, '&');
     611                                else
     612                                        $r['body'] = http_build_query($r['body'], null, '&');
     613                                $r['headers']['content-type'] = 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset');
     614                                $r['headers']['content-length'] = strlen($r['body']);
     615                        }
     616
     617                        if ( ! isset( $r['headers']['content-length'] ) && ! isset( $r['headers']['content-length'] ) )
     618                                $r['headers']['content-length'] = strlen($r['body']);
     619                }
     620
     621                $r['processed'] = true;
     622
     623                $this->args = $r;
     624        }
     625
     626        /**
     627         * Retrieve transports based on whether body is sent with the request.
     628         *
     629         * There used to be a note in the methods used that they both are ambiguous. The note was given
     630         * to prevent future coders from incorrectly assuming that the 'get' in
     631         * {@link WP_Http::_getTransport()} was for HTTP GET method requests and that the 'post' in
     632         * {@link WP_Http::_postTransport()} was for HTTP POST method requests. This is not the case,
     633         * the two methods were created because there is a transport for PHP4 that does not support
     634         * sending the request body and must be ignored for those requests.
     635         *
     636         * The above note are part of the methods, but the note was duplicated for clarity sake to
     637         * prevent questions on why they are that way.
     638         *
     639         * @since {unknown}
     640         *
     641         * @return array Transports for sending requests.
     642         */
     643        function get_transports() {
     644                return ( empty($this->args['body']) ) ? WP_Http::_getTransport($r) : WP_Http::_postTransport($r);
     645        }
     646
     647        /**
     648         * Retrieve processed arguments.
     649         *
     650         * The {@link WP_Http_Config::process()} needs to be called first or this method will only
     651         * return an empty array.
     652         *
     653         * @since {unknown}
     654         *
     655         * @return array Processed Arguments for requests.
     656         */
     657        function get_arguments() {
     658                return $this->args;
     659        }
     660
     661        /**
     662         * Block requests through the proxy.
     663         *
     664         * Those who are behind a proxy and want to prevent access to certain hosts may do so. This will
     665         * prevent plugins from working and core functionality, if you don't include api.wordpress.org.
     666         *
     667         * You block external URL requests by defining WP_HTTP_BLOCK_EXTERNAL as true in your wp-config.php
     668         * file and this will only allow localhost and your blog to make requests. The constant
     669         * WP_ACCESSIBLE_HOSTS will allow additional hosts to go through for requests. The format of the
     670         * WP_ACCESSIBLE_HOSTS constant is a comma separated list of hostnames to allow.
     671         *
     672         * @since 2.8.0
     673         * @link http://core.trac.wordpress.org/ticket/8927 Allow preventing external requests.
     674         *
     675         * @param string $uri URI of url.
     676         * @return bool True to block, false to allow.
     677         */
     678        function block_request() {
    552679                // We don't need to block requests, because nothing is blocked.
    553680                if ( ! defined( 'WP_HTTP_BLOCK_EXTERNAL' ) || ! WP_HTTP_BLOCK_EXTERNAL )
    554681                        return false;
    555682
    556683                // parse_url() only handles http, https type URLs, and will emit E_WARNING on failure.
    557684                // This will be displayed on blogs, which is not reasonable.
    558                 $check = @parse_url($uri);
     685                $check = @parse_url($this->uri);
    559686
    560687                /* Malformed URL, can not process, but this could mean ssl, so let through anyway.
    561688                 *
     
    609736         * @return array 'headers', 'body', 'cookies' and 'response' keys.
    610737         */
    611738        function request($url, $args = array()) {
    612                 $defaults = array(
    613                         'method' => 'GET', 'timeout' => 5,
    614                         'redirection' => 5, 'httpversion' => '1.0',
    615                         'blocking' => true,
    616                         'headers' => array(), 'body' => null, 'cookies' => array()
    617                 );
     739                $config = new WP_Http_Config($url);
    618740
    619                 $r = wp_parse_args( $args, $defaults );
    620 
    621                 if ( isset($r['headers']['User-Agent']) ) {
    622                         $r['user-agent'] = $r['headers']['User-Agent'];
    623                         unset($r['headers']['User-Agent']);
    624                 } else if( isset($r['headers']['user-agent']) ) {
    625                         $r['user-agent'] = $r['headers']['user-agent'];
    626                         unset($r['headers']['user-agent']);
     741                $r = $args;
     742                if( ! isset($args['processed']) && ! $args['processed'] ) {
     743                        $config->process($args);
     744                        $r = $config->get_arguments();
    627745                }
    628746
    629                 // Construct Cookie: header if any cookies are set
    630                 WP_Http::buildCookieHeader( $r );
    631 
    632747                $iError = null; // Store error number
    633748                $strError = null; // Store error string
    634749
     
    729844                        return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
    730845                }
    731846
    732                 $strResponse = '';
    733                 while ( ! feof($handle) )
    734                         $strResponse .= fread($handle, 4096);
    735 
     847                $strResponse = $this->_get_response(&$handle);
    736848                fclose($handle);
    737849
    738850                if ( true === $secure_transport )
     
    765877        }
    766878
    767879        /**
     880         * Retrieves the response message using resource handle.
     881         *
     882         * This should allow for others to inherit and extend the class to implement their own resource
     883         * handling. A request was made a long time ago for handling long streams which will exhaust
     884         * memory, but is not a feature that majority of developers will need.
     885         *
     886         * @param resource $handle Fsockopen resource
     887         * @return string Response message (includes header and body).
     888         */
     889        function _get_response(&$handle) {
     890                $strResponse = '';
     891                while ( ! feof($handle) )
     892                        $strResponse .= fread($handle, 4096);
     893
     894                return $strResponse;
     895        }
     896
     897        /**
    768898         * Whether this class can be used for retrieving an URL.
    769899         *
    770900         * @since 2.7.0
     
    818948         * @return array 'headers', 'body', 'cookies' and 'response' keys.
    819949         */
    820950        function request($url, $args = array()) {
    821                 $defaults = array(
    822                         'method' => 'GET', 'timeout' => 5,
    823                         'redirection' => 5, 'httpversion' => '1.0',
    824                         'blocking' => true,
    825                         'headers' => array(), 'body' => null, 'cookies' => array()
    826                 );
     951                $config = new WP_Http_Config($url);
    827952
    828                 $r = wp_parse_args( $args, $defaults );
     953                $r = $args;
     954                if( ! isset($args['processed']) && ! $args['processed'] ) {
     955                        $config->process($args);
     956                        $r = $config->get_arguments();
     957                }
    829958
    830959                $arrURL = parse_url($url);
    831960
     
    9611090         * @return array 'headers', 'body', 'cookies' and 'response' keys.
    9621091         */
    9631092        function request($url, $args = array()) {
    964                 $defaults = array(
    965                         'method' => 'GET', 'timeout' => 5,
    966                         'redirection' => 5, 'httpversion' => '1.0',
    967                         'blocking' => true,
    968                         'headers' => array(), 'body' => null, 'cookies' => array()
    969                 );
     1093                $config = new WP_Http_Config($url);
    9701094
    971                 $r = wp_parse_args( $args, $defaults );
    972 
    973                 if ( isset($r['headers']['User-Agent']) ) {
    974                         $r['user-agent'] = $r['headers']['User-Agent'];
    975                         unset($r['headers']['User-Agent']);
    976                 } else if( isset($r['headers']['user-agent']) ) {
    977                         $r['user-agent'] = $r['headers']['user-agent'];
    978                         unset($r['headers']['user-agent']);
     1095                $r = $args;
     1096                if( ! isset($args['processed']) && ! $args['processed'] ) {
     1097                        $config->process($args);
     1098                        $r = $config->get_arguments();
    9791099                }
    9801100
    981                 // Construct Cookie: header if any cookies are set
    982                 WP_Http::buildCookieHeader( $r );
    983 
    9841101                $arrURL = parse_url($url);
    9851102
    9861103                if ( false === $arrURL )
     
    11341251         * @return array 'headers', 'body', 'cookies' and 'response' keys.
    11351252         */
    11361253        function request($url, $args = array()) {
    1137                 $defaults = array(
    1138                         'method' => 'GET', 'timeout' => 5,
    1139                         'redirection' => 5, 'httpversion' => '1.0',
    1140                         'blocking' => true,
    1141                         'headers' => array(), 'body' => null, 'cookies' => array()
    1142                 );
     1254                $config = new WP_Http_Config($url);
    11431255
    1144                 $r = wp_parse_args( $args, $defaults );
    1145 
    1146                 if ( isset($r['headers']['User-Agent']) ) {
    1147                         $r['user-agent'] = $r['headers']['User-Agent'];
    1148                         unset($r['headers']['User-Agent']);
    1149                 } else if( isset($r['headers']['user-agent']) ) {
    1150                         $r['user-agent'] = $r['headers']['user-agent'];
    1151                         unset($r['headers']['user-agent']);
     1256                $r = $args;
     1257                if( ! isset($args['processed']) && ! $args['processed'] ) {
     1258                        $config->process($args);
     1259                        $r = $config->get_arguments();
    11521260                }
    11531261
    1154                 // Construct Cookie: header if any cookies are set
    1155                 WP_Http::buildCookieHeader( $r );
    1156 
    11571262                switch ( $r['method'] ) {
    11581263                        case 'POST':
    11591264                                $r['method'] = HTTP_METH_POST;
     
    12251330                if ( ! $r['blocking'] )
    12261331                        return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
    12271332
    1228                 $headers_body = WP_HTTP::processResponse($strResponse);
     1333                $headers_body = WP_Http::processResponse($strResponse);
    12291334                $theHeaders = $headers_body['headers'];
    12301335                $theBody = $headers_body['body'];
    12311336                unset($headers_body);
     
    12841389         * @return array 'headers', 'body', 'cookies' and 'response' keys.
    12851390         */
    12861391        function request($url, $args = array()) {
    1287                 $defaults = array(
    1288                         'method' => 'GET', 'timeout' => 5,
    1289                         'redirection' => 5, 'httpversion' => '1.0',
    1290                         'blocking' => true,
    1291                         'headers' => array(), 'body' => null, 'cookies' => array()
    1292                 );
     1392                $config = new WP_Http_Config($url);
    12931393
    1294                 $r = wp_parse_args( $args, $defaults );
    1295 
    1296                 if ( isset($r['headers']['User-Agent']) ) {
    1297                         $r['user-agent'] = $r['headers']['User-Agent'];
    1298                         unset($r['headers']['User-Agent']);
    1299                 } else if( isset($r['headers']['user-agent']) ) {
    1300                         $r['user-agent'] = $r['headers']['user-agent'];
    1301                         unset($r['headers']['user-agent']);
     1394                $r = $args;
     1395                if( ! isset($args['processed']) && ! $args['processed'] ) {
     1396                        $config->process($args);
     1397                        $r = $config->get_arguments();
    13021398                }
    13031399
    1304                 // Construct Cookie: header if any cookies are set.
    1305                 WP_Http::buildCookieHeader( $r );
    1306 
    13071400                $handle = curl_init();
    13081401
    13091402                // cURL offers really easy proxy support.