Make WordPress Core

Ticket #11613: 11613.patch

File 11613.patch, 19.0 KB (added by jacobsantos, 14 years ago)

Non-tested prototype for better solution.

  • class-http.php

     
    167167                        return $blocking_transport;
    168168        }
    169169
     170        function get_transports($type = 'blocking') {
     171                static $working_transport, $blocking_transport, $nonblocking_transport;
     172
     173                if ( is_null($working_transport) ) {
     174                        if ( true === WP_Http_ExtHttp::test() ) {
     175                                $working_transport['exthttp'] = new WP_Http_ExtHttp();
     176                                $blocking_transport[] = &$working_transport['exthttp'];
     177                        } else if ( true === WP_Http_Curl::test() ) {
     178                                $working_transport['curl'] = new WP_Http_Curl();
     179                                $blocking_transport[] = &$working_transport['curl'];
     180                        } else if ( true === WP_Http_Streams::test() ) {
     181                                $working_transport['streams'] = new WP_Http_Streams();
     182                                $blocking_transport[] = &$working_transport['streams'];
     183                        } else if ( true === WP_Http_Fopen::test() ) {
     184                                $working_transport['fopen'] = new WP_Http_Fopen();
     185                                $blocking_transport[] = &$working_transport['fopen'];
     186                        } else if ( true === WP_Http_Fsockopen::test() ) {
     187                                $working_transport['fsockopen'] = new WP_Http_Fsockopen();
     188                                $blocking_transport[] = &$working_transport['fsockopen'];
     189                        }
     190
     191                        foreach ( array('curl', 'streams', 'fsockopen', 'exthttp') as $transport ) {
     192                                if ( isset($working_transport[$transport]) )
     193                                        $nonblocking_transport[] = &$working_transport[$transport];
     194                        }
     195                }
     196
     197                do_action( 'http_transport_post_debug', $working_transport, $blocking_transport, $nonblocking_transport );
     198
     199                switch ( $type ) {
     200                        case 'blocking':
     201                                return $blocking_transport;
     202                        case 'nonblocking':
     203                                return $nonblocking_transport;
     204                        default:
     205                                return $working_transport;
     206                }
     207        }
     208
    170209        /**
    171210         * Send a HTTP request to a URI.
    172211         *
     
    175214         * is acceptable. If the 'body' argument is an array, then it will automatically be escaped
    176215         * using http_build_query().
    177216         *
    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.
     217         * The only URI that should be used are those that are for the HTTP protocol. Any other URI
     218         * scheme will fail. HTTPS is supported, provided that PHP supports SSL and has the extensions
     219         * installed.
    181220         *
    182221         * The defaults are 'method', 'timeout', 'redirection', 'httpversion', 'blocking' and
    183222         * 'user-agent'.
     
    314353
    315354                $response = array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
    316355                foreach ( (array) $transports as $transport ) {
     356                        // Really just want to check that able to send body and do SSL.
     357                        if ( ! $transport->supports_args($r, false) )
     358                                continue;
     359
    317360                        $response = $transport->request($url, $r);
    318361
    319362                        do_action( 'http_api_debug', $response, 'response', get_class($transport) );
     
    729772                        return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
    730773                }
    731774
    732                 $strResponse = '';
    733                 while ( ! feof($handle) )
    734                         $strResponse .= fread($handle, 4096);
    735 
     775                $strResponse = $this->_get_response(&$handle);
    736776                fclose($handle);
    737777
    738778                if ( true === $secure_transport )
     
    765805        }
    766806
    767807        /**
     808         * Retrieves the response message using resource handle.
     809         *
     810         * This should allow for others to inherit and extend the class to implement their own resource
     811         * handling. A request was made a long time ago for handling long streams which will exhaust
     812         * memory, but is not a feature that majority of developers will need.
     813         *
     814         * @param resource $handle Fsockopen resource
     815         * @return string Response message (includes header and body).
     816         */
     817        function _get_response(&$handle) {
     818                $strResponse = '';
     819                while ( ! feof($handle) )
     820                        $strResponse .= fread($handle, 4096);
     821
     822                return $strResponse;
     823        }
     824
     825        /**
    768826         * Whether this class can be used for retrieving an URL.
    769827         *
     828         * The scope of this method is to tell whether or not the transport is supported by the server.
     829         *
    770830         * @since 2.7.0
    771831         * @static
    772832         * @return boolean False means this class can not be used, true means it can.
     
    775835                if ( false !== ($option = get_option( 'disable_fsockopen' )) && time()-$option < 43200 ) // 12 hours
    776836                        return false;
    777837
     838                return $this->supports_args($args);
     839        }
     840
     841        /**
     842         * Whether feature is supported by transport.
     843         *
     844         * The supported feature values are 'ssl', 'non-blocking', 'headers', and 'post'. SSL is whether
     845         * SSL connections can be made. The 'non-blocking' means whether the execution of the HTTP
     846         * request will continue to block the execution of the script. This is important for wp-cron and
     847         * other async requests where speed is important and AJAX workaround would be too complex to
     848         * use.
     849         *
     850         * The 'headers' feature really means whether headers can be sent, which really all of the
     851         * transports can now anyway. The 'post' feature really just means whether the body can be sent
     852         * with the request.
     853         *
     854         * @since {unknown}
     855         *
     856         * @param string $feature Feature that can be used by transport: 'ssl', 'non-blocking', 'headers', and 'post'.
     857         * @param mixed $option Optional. Not used by class.
     858         * @return boolean Whether feature is supported by Transport.
     859         */
     860        function supports( $feature, $option = '' ) {
     861                $supports = false;
     862                switch( strtolower($feature) ) {
     863                        case 'ssl':
     864                                $supports = extension_loaded('openssl');
     865                                break;
     866                        case 'non-blocking':
     867                                $supports = false;
     868                                break;
     869                        case 'headers':
     870                                $supports = true;
     871                                break;
     872                        case 'post':
     873                                $supports = true;
     874                                break;
     875                }
     876
     877                return $supports;
     878        }
     879
     880        /**
     881         * Whether the request arguments are supported by the transport.
     882         *
     883         * This method is useful since you can pass the complete args and it will test it and return
     884         * whether the class can be used for the request.
     885         *
     886         * @param array $args Processed request arguments. Must be the processed arguments!
     887         * @param bool $strict Optional. Whether to check for additional problems that won't fail execution otherwise.
     888         * @return boolean
     889         */
     890        function supports_args($args, $strict = false) {
     891                $supported = true;
    778892                $is_ssl = isset($args['ssl']) && $args['ssl'];
    779893
    780894                if ( ! $is_ssl && function_exists( 'fsockopen' ) )
    781                         $use = true;
    782                 elseif ( $is_ssl && extension_loaded('openssl') && function_exists( 'fsockopen' ) )
    783                         $use = true;
     895                        $supported = true;
     896                elseif ( $is_ssl && $this->supports('ssl') && function_exists( 'fsockopen' ) )
     897                        $supported = true;
    784898                else
    785                         $use = false;
     899                        $supported = false;
    786900
    787                 return apply_filters('use_fsockopen_transport', $use, $args);
     901                if ( $strict ) {
     902                        if ( isset($args['blocking']) && ! $args['blocking'] ) {
     903                                $supported = false;
     904                        }
     905                }
     906
     907                return apply_filters('use_fsockopen_transport', $supported, $args);
    788908        }
    789909}
    790910
     
    9061026        /**
    9071027         * Whether this class can be used for retrieving an URL.
    9081028         *
     1029         * The scope of this method is to tell whether or not the transport is supported by the server.
     1030         *
    9091031         * @since 2.7.0
    9101032         * @static
    9111033         * @return boolean False means this class can not be used, true means it can.
    9121034         */
    9131035        function test($args = array()) {
     1036                if ( version_compare(PHP_VERSION, '5.0', '>=') ) // PHP4 only backwards compat.
     1037                        return false;
     1038
    9141039                if ( ! function_exists('fopen') || (function_exists('ini_get') && true != ini_get('allow_url_fopen')) )
    9151040                        return false;
    9161041
     1042                return $this->supports_args($args);
     1043        }
     1044
     1045        /**
     1046         * Whether feature is supported by transport.
     1047         *
     1048         * The supported feature values are 'ssl', 'non-blocking', 'headers', and 'post'. SSL is whether
     1049         * SSL connections can be made. The 'non-blocking' means whether the execution of the HTTP
     1050         * request will continue to block the execution of the script. This is important for wp-cron and
     1051         * other async requests where speed is important and AJAX workaround would be too complex to
     1052         * use.
     1053         *
     1054         * The 'headers' feature really means whether headers can be sent, which really all of the
     1055         * transports can now anyway. The 'post' feature really just means whether the body can be sent
     1056         * with the request.
     1057         *
     1058         * @since {unknown}
     1059         *
     1060         * @param string $feature Feature that can be used by transport: 'ssl', 'non-blocking', 'headers', and 'post'.
     1061         * @param mixed $option Optional. Is used for SSL feature. Should be request args.
     1062         * @return boolean Whether feature is supported by Transport.
     1063         */
     1064        function supports( $feature, $option = '' ) {
     1065                $supports = false;
     1066                switch ( strtolower( $feature ) ) {
     1067                        case 'ssl':
     1068                                $is_local = isset($option['local']) && $option['local'];
     1069                                $ssl_verify = isset($option['sslverify']) && $option['sslverify'];
     1070                                if ( $is_local && true != apply_filters('https_local_ssl_verify', true) )
     1071                                        $supports = true;
     1072                                elseif ( !$is_local && true != apply_filters('https_ssl_verify', true) )
     1073                                        $supports = true;
     1074                                elseif ( !$ssl_verify )
     1075                                        $supports = true;
     1076                                break;
     1077                        case 'non-blocking':
     1078                                $supports = false;
     1079                                break;
     1080                        case 'headers':
     1081                                $supports = true;
     1082                                break;
     1083                        case 'post':
     1084                                $supports = false;
     1085                                break;
     1086                }
     1087
     1088                return $supports;
     1089        }
     1090
     1091        /**
     1092         * Whether the request arguments are supported by the transport.
     1093         *
     1094         * This method is useful since you can pass the complete args and it will test it and return
     1095         * whether the class can be used for the request.
     1096         *
     1097         * @since {unknown}
     1098         *
     1099         * @param array $args Processed request arguments. Must be the processed arguments!
     1100         * @param bool $strict Optional. Whether to check for additional problems that won't fail execution otherwise.
     1101         * @return boolean
     1102         */
     1103        function supports_args($args, $strict = false) {
    9171104                if ( isset($args['method']) && 'HEAD' == $args['method'] ) //This transport cannot make a HEAD request
    9181105                        return false;
    9191106
    920                 $use = true;
     1107                if ( isset($args['body']) && ! empty($args['body']) ) { // This transport cannot send body.
     1108                        return false;
     1109                }
     1110
     1111                $supported = true;
     1112
    9211113                //PHP does not verify SSL certs, We can only make a request via this transports if SSL Verification is turned off.
    922                 $is_ssl = isset($args['ssl']) && $args['ssl'];
    923                 if ( $is_ssl ) {
    924                         $is_local = isset($args['local']) && $args['local'];
    925                         $ssl_verify = isset($args['sslverify']) && $args['sslverify'];
    926                         if ( $is_local && true != apply_filters('https_local_ssl_verify', true) )
    927                                 $use = true;
    928                         elseif ( !$is_local && true != apply_filters('https_ssl_verify', true) )
    929                                 $use = true;
    930                         elseif ( !$ssl_verify )
    931                                 $use = true;
    932                         else
    933                                 $use = false;
     1114                if ( isset($args['ssl']) && $args['ssl'] ) {
     1115                        $supported = $this->supports('ssl', $args);
    9341116                }
    9351117
    936                 return apply_filters('use_fopen_transport', $use, $args);
     1118                if ( $strict ) {
     1119                        if ( isset($args['blocking']) && ! $args['blocking'] ) {
     1120                                $supported = false;
     1121                        }
     1122                }
     1123
     1124                return apply_filters('use_fopen_transport', $supported, $args);
    9371125        }
    9381126}
    9391127
     
    10801268        /**
    10811269         * Whether this class can be used for retrieving an URL.
    10821270         *
     1271         * The scope of this method is to tell whether or not the transport is supported by the server.
     1272         *
    10831273         * @static
    10841274         * @access public
    10851275         * @since 2.7.0
     
    10931283                if ( version_compare(PHP_VERSION, '5.0', '<') )
    10941284                        return false;
    10951285
     1286                return $this->supports_args($args);
     1287        }
     1288
     1289        /**
     1290         * Whether feature is supported by transport.
     1291         *
     1292         * The supported feature values are 'ssl', 'non-blocking', 'headers', and 'post'. SSL is whether
     1293         * SSL connections can be made. The 'non-blocking' means whether the execution of the HTTP
     1294         * request will continue to block the execution of the script. This is important for wp-cron and
     1295         * other async requests where speed is important and AJAX workaround would be too complex to
     1296         * use.
     1297         *
     1298         * The 'headers' feature really means whether headers can be sent, which really all of the
     1299         * transports can now anyway. The 'post' feature really just means whether the body can be sent
     1300         * with the request.
     1301         *
     1302         * @since {unknown}
     1303         *
     1304         * @param string $feature Feature that can be used by transport: 'ssl', 'non-blocking', 'headers', and 'post'.
     1305         * @param mixed $option Optional. Not used by class.
     1306         * @return boolean Whether feature is supported by Transport.
     1307         */
     1308        function supports( $feature, $option = '' ) {
     1309                $supports = false;
     1310                switch( strtolower($feature) ) {
     1311                        case 'ssl':
     1312                                $supports = true;
     1313                                if ( version_compare(PHP_VERSION, '5.1.0', '<') ) {
     1314                                        $proxy = new WP_HTTP_Proxy();
     1315                                        /**
     1316                                         * No URL check, as its not currently passed to the ::test() function
     1317                                         * In the case where a Proxy is in use, Just bypass this transport for HTTPS.
     1318                                         */
     1319                                        if ( $proxy->is_enabled() )
     1320                                                $supports = false;
     1321                                }
     1322                                break;
     1323                        case 'non-blocking':
     1324                                $supports = true;
     1325                                break;
     1326                        case 'headers':
     1327                                $supports = true;
     1328                                break;
     1329                        case 'post':
     1330                                $supports = true;
     1331                                break;
     1332                }
     1333
     1334                return $supports;
     1335        }
     1336
     1337        /**
     1338         * Whether the request arguments are supported by the transport.
     1339         *
     1340         * This method is useful since you can pass the complete args and it will test it and return
     1341         * whether the class can be used for the request.
     1342         *
     1343         * @since {unknown}
     1344         * @access public
     1345         *
     1346         * @param array $args Processed request arguments. Must be the processed arguments!
     1347         * @param bool $strict Optional. Whether to check for additional problems that won't fail execution otherwise.
     1348         * @return boolean
     1349         */
     1350        function supports_args($args, $strict = false) {
     1351                $supported = true;
    10961352                //HTTPS via Proxy was added in 5.1.0
    10971353                $is_ssl = isset($args['ssl']) && $args['ssl'];
    1098                 if ( $is_ssl && version_compare(PHP_VERSION, '5.1.0', '<') ) {
    1099                         $proxy = new WP_HTTP_Proxy();
    1100                         /**
    1101                          * No URL check, as its not currently passed to the ::test() function
    1102                          * In the case where a Proxy is in use, Just bypass this transport for HTTPS.
    1103                          */
    1104                         if ( $proxy->is_enabled() )
    1105                                 return false;
     1354                if ( $is_ssl && ! $this->supports('ssl') ) {
     1355                        $supported = false;
    11061356                }
    11071357
    1108                 return apply_filters('use_streams_transport', true, $args);
     1358                return apply_filters('use_streams_transport', $supported, $args);
    11091359        }
    11101360}
    11111361
     
    12251475                if ( ! $r['blocking'] )
    12261476                        return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
    12271477
    1228                 $headers_body = WP_HTTP::processResponse($strResponse);
     1478                $headers_body = WP_Http::processResponse($strResponse);
    12291479                $theHeaders = $headers_body['headers'];
    12301480                $theBody = $headers_body['body'];
    12311481                unset($headers_body);
     
    12521502        /**
    12531503         * Whether this class can be used for retrieving an URL.
    12541504         *
     1505         * The scope of this method is to tell whether or not the transport is supported by the server.
     1506         *
    12551507         * @static
    12561508         * @since 2.7.0
    12571509         *
     
    12601512        function test($args = array()) {
    12611513                return apply_filters('use_http_extension_transport', function_exists('http_request'), $args );
    12621514        }
     1515
     1516        /**
     1517         * Whether feature is supported by transport.
     1518         *
     1519         * The supported feature values are 'ssl', 'non-blocking', 'headers', and 'post'. SSL is whether
     1520         * SSL connections can be made. The 'non-blocking' means whether the execution of the HTTP
     1521         * request will continue to block the execution of the script. This is important for wp-cron and
     1522         * other async requests where speed is important and AJAX workaround would be too complex to
     1523         * use.
     1524         *
     1525         * The 'headers' feature really means whether headers can be sent, which really all of the
     1526         * transports can now anyway. The 'post' feature really just means whether the body can be sent
     1527         * with the request.
     1528         *
     1529         * @since {unknown}
     1530         *
     1531         * @param string $feature Feature that can be used by transport: 'ssl', 'non-blocking', 'headers', and 'post'.
     1532         * @param mixed $option Optional. Not used by class.
     1533         * @return boolean Whether feature is supported by Transport.
     1534         */
     1535        function supports( $feature, $option = '' ) {
     1536                $supports = false;
     1537                switch( strtolower($feature) ) {
     1538                        case 'ssl':
     1539                                $supports = true;
     1540                                break;
     1541                        case 'non-blocking':
     1542                                $supports = false;
     1543                                break;
     1544                        case 'headers':
     1545                                $supports = true;
     1546                                break;
     1547                        case 'post':
     1548                                $supports = true;
     1549                                break;
     1550                }
     1551
     1552                return $supports;
     1553        }
     1554
     1555        /**
     1556         * Whether the request arguments are supported by the transport.
     1557         *
     1558         * This method is useful since you can pass the complete args and it will test it and return
     1559         * whether the class can be used for the request.
     1560         *
     1561         * @since {unknown}
     1562         * @access public
     1563         *
     1564         * @param array $args Processed request arguments. Must be the processed arguments!
     1565         * @param bool $strict Optional. Whether to check for additional problems that won't fail execution otherwise.
     1566         * @return boolean
     1567         */
     1568        function supports_args($args, $strict = false) {
     1569                $supported = true;
     1570                if ( $strict ) {
     1571                        if ( isset($args['blocking']) && ! $args['blocking'] ) {
     1572                                $supported = false;
     1573                        }
     1574                }
     1575
     1576                return apply_filters('use_http_extension_transport', $supported, $args);
     1577        }
    12631578}
    12641579
    12651580/**
     
    14471762        /**
    14481763         * Whether this class can be used for retrieving an URL.
    14491764         *
     1765         * The scope of this method is to tell whether or not the transport is supported by the server.
     1766         *
    14501767         * @static
    14511768         * @since 2.7.0
    14521769         *
     
    14581775
    14591776                return false;
    14601777        }
     1778
     1779        /**
     1780         * Whether feature is supported by transport.
     1781         *
     1782         * The supported feature values are 'ssl', 'non-blocking', 'headers', and 'post'. SSL is whether
     1783         * SSL connections can be made. The 'non-blocking' means whether the execution of the HTTP
     1784         * request will continue to block the execution of the script. This is important for wp-cron and
     1785         * other async requests where speed is important and AJAX workaround would be too complex to
     1786         * use.
     1787         *
     1788         * The 'headers' feature really means whether headers can be sent, which really all of the
     1789         * transports can now anyway. The 'post' feature really just means whether the body can be sent
     1790         * with the request.
     1791         *
     1792         * @since {unknown}
     1793         *
     1794         * @param string $feature Feature that can be used by transport: 'ssl', 'non-blocking', 'headers', and 'post'.
     1795         * @param mixed $option Optional. Not used by class.
     1796         * @return boolean Whether feature is supported by Transport.
     1797         */
     1798        function supports( $feature, $option = '' ) {
     1799                $supports = false;
     1800                switch( strtolower($feature) ) {
     1801                        case 'ssl':
     1802                                $supports = true;
     1803                                break;
     1804                        case 'non-blocking':
     1805                                $supports = true;
     1806                                break;
     1807                        case 'headers':
     1808                                $supports = true;
     1809                                break;
     1810                        case 'post':
     1811                                $supports = true;
     1812                                break;
     1813                }
     1814
     1815                return $supports;
     1816        }
     1817
     1818        /**
     1819         * Whether the request arguments are supported by the transport.
     1820         *
     1821         * This method is useful since you can pass the complete args and it will test it and return
     1822         * whether the class can be used for the request.
     1823         *
     1824         * @since {unknown}
     1825         * @access public
     1826         *
     1827         * @param array $args Processed request arguments. Must be the processed arguments!
     1828         * @param bool $strict Optional. Whether to check for additional problems that won't fail execution otherwise.
     1829         * @return boolean
     1830         */
     1831        function supports_args($args, $strict = false) {
     1832                return apply_filters('use_curl_transport', true, $args);
     1833        }
    14611834}
    14621835
    14631836/**