WordPress.org

Make WordPress Core

Ticket #4011: 4011.diff

File 4011.diff, 42.8 KB (added by jacobsantos, 5 years ago)

Incomplete patch for testing proxy support.

  • http.php

     
    1313 */ 
    1414 
    1515/** 
    16  * Implementation for deflate and gzip transfer encodings. 
    17  * 
    18  * Includes RFC 1950, RFC 1951, and RFC 1952. 
    19  * 
    20  * @since unknown 
    21  * @package WordPress 
    22  * @subpackage HTTP 
    23  */ 
    24 class WP_Http_Encoding { 
    25  
    26         /** 
    27          * Compress raw string using the deflate format. 
    28          * 
    29          * Supports the RFC 1951 standard. 
    30          * 
    31          * @since unknown 
    32          * 
    33          * @param string $raw String to compress. 
    34          * @param int $level Optional, default is 9. Compression level, 9 is highest. 
    35          * @param string $supports Optional, not used. When implemented it will choose the right compression based on what the server supports. 
    36          * @return string|bool False on failure. 
    37          */ 
    38         function compress( $raw, $level = 9, $supports = null ) { 
    39                 return gzdeflate( $raw, $level ); 
    40         } 
    41  
    42         /** 
    43          * Decompression of deflated string. 
    44          * 
    45          * Will attempt to decompress using the RFC 1950 standard, and if that fails 
    46          * then the RFC 1951 standard deflate will be attempted. Finally, the RFC 
    47          * 1952 standard gzip decode will be attempted. If all fail, then the 
    48          * original compressed string will be returned. 
    49          * 
    50          * @since unknown 
    51          * 
    52          * @param string $compressed String to decompress. 
    53          * @param int $length The optional length of the compressed data. 
    54          * @return string|bool False on failure. 
    55          */ 
    56         function decompress( $compressed, $length = null ) { 
    57                 $decompressed = gzinflate( $compressed ); 
    58  
    59                 if( false !== $decompressed ) 
    60                         return $decompressed; 
    61  
    62                 $decompressed = gzuncompress( $compressed ); 
    63  
    64                 if( false !== $decompressed ) 
    65                         return $decompressed; 
    66  
    67                 $decompressed = gzdecode( $compressed ); 
    68  
    69                 if( false !== $decompressed ) 
    70                         return $decompressed; 
    71  
    72                 return $compressed; 
    73         } 
    74  
    75         /** 
    76          * What encoding types to accept and their priority values. 
    77          * 
    78          * @since unknown 
    79          * 
    80          * @return string Types of encoding to accept. 
    81          */ 
    82         function accept_encoding() { 
    83                 $type = array(); 
    84                 if( function_exists( 'gzinflate' ) ) 
    85                         $type[] = 'deflate;q=1.0'; 
    86  
    87                 if( function_exists( 'gzuncompress' ) ) 
    88                         $type[] = 'compress;q=0.5'; 
    89  
    90                 if( function_exists( 'gzdecode' ) ) 
    91                         $type[] = 'gzip;q=0.5'; 
    92  
    93                 return implode(', ', $type); 
    94         } 
    95  
    96         /** 
    97          * What enconding the content used when it was compressed to send in the headers. 
    98          * 
    99          * @since unknown 
    100          * 
    101          * @return string Content-Encoding string to send in the header. 
    102          */ 
    103         function content_encoding() { 
    104                 return 'deflate'; 
    105         } 
    106  
    107         /** 
    108          * Whether the content be decoded based on the headers. 
    109          * 
    110          * @since unknown 
    111          * 
    112          * @param array|string $headers All of the available headers. 
    113          * @return bool 
    114          */ 
    115         function should_decode($headers) { 
    116                 if( is_array( $headers ) ) { 
    117                         if( array_key_exists('content-encoding', $headers) && ! empty( $headers['content-encoding'] ) ) 
    118                                 return true; 
    119                 } else if( is_string( $headers ) ) { 
    120                         return ( stripos($headers, 'content-encoding:') !== false ); 
    121                 } 
    122  
    123                 return false; 
    124         } 
    125  
    126         /** 
    127          * Whether decompression and compression are supported by the PHP version. 
    128          * 
    129          * Each function is tested instead of checking for the zlib extension, to 
    130          * ensure that the functions all exist in the PHP version and aren't 
    131          * disabled. 
    132          * 
    133          * @since unknown 
    134          * 
    135          * @return bool 
    136          */ 
    137         function is_available() { 
    138                 return ( function_exists('gzuncompress') || function_exists('gzdeflate') || 
    139                                  function_exists('gzinflate') ); 
    140         } 
    141 } 
    142  
    143 /** 
    14416 * WordPress HTTP Class for managing HTTP Transports and making HTTP requests. 
    14517 * 
    146  * This class is called for the functionality of making HTTP requests and should 
    147  * replace Snoopy functionality, eventually. There is no available functionality 
    148  * to add HTTP transport implementations, since most of the HTTP transports are 
    149  * added and available for use. 
     18 * This class is called for the functionality of making HTTP requests and should replace Snoopy 
     19 * functionality, eventually. There is no available functionality to add HTTP transport 
     20 * implementations, since most of the HTTP transports are added and available for use. 
    15021 * 
    151  * The exception is that cURL is not available as a transport and lacking an 
    152  * implementation. It will be added later and should be a patch on the WordPress 
    153  * Trac. 
     22 * The exception is that cURL is not available as a transport and lacking an implementation. It will 
     23 * be added later and should be a patch on the WordPress Trac. 
    15424 * 
    155  * There are no properties, because none are needed and for performance reasons. 
    156  * Some of the functions are static and while they do have some overhead over 
    157  * functions in PHP4, the purpose is maintainability. When PHP5 is finally the 
    158  * requirement, it will be easy to add the static keyword to the code. It is not 
    159  * as easy to convert a function to a method after enough code uses the old way. 
     25 * There are no properties, because none are needed and for performance reasons. Some of the 
     26 * functions are static and while they do have some overhead over functions in PHP4, the purpose is 
     27 * maintainability. When PHP5 is finally the requirement, it will be easy to add the static keyword 
     28 * to the code. It is not as easy to convert a function to a method after enough code uses the old 
     29 * way. 
    16030 * 
    161  * Debugging includes several actions, which pass different variables for 
    162  * debugging the HTTP API. 
     31 * Debugging includes several actions, which pass different variables for debugging the HTTP API. 
    16332 * 
    164  * <strong>http_transport_get_debug</strong> - gives working, nonblocking, and 
    165  * blocking transports. 
     33 * <strong>http_transport_get_debug</strong> - gives working, nonblocking, and blocking transports. 
    16634 * 
    167  * <strong>http_transport_post_debug</strong> - gives working, nonblocking, and 
    168  * blocking transports. 
     35 * <strong>http_transport_post_debug</strong> - gives working, nonblocking, and blocking transports. 
    16936 * 
    17037 * @package WordPress 
    17138 * @subpackage HTTP 
     
    22895                static $working_transport, $blocking_transport, $nonblocking_transport; 
    22996 
    23097                if ( is_null($working_transport) ) { 
    231                         if ( true === WP_Http_ExtHttp::test() && apply_filters('use_http_extension_transport', true) ) { 
     98                        if ( true === WP_Http_ExtHttp::test() ) { 
    23299                                $working_transport['exthttp'] = new WP_Http_ExtHttp(); 
    233100                                $blocking_transport[] = &$working_transport['exthttp']; 
    234                         } else if ( true === WP_Http_Curl::test() && apply_filters('use_curl_transport', true) ) { 
     101                        } else if ( true === WP_Http_Curl::test() ) { 
    235102                                $working_transport['curl'] = new WP_Http_Curl(); 
    236103                                $blocking_transport[] = &$working_transport['curl']; 
    237                         } else if ( true === WP_Http_Streams::test() && apply_filters('use_streams_transport', true) ) { 
     104                        } else if ( true === WP_Http_Streams::test() ) { 
    238105                                $working_transport['streams'] = new WP_Http_Streams(); 
    239106                                $blocking_transport[] = &$working_transport['streams']; 
    240                         } else if ( true === WP_Http_Fopen::test() && apply_filters('use_fopen_transport', true) && ( isset($args['ssl']) && !$args['ssl'] ) ) { 
     107                        } else if ( true === WP_Http_Fopen::test() && ( isset($args['ssl']) && !$args['ssl'] ) ) { 
    241108                                $working_transport['fopen'] = new WP_Http_Fopen(); 
    242109                                $blocking_transport[] = &$working_transport['fopen']; 
    243                         } else if ( true === WP_Http_Fsockopen::test() && apply_filters('use_fsockopen_transport', true) && ( isset($args['ssl']) && !$args['ssl'] ) ) { 
     110                        } else if ( true === WP_Http_Fsockopen::test() && ( isset($args['ssl']) && !$args['ssl'] ) ) { 
    244111                                $working_transport['fsockopen'] = new WP_Http_Fsockopen(); 
    245112                                $blocking_transport[] = &$working_transport['fsockopen']; 
    246113                        } 
     
    279146                static $working_transport, $blocking_transport, $nonblocking_transport; 
    280147 
    281148                if ( is_null($working_transport) ) { 
    282                         if ( true === WP_Http_ExtHttp::test() && apply_filters('use_http_extension_transport', true) ) { 
     149                        if ( true === WP_Http_ExtHttp::test() ) { 
    283150                                $working_transport['exthttp'] = new WP_Http_ExtHttp(); 
    284151                                $blocking_transport[] = &$working_transport['exthttp']; 
    285                         } else if ( true === WP_Http_Curl::test() && apply_filters('use_curl_transport', true) ) { 
     152                        } else if ( true === WP_Http_Curl::test() ) { 
    286153                                $working_transport['curl'] = new WP_Http_Curl(); 
    287154                                $blocking_transport[] = &$working_transport['curl']; 
    288                         } else if ( true === WP_Http_Streams::test() && apply_filters('use_streams_transport', true) ) { 
     155                        } else if ( true === WP_Http_Streams::test() ) { 
    289156                                $working_transport['streams'] = new WP_Http_Streams(); 
    290157                                $blocking_transport[] = &$working_transport['streams']; 
    291                         } else if ( true === WP_Http_Fsockopen::test() && apply_filters('use_fsockopen_transport', true) && ( isset($args['ssl']) && !$args['ssl'] ) ) { 
     158                        } else if ( true === WP_Http_Fsockopen::test() && ( isset($args['ssl']) && !$args['ssl'] ) ) { 
    292159                                $working_transport['fsockopen'] = new WP_Http_Fsockopen(); 
    293160                                $blocking_transport[] = &$working_transport['fsockopen']; 
    294161                        } 
     
    311178        /** 
    312179         * Send a HTTP request to a URI. 
    313180         * 
    314          * The body and headers are part of the arguments. The 'body' argument is 
    315          * for the body and will accept either a string or an array. The 'headers' 
    316          * argument should be an array, but a string is acceptable. If the 'body' 
    317          * argument is an array, then it will automatically be escaped using 
    318          * http_build_query(). 
     181         * The body and headers are part of the arguments. The 'body' argument is for the body and will 
     182         * accept either a string or an array. The 'headers' argument should be an array, but a string 
     183         * is acceptable. If the 'body' argument is an array, then it will automatically be escaped 
     184         * using http_build_query(). 
    319185         * 
    320          * The only URI that are supported in the HTTP Transport implementation are 
    321          * the HTTP and HTTPS protocols. HTTP and HTTPS are assumed so the server 
    322          * might not know how to handle the send headers. Other protocols are 
    323          * unsupported and most likely will fail. 
     186         * The only URI that are supported in the HTTP Transport implementation are the HTTP and HTTPS 
     187         * protocols. HTTP and HTTPS are assumed so the server might not know how to handle the send 
     188         * headers. Other protocols are unsupported and most likely will fail. 
    324189         * 
    325          * The defaults are 'method', 'timeout', 'redirection', 'httpversion', 
    326          * 'blocking' and 'user-agent'. 
     190         * The defaults are 'method', 'timeout', 'redirection', 'httpversion', 'blocking' and 
     191         * 'user-agent'. 
    327192         * 
    328          * Accepted 'method' values are 'GET', 'POST', and 'HEAD', some transports 
    329          * technically allow others, but should not be assumed. The 'timeout' is 
    330          * used to sent how long the connection should stay open before failing when 
    331          * no response. 'redirection' is used to track how many redirects were taken 
    332          * and used to sent the amount for other transports, but not all transports 
     193         * Accepted 'method' values are 'GET', 'POST', and 'HEAD', some transports technically allow 
     194         * others, but should not be assumed. The 'timeout' is used to sent how long the connection 
     195         * should stay open before failing when no response. 'redirection' is used to track how many 
     196         * redirects were taken and used to sent the amount for other transports, but not all transports 
    333197         * accept setting that value. 
    334198         * 
    335          * The 'httpversion' option is used to sent the HTTP version and accepted 
    336          * values are '1.0', and '1.1' and should be a string. Version 1.1 is not 
    337          * supported, because of chunk response. The 'user-agent' option is the 
    338          * user-agent and is used to replace the default user-agent, which is 
     199         * The 'httpversion' option is used to sent the HTTP version and accepted values are '1.0', and 
     200         * '1.1' and should be a string. Version 1.1 is not supported, because of chunk response. The 
     201         * 'user-agent' option is the user-agent and is used to replace the default user-agent, which is 
    339202         * 'WordPress/WP_Version', where WP_Version is the value from $wp_version. 
    340203         * 
    341          * 'blocking' is the default, which is used to tell the transport, whether 
    342          * it should halt PHP while it performs the request or continue regardless. 
    343          * Actually, that isn't entirely correct. Blocking mode really just means 
    344          * whether the fread should just pull what it can whenever it gets bytes or 
    345          * if it should wait until it has enough in the buffer to read or finishes 
    346          * reading the entire content. It doesn't actually always mean that PHP will 
    347          * continue going after making the request. 
     204         * 'blocking' is the default, which is used to tell the transport, whether it should halt PHP 
     205         * while it performs the request or continue regardless. Actually, that isn't entirely correct. 
     206         * Blocking mode really just means whether the fread should just pull what it can whenever it 
     207         * gets bytes or if it should wait until it has enough in the buffer to read or finishes reading 
     208         * the entire content. It doesn't actually always mean that PHP will continue going after making 
     209         * the request. 
    348210         * 
    349211         * @access public 
    350212         * @since 2.7.0 
     
    376238 
    377239                $arrURL = parse_url($url); 
    378240 
     241                if ( $this->block_request( $url ) ) 
     242                        return new WP_Error('http_request_failed', 'User has blocked requests through HTTP.'); 
     243 
    379244                // Determine if this is a https call and pass that on to the transport functions 
    380245                // so that we can blacklist the transports that do not support ssl verification 
    381246                if ( $arrURL['scheme'] == 'https' || $arrURL['scheme'] == 'ssl' ) 
     
    400265                        $r['user-agent'] = $r['headers']['user-agent']; 
    401266                        unset($r['headers']['user-agent']); 
    402267                } 
    403                  
     268 
    404269                // Construct Cookie: header if any cookies are set 
    405270                WP_Http::buildCookieHeader( $r ); 
    406271 
     
    514379        /** 
    515380         * Transform header string into an array. 
    516381         * 
    517          * If an array is given then it is assumed to be raw header data with 
    518          * numeric keys with the headers as the values. No headers must be passed 
    519          * that were already processed. 
     382         * If an array is given then it is assumed to be raw header data with numeric keys with the 
     383         * headers as the values. No headers must be passed that were already processed. 
    520384         * 
    521385         * @access public 
    522386         * @static 
     
    561425 
    562426                return array('response' => $response, 'headers' => $newheaders, 'cookies' => $cookies); 
    563427        } 
    564          
     428 
    565429        /** 
    566430         * Takes the arguments for a ::request() and checks for the cookie array. 
    567          * If it's found, then it's assumed to contain WP_Http_Cookie objects, which 
    568          * are each parsed into strings and added to the Cookie: header (within the 
    569          * arguments array). Edits the array by reference. 
    570431         * 
     432         * If it's found, then it's assumed to contain WP_Http_Cookie objects, which are each parsed 
     433         * into strings and added to the Cookie: header (within the arguments array). Edits the array by 
     434         * reference. 
     435         * 
    571436         * @access public 
     437         * @version 2.8.0 
    572438         * @static 
    573439         * 
    574440         * @param array $r Full array of args passed into ::request() 
     
    583449                        $r['headers']['cookie'] = $cookies_header; 
    584450                } 
    585451        } 
    586          
     452 
    587453        /** 
    588454         * Decodes chunk transfer-encoding, based off the HTTP 1.1 specification. 
    589455         * 
    590          * Based off the HTTP http_encoding_dechunk function. Does not support 
    591          * UTF-8. Does not support returning footer headers. Shouldn't be too 
    592          * difficult to support it though. 
     456         * Based off the HTTP http_encoding_dechunk function. Does not support UTF-8. Does not support 
     457         * returning footer headers. Shouldn't be too difficult to support it though. 
    593458         * 
    594459         * @todo Add support for footer chunked headers. 
    595460         * @access public 
     
    630495                        } 
    631496                } 
    632497        } 
     498 
     499        /** 
     500         * Block requests through the proxy. 
     501         * 
     502         * Those who are behind a proxy and want to prevent access to certain hosts may do so. This will 
     503         * prevent plugins from working and core functionality, if you don't include api.wordpress.org. 
     504         * 
     505         * You block external URL requests by defining WP_HTTP_BLOCK_EXTERNAL in your wp-config.php file 
     506         * and this will only allow localhost and your blog to make requests. The constant 
     507         * WP_ACCESSABLE_HOSTS will allow additional hosts to go through for requests. 
     508         * 
     509         * @since unknown 
     510         * @link http://core.trac.wordpress.org/ticket/8927 Allow preventing external requests. 
     511         * 
     512         * @param string $uri URI of url. 
     513         * @return bool True to block, false to allow. 
     514         */ 
     515        function block_request($uri) { 
     516                // We don't need to block requests, because nothing is blocked. 
     517                if ( ! defined('WP_HTTP_BLOCK_EXTERNAL') || ( defined('WP_HTTP_BLOCK_EXTERNAL') && WP_HTTP_BLOCK_EXTERNAL == false ) ) 
     518                        return false; 
     519 
     520                // parse_url() only handles http, https type URLs, and will emit E_WARNING on failure. 
     521                // This will be displayed on blogs, which is not reasonable. 
     522                $check = @parse_url($uri); 
     523 
     524                /* Malformed URL, can not process, but this could mean ssl, so let through anyway. 
     525                 * 
     526                 * This isn't very security sound. There are instances where a hacker might attempt 
     527                 * to bypass the proxy and this check. However, the reason for this behavior is that 
     528                 * WordPress does not do any checking currently for non-proxy requests, so it is keeps with 
     529                 * the default unsecure nature of the HTTP request. 
     530                 */ 
     531                if ( $check === false ) 
     532                        return false; 
     533 
     534                $home = parse_url( get_bloginfo('site_url') ); 
     535 
     536                if ( $uri == 'localhost' || $uri == $home['host'] ) 
     537                        return false; 
     538 
     539                if ( defined('WP_ACCESSABLE_HOSTS') && is_array( WP_ACCESSABLE_HOSTS ) && in_array( $check['host'], WP_ACCESSABLE_HOSTS ) ) { 
     540                                return false; 
     541                } 
     542 
     543                return true; 
     544        } 
    633545} 
    634546 
    635547/** 
    636548 * HTTP request method uses fsockopen function to retrieve the url. 
    637549 * 
    638  * This would be the preferred method, but the fsockopen implementation has the 
    639  * most overhead of all the HTTP transport implementations. 
     550 * This would be the preferred method, but the fsockopen implementation has the most overhead of all 
     551 * the HTTP transport implementations. 
    640552 * 
    641553 * @package WordPress 
    642554 * @subpackage HTTP 
     
    696608                        $arrURL['port'] = apply_filters('http_request_port', $arrURL['port']); 
    697609                } 
    698610 
    699                 // There are issues with the HTTPS and SSL protocols that cause errors 
    700                 // that can be safely ignored and should be ignored. 
     611                // There are issues with the HTTPS and SSL protocols that cause errors that can be safely 
     612                // ignored and should be ignored. 
    701613                if ( true === $secure_transport ) 
    702614                        $error_reporting = error_reporting(0); 
    703615 
     
    710622 
    711623                $endDelay = time(); 
    712624 
    713                 // If the delay is greater than the timeout then fsockopen should't be 
    714                 // used, because it will cause a long delay. 
     625                // If the delay is greater than the timeout then fsockopen should't be used, because it will 
     626                // cause a long delay. 
    715627                $elapseDelay = ($endDelay-$startDelay) > $r['timeout']; 
    716628                if ( true === $elapseDelay ) 
    717629                        add_option( 'disable_fsockopen', $endDelay, null, true ); 
     
    719631                if ( false === $handle ) 
    720632                        return new WP_Error('http_request_failed', $iError . ': ' . $strError); 
    721633 
    722                 // WordPress supports PHP 4.3, which has this function. Removed sanity 
    723                 // checking for performance reasons. 
     634                // WordPress supports PHP 4.3, which has this function. Removed sanity checking for 
     635                // performance reasons. 
    724636                stream_set_timeout($handle, $r['timeout'] ); 
    725637 
    726638                $requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' ); 
     
    798710                if ( false !== ($option = get_option( 'disable_fsockopen' )) && time()-$option < 43200 ) // 12 hours 
    799711                        return false; 
    800712 
    801                 if ( function_exists( 'fsockopen' ) ) 
     713                if ( function_exists( 'fsockopen' ) && apply_filters('use_fsockopen_transport', true) ) 
    802714                        return true; 
    803715 
    804716                return false; 
     
    808720/** 
    809721 * HTTP request method uses fopen function to retrieve the url. 
    810722 * 
    811  * Requires PHP version greater than 4.3.0 for stream support. Does not allow 
    812  * for $context support, but should still be okay, to write the headers, before 
    813  * getting the response. Also requires that 'allow_url_fopen' to be enabled. 
     723 * Requires PHP version greater than 4.3.0 for stream support. Does not allow for $context support, 
     724 * but should still be okay, to write the headers, before getting the response. Also requires that 
     725 * 'allow_url_fopen' to be enabled. 
    814726 * 
    815727 * @package WordPress 
    816728 * @subpackage HTTP 
     
    820732        /** 
    821733         * Send a HTTP request to a URI using fopen(). 
    822734         * 
    823          * This transport does not support sending of headers and body, therefore 
    824          * should not be used in the instances, where there is a body and headers. 
     735         * This transport does not support sending of headers and body, therefore should not be used in 
     736         * the instances, where there is a body and headers. 
    825737         * 
    826738         * Notes: Does not support non-blocking mode. Ignores 'redirection' option. 
    827739         * 
     
    911823                if ( ! function_exists('fopen') || (function_exists('ini_get') && true != ini_get('allow_url_fopen')) ) 
    912824                        return false; 
    913825 
    914                 return true; 
     826                return apply_filters('use_fopen_transport', true); 
    915827        } 
    916828} 
    917829 
    918830/** 
    919831 * HTTP request method uses Streams to retrieve the url. 
    920832 * 
    921  * Requires PHP 5.0+ and uses fopen with stream context. Requires that 
    922  * 'allow_url_fopen' PHP setting to be enabled. 
     833 * Requires PHP 5.0+ and uses fopen with stream context. Requires that 'allow_url_fopen' PHP setting 
     834 * to be enabled. 
    923835 * 
    924836 * Second preferred method for getting the URL, for PHP 5. 
    925837 * 
     
    955867                        $r['user-agent'] = $r['headers']['user-agent']; 
    956868                        unset($r['headers']['user-agent']); 
    957869                } 
    958                  
     870 
    959871                // Construct Cookie: header if any cookies are set 
    960872                WP_Http::buildCookieHeader( $r ); 
    961873 
     
    984896                                'header' => $strHeaders, 
    985897                                'timeout' => $r['timeout'], 
    986898                                'ssl' => array( 
    987                                         'verify_peer' => apply_filters('https_ssl_verify', $r['sslverify']), 
    988                                         'verify_host' => apply_filters('https_ssl_verify', $r['sslverify']) 
    989                                 ) 
     899                                                'verify_peer' => apply_filters('https_ssl_verify', $r['sslverify']), 
     900                                                'verify_host' => apply_filters('https_ssl_verify', $r['sslverify']) 
     901                                ) 
    990902                        ) 
    991903                ); 
    992904 
     905                $proxy = new WP_HTTP_Proxy(); 
     906 
     907                if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { 
     908                        // WTF happens when the user stupidly puts http:// in the host? Bad things. Really, 
     909                        // really bad things happen. Not exactly unleashing demons from hell, but you know. 
     910                        // Just as bad probably. Actually, none of the other transports should work in that case 
     911                        // so no sanitization is done. If there is, it should be done in the 
     912                        // WP_HTTP_Proxy::host(). 
     913                        // 
     914                        // On second thought, why is it tcp protocol? Why not http? What if the proxy is http 
     915                        // and not tcp? Even though, technically, http is tcp, but just a specialized form of 
     916                        // tcp. Behavior is undefined, so it is probably good that not a lot of users will be 
     917                        // affected by FUBAR behavior. 
     918                        // 
     919                        // Is it another WTF? that this multiline comment isn't using multiline comment syntax? 
     920                        $arrContext['http']['proxy'] = 'tcp://'.$proxy->host().':'$proxy->port(); 
     921 
     922                        // Yeah, this may or may not work. Good luck. 
     923                        if ( $proxy->use_authentication() ) { 
     924                                $arrContext['http']['header'] .= $proxy->authentication_header() . "\r\n"; 
     925                        } 
     926                } 
     927 
    993928                if ( ! is_null($r['body']) && ! empty($r['body'] ) ) 
    994929                        $arrContext['http']['content'] = $r['body']; 
    995930 
     
    1003938                if ( ! $handle) 
    1004939                        return new WP_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); 
    1005940 
    1006                 // WordPress supports PHP 4.3, which has this function. Removed sanity 
    1007                 // checking for performance reasons. 
     941                // WordPress supports PHP 4.3, which has this function. Removed sanity checking for 
     942                // performance reasons. 
    1008943                stream_set_timeout($handle, $r['timeout'] ); 
    1009944 
    1010945                if ( ! $r['blocking'] ) { 
     
    1049984                if ( version_compare(PHP_VERSION, '5.0', '<') ) 
    1050985                        return false; 
    1051986 
    1052                 return true; 
     987                return apply_filters('use_streams_transport', true); 
    1053988        } 
    1054989} 
    1055990 
    1056991/** 
    1057992 * HTTP request method uses HTTP extension to retrieve the url. 
    1058993 * 
    1059  * Requires the HTTP extension to be installed. This would be the preferred 
    1060  * transport since it can handle a lot of the problems that forces the others to 
    1061  * use the HTTP version 1.0. Even if PHP 5.2+ is being used, it doesn't mean 
    1062  * that the HTTP extension will be enabled. 
     994 * Requires the HTTP extension to be installed. This would be the preferred transport since it can 
     995 * handle a lot of the problems that forces the others to use the HTTP version 1.0. Even if PHP 5.2+ 
     996 * is being used, it doesn't mean that the HTTP extension will be enabled. 
    1063997 * 
    1064998 * @package WordPress 
    1065999 * @subpackage HTTP 
     
    10951029                        $r['user-agent'] = $r['headers']['user-agent']; 
    10961030                        unset($r['headers']['user-agent']); 
    10971031                } 
    1098                  
     1032 
    10991033                // Construct Cookie: header if any cookies are set 
    11001034                WP_Http::buildCookieHeader( $r ); 
    11011035 
     
    11281062                        ) 
    11291063                ); 
    11301064 
     1065                // The HTTP extensions offers really easy proxy support. 
     1066                $proxy = new WP_HTTP_Proxy(); 
     1067 
     1068                if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { 
     1069                        $options['proxyhost'] = $proxy->host(); 
     1070                        $options['proxyport'] = $proxy->port(); 
     1071                        $options['proxytype'] = HTTP_PROXY_HTTP; 
     1072 
     1073                        if ( $proxy->use_authentication() ) { 
     1074                                $options['proxyauth'] = $proxy->authentication(); 
     1075                                $options['proxyauthtype'] = HTTP_AUTH_BASIC; 
     1076                        } 
     1077                } 
     1078 
    11311079                if ( !defined('WP_DEBUG') || ( defined('WP_DEBUG') && false === WP_DEBUG ) ) //Emits warning level notices for max redirects and timeouts 
    11321080                        $strResponse = @http_request($r['method'], $url, $r['body'], $options, $info); 
    11331081                else 
    11341082                        $strResponse = http_request($r['method'], $url, $r['body'], $options, $info); //Emits warning level notices for max redirects and timeouts 
    11351083 
    1136                 if ( false === $strResponse || ! empty($info['error']) ) //Error may still be set, Response may return headers or partial document, and error contains a reason the request was aborted, eg, timeout expired or max-redirects reached 
     1084                // Error may still be set, Response may return headers or partial document, and error 
     1085                // contains a reason the request was aborted, eg, timeout expired or max-redirects reached. 
     1086                if ( false === $strResponse || ! empty($info['error']) ) 
    11371087                        return new WP_Error('http_request_failed', $info['response_code'] . ': ' . $info['error']); 
    11381088 
    11391089                if ( ! $r['blocking'] ) 
     
    11681118         * @return boolean False means this class can not be used, true means it can. 
    11691119         */ 
    11701120        function test() { 
    1171                 if ( function_exists('http_request') ) 
     1121                if ( function_exists('http_request') && apply_filters('use_http_extension_transport', true) ) 
    11721122                        return true; 
    11731123 
    11741124                return false; 
     
    11851135 * @since 2.7 
    11861136 */ 
    11871137class WP_Http_Curl { 
     1138 
    11881139        /** 
    11891140         * Send a HTTP request to a URI using cURL extension. 
    11901141         * 
     
    12121163                        $r['user-agent'] = $r['headers']['user-agent']; 
    12131164                        unset($r['headers']['user-agent']); 
    12141165                } 
    1215                  
    1216                 // Construct Cookie: header if any cookies are set 
     1166 
     1167                // Construct Cookie: header if any cookies are set. 
    12171168                WP_Http::buildCookieHeader( $r ); 
    12181169 
    1219                 // cURL extension will sometimes fail when the timeout is less than 1 as 
    1220                 // it may round down to 0, which gives it unlimited timeout. 
     1170                // cURL extension will sometimes fail when the timeout is less than 1 as it may round down 
     1171                // to 0, which gives it unlimited timeout. 
    12211172                if ( $r['timeout'] > 0 && $r['timeout'] < 1 ) 
    12221173                        $r['timeout'] = 1; 
    12231174 
    12241175                $handle = curl_init(); 
    12251176 
     1177                // cURL offers really easy proxy support. 
     1178                $proxy = new WP_HTTP_Proxy(); 
     1179 
     1180                if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { 
     1181                        curl_setopt( $handle, CURLOPT_HTTPPROXYTUNNEL, true ); 
     1182 
     1183                        $isPHP5 = version_compare(PHP_VERSION, '5.0.0', '>='); 
     1184 
     1185                        if ( $isPHP5 ) { 
     1186                                curl_setopt( $handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); 
     1187                                curl_setopt( $handle, CURLOPT_PROXY, $proxy->host() ); 
     1188                                curl_setopt( $handle, CURLOPT_PROXYPORT, $proxy->port() ); 
     1189                        } else { 
     1190                                curl_setopt( $handle, CURLOPT_PROXY, $proxy->host() .':'. $proxy->port() ); 
     1191                        } 
     1192 
     1193                        if ( $proxy->use_authentication() ) { 
     1194                                if ( $isPHP5 ) 
     1195                                        curl_setopt( $handle, CURLOPT_PROXYAUTH, CURLAUTH_BASIC ); 
     1196 
     1197                                curl_setopt( $handle, CURLOPT_PROXYUSERPWD, $proxy->authentication() ); 
     1198                        } 
     1199                } 
     1200 
    12261201                curl_setopt( $handle, CURLOPT_URL, $url); 
    12271202                curl_setopt( $handle, CURLOPT_RETURNTRANSFER, true ); 
    12281203                curl_setopt( $handle, CURLOPT_SSL_VERIFYHOST, apply_filters('https_ssl_verify', $r['sslverify']) ); 
     
    12651240                else 
    12661241                        curl_setopt( $handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 ); 
    12671242 
    1268                 // Cookies are not handled by the HTTP API currently. Allow for plugin 
    1269                 // authors to handle it themselves... Although, it is somewhat pointless 
    1270                 // without some reference. 
     1243                // Cookies are not handled by the HTTP API currently. Allow for plugin authors to handle it 
     1244                // themselves... Although, it is somewhat pointless without some reference. 
    12711245                do_action_ref_array( 'http_api_curl', array(&$handle) ); 
    12721246 
    1273                 // We don't need to return the body, so don't. Just execute request 
    1274                 // and return. 
     1247                // We don't need to return the body, so don't. Just execute request and return. 
    12751248                if ( ! $r['blocking'] ) { 
    12761249                        curl_exec( $handle ); 
    12771250                        curl_close( $handle ); 
     
    13201293         * @return boolean False means this class can not be used, true means it can. 
    13211294         */ 
    13221295        function test() { 
    1323                 if ( function_exists('curl_init') && function_exists('curl_exec') ) 
     1296                if ( function_exists('curl_init') && function_exists('curl_exec') && apply_filters('use_curl_transport', true) ) 
    13241297                        return true; 
    13251298 
    13261299                return false; 
    13271300        } 
    13281301} 
    13291302 
     1303/** 
     1304 * Adds Proxy support to the WordPress HTTP API. 
     1305 * 
     1306 * Proxy support is fringe enough that it isn't support in WordPress by default, meaning no plans 
     1307 * were made to implement it. Most WordPress users are not going to benefit with its support, but 
     1308 * enough people have made a stink out of the lack of it that it should be supported. 
     1309 * 
     1310 * There are caveats to proxy support. It requires that defines be made in the wp-config.php file to 
     1311 * enable proxy support. There are also a few filters that plugins can hook into for some of the 
     1312 * constants. 
     1313 * 
     1314 * The constants are as follows: 
     1315 * <ol> 
     1316 * <li>WP_PROXY_HOST - Enable proxy support and host for connecting.</li> 
     1317 * <li>WP_PROXY_PORT - Proxy port for connection. No default, must be defined.</li> 
     1318 * <li>WP_PROXY_USERNAME - Proxy username, if it requires authentication.</li> 
     1319 * <li>WP_PROXY_PASSWORD - Proxy password, if it requires authentication.</li> 
     1320 * <li>WP_PROXY_BYPASS_HOSTS - Will prevent the hosts in this list from going through the proxy. 
     1321 * You do not need to have localhost and the blog host in this list, because they will not be passed 
     1322 * through the proxy.</li> 
     1323 * </ol> 
     1324 * 
     1325 * An example can be as seen below. 
     1326 * <code> 
     1327 * define('WP_PROXY_HOST', '192.168.84.101'); 
     1328 * define('WP_PROXY_PORT', '8080'); 
     1329 * define('WP_PROXY_BYPASS_HOSTS', array('localhost', 'www.example.com')); 
     1330 * </code> 
     1331 * 
     1332 * @link http://core.trac.wordpress.org/ticket/4011 Proxy support ticket in WordPress. 
     1333 * @since unknown 
     1334 */ 
     1335class WP_HTTP_Proxy { 
    13301336 
     1337        function WP_HTTP_Proxy() { 
     1338                $this->__construct(); 
     1339        } 
     1340 
     1341        function __construct() { 
     1342                 
     1343        } 
     1344 
     1345        /** 
     1346         * Whether proxy connection should be used. 
     1347         * 
     1348         * @since unknown 
     1349         * @use WP_PROXY_HOST 
     1350         * @use WP_PROXY_PORT 
     1351         * 
     1352         * @return bool 
     1353         */ 
     1354        function is_enabled() { 
     1355                return ( defined('WP_PROXY_HOST') && defined('WP_PROXY_PORT') ); 
     1356        } 
     1357 
     1358        /** 
     1359         * Whether authentication should be used. 
     1360         * 
     1361         * @since unknown 
     1362         * @use WP_PROXY_USERNAME 
     1363         * @use WP_PROXY_PASSWORD 
     1364         * 
     1365         * @return bool 
     1366         */ 
     1367        function use_authentication() { 
     1368                return ( defined('WP_PROXY_USERNAME') && defined('WP_PROXY_PASSWORD') ); 
     1369        } 
     1370 
     1371        /** 
     1372         * Retrieve the host for the proxy server. 
     1373         * 
     1374         * @since unknown 
     1375         * 
     1376         * @return string 
     1377         */ 
     1378        function host() 
     1379        { 
     1380                if( defined('WP_PROXY_HOST') ) 
     1381                        return WP_PROXY_HOST; 
     1382 
     1383                return ''; 
     1384        } 
     1385 
     1386        /** 
     1387         * Retrieve the port for the proxy server. 
     1388         * 
     1389         * @since unknown 
     1390         * 
     1391         * @return string 
     1392         */ 
     1393        function port() 
     1394        { 
     1395                if( defined('WP_PROXY_PORT') ) 
     1396                        return WP_PROXY_PORT; 
     1397 
     1398                return ''; 
     1399        } 
     1400 
     1401        /** 
     1402         * Retrieve the username for proxy authentication. 
     1403         * 
     1404         * @since unknown 
     1405         * 
     1406         * @return string 
     1407         */ 
     1408        function username() 
     1409        { 
     1410                if( defined('WP_PROXY_USERNAME') ) 
     1411                        return WP_PROXY_USERNAME; 
     1412 
     1413                return ''; 
     1414        } 
     1415 
     1416        /** 
     1417         * Retrieve the password for proxy authentication. 
     1418         * 
     1419         * @since unknown 
     1420         * 
     1421         * @return string 
     1422         */ 
     1423        function password() 
     1424        { 
     1425                if( defined('WP_PROXY_PASSWORD') ) 
     1426                        return WP_PROXY_PASSWORD; 
     1427 
     1428                return ''; 
     1429        } 
     1430 
     1431        /** 
     1432         * Retrieve authentication string for proxy authentication. 
     1433         * 
     1434         * @since unknown 
     1435         * 
     1436         * @return string 
     1437         */ 
     1438        function authentication() { 
     1439                return $this->username() .':'. $this->password(); 
     1440        } 
     1441 
     1442        /** 
     1443         * Retrieve header string for proxy authentication. 
     1444         * 
     1445         * @since unknown 
     1446         * 
     1447         * @return string 
     1448         */ 
     1449        function authentication_header() { 
     1450                return 'Proxy-Authentication: Basic '. base64_encode( $this->authentication() ); 
     1451        } 
     1452 
     1453        /** 
     1454         * Whether URL should be sent through the proxy server. 
     1455         * 
     1456         * We want to keep localhost and the blog URL from being sent through the proxy server, because 
     1457         * some proxies can not handle this. We also have the constant available for defining other 
     1458         * hosts that won't be sent through the proxy. 
     1459         * 
     1460         * @uses WP_PROXY_BYPASS_HOSTS 
     1461         * @since unknown 
     1462         * 
     1463         * @param string $uri URI to check. 
     1464         * @return bool True, to send through the proxy and false if, the proxy should not be used. 
     1465         */ 
     1466        function send_through_proxy( $uri ) { 
     1467                // parse_url() only handles http, https type URLs, and will emit E_WARNING on failure. 
     1468                // This will be displayed on blogs, which is not reasonable. 
     1469                $check = @parse_url($uri); 
     1470 
     1471                // Malformed URL, can not process, but this could mean ssl, so let through anyway. 
     1472                if( $check === false ) 
     1473                        return true; 
     1474 
     1475                $home = parse_url( get_bloginfo('site_url') ); 
     1476 
     1477                if ( $uri == 'localhost' || $uri == $home['host'] ) 
     1478                        return false; 
     1479 
     1480                if ( defined('WP_PROXY_BYPASS_HOSTS') && is_array( WP_PROXY_BYPASS_HOSTS ) && in_array( $check['host'], WP_PROXY_BYPASS_HOSTS ) ) { 
     1481                                return false; 
     1482                } 
     1483 
     1484                return true; 
     1485        } 
     1486} 
     1487 
     1488 
    13311489/** 
    1332  * Internal representation of a cookie. 
     1490 * Internal representation of a single cookie. 
    13331491 * 
    1334  * Returned cookies are represented using this class, and when cookies are 
    1335  * set, if they are not already a WP_Http_Cookie() object, then they are turned 
    1336  * into one. 
     1492 * Returned cookies are represented using this class, and when cookies are set, if they are not 
     1493 * already a WP_Http_Cookie() object, then they are turned into one. 
    13371494 * 
     1495 * @todo The WordPress convention is to use underscores instead of camelCase for function and method 
     1496 * names. Need to switch to use underscores instead for the methods. 
     1497 * 
    13381498 * @package WordPress 
    13391499 * @subpackage HTTP 
     1500 * @since 2.8.0 
     1501 * @author Beau Lebens 
    13401502 */ 
    13411503class WP_Http_Cookie { 
    1342         var $name, 
    1343                 $value, 
    1344                 $expires, 
    1345                 $path, 
    1346                 $domain; 
    1347          
     1504 
    13481505        /** 
    1349          * PHP4 style Constructor - Calls PHP5 Style Constructor 
     1506         * Cookie name. 
     1507         * 
     1508         * @since 2.8.0 
     1509         * @var string 
    13501510         */ 
     1511        var $name; 
     1512 
     1513        /** 
     1514         * Cookie value. 
     1515         * 
     1516         * @since 2.8.0 
     1517         * @var string 
     1518         */ 
     1519        var $value; 
     1520 
     1521        /** 
     1522         * When the cookie expires. 
     1523         * 
     1524         * @since 2.8.0 
     1525         * @var string 
     1526         */ 
     1527        var $expires; 
     1528 
     1529        /** 
     1530         * Cookie URL path. 
     1531         * 
     1532         * @since 2.8.0 
     1533         * @var string 
     1534         */ 
     1535        var $path; 
     1536 
     1537        /** 
     1538         * Cookie Domain. 
     1539         * 
     1540         * @since 2.8.0 
     1541         * @var string 
     1542         */ 
     1543        var $domain; 
     1544 
     1545        /** 
     1546         * PHP4 style Constructor - Calls PHP5 Style Constructor. 
     1547         * 
     1548         * @access public 
     1549         * @since 2.8.0 
     1550         * @param string|array $data Raw cookie data. 
     1551         */ 
    13511552        function WP_Http_Cookie( $data ) { 
    1352                 return $this->__construct( $data ); 
     1553                $this->__construct( $data ); 
    13531554        } 
    1354          
     1555 
    13551556        /** 
    13561557         * Sets up this cookie object. 
    13571558         * 
     1559         * The parameter $data should be either an associative array containing the indices names below 
     1560         * or a header string detailing it. 
     1561         * 
     1562         * If it's an array, it should include the following elements: 
     1563         * <ol> 
     1564         * <li>Name</li> 
     1565         * <li>Value - should NOT be urlencoded already.</li> 
     1566         * <li>Expires - (optional) String or int (UNIX timestamp).</li> 
     1567         * <li>Path (optional)</li> 
     1568         * <li>Domain (optional)</li> 
     1569         * </ol> 
     1570         * 
    13581571         * @access public 
     1572         * @since 2.8.0 
    13591573         * 
    1360          * @param mixed $data Either an associative array describing the cookie, or a header-string detailing it. 
    1361          *              If it's an array, it should include the following elements: 
    1362          *                      - name 
    1363          *                      - value [should NOT be urlencoded already] 
    1364          *                      - expires (optional) String or int (UNIX timestamp) 
    1365          *                      - path (optional) 
    1366          *                      - domain (optional) 
     1574         * @param string|array $data Raw cookie data. 
    13671575         */ 
    13681576        function __construct( $data ) { 
    13691577                if ( is_string( $data ) ) { 
    13701578                        // Assume it's a header string direct from a previous request 
    13711579                        $pairs = explode( ';', $data ); 
    1372                          
     1580 
    13731581                        // Special handling for first pair; name=value. Also be careful of "=" in value 
    13741582                        $name  = trim( substr( $pairs[0], 0, strpos( $pairs[0], '=' ) ) ); 
    13751583                        $value = substr( $pairs[0], strpos( $pairs[0], '=' ) + 1 ); 
    13761584                        $this->name  = $name; 
    13771585                        $this->value = urldecode( $value ); 
    13781586                        array_shift( $pairs ); //Removes name=value from items. 
    1379                          
     1587 
    13801588                        // Set everything else as a property 
    13811589                        foreach ( $pairs as $pair ) { 
    13821590                                if ( empty($pair) ) //Handles the cookie ending in ; which results in a empty final pair 
    13831591                                        continue; 
     1592 
    13841593                                list( $key, $val ) = explode( '=', $pair ); 
    13851594                                $key = strtolower( trim( $key ) ); 
    13861595                                if ( 'expires' == $key ) 
     
    13901599                } else { 
    13911600                        if ( !isset( $data['name'] ) ) 
    13921601                                return false; 
    1393                          
     1602 
    13941603                        // Set properties based directly on parameters 
    13951604                        $this->name   = $data['name']; 
    13961605                        $this->value  = isset( $data['value'] ) ? $data['value'] : ''; 
    13971606                        $this->path   = isset( $data['path'] ) ? $data['path'] : ''; 
    13981607                        $this->domain = isset( $data['domain'] ) ? $data['domain'] : ''; 
     1608 
    13991609                        if ( isset( $data['expires'] ) ) 
    14001610                                $this->expires = is_int( $data['expires'] ) ? $data['expires'] : strtotime( $data['expires'] ); 
    14011611                        else 
    14021612                                $this->expires = null; 
    14031613                } 
    14041614        } 
    1405          
     1615 
    14061616        /** 
    14071617         * Confirms that it's OK to send this cookie to the URL checked against. 
    14081618         *  
    14091619         * Decision is based on RFC 2109/2965, so look there for details on validity. 
    14101620         * 
    14111621         * @access public 
     1622         * @since 2.8.0 
    14121623         * 
    14131624         * @param string $url URL you intend to send this cookie to 
    14141625         * @return boolean TRUE if allowed, FALSE otherwise. 
     
    14171628                // Expires - if expired then nothing else matters 
    14181629                if ( time() > $this->expires ) 
    14191630                        return false; 
    1420                  
     1631 
    14211632                // Get details on the URL we're thinking about sending to 
    14221633                $url = parse_url( $url ); 
    14231634                $url['port'] = isset( $url['port'] ) ? $url['port'] : 80; 
    14241635                $url['path'] = isset( $url['path'] ) ? $url['path'] : '/'; 
    1425                  
    1426                  // Values to use for comparison against the URL 
     1636 
     1637                // Values to use for comparison against the URL 
    14271638                $path   = isset( $this->path )   ? $this->path   : '/'; 
    14281639                $port   = isset( $this->port )   ? $this->port   : 80; 
    14291640                $domain = isset( $this->domain ) ? strtolower( $this->domain ) : strtolower( $url['host'] ); 
    14301641                if ( false === stripos( $domain, '.' ) ) 
    14311642                        $domain .= '.local'; 
    1432                  
     1643 
    14331644                // Host - very basic check that the request URL ends with the domain restriction (minus leading dot) 
    14341645                $domain = substr( $domain, 0, 1 ) == '.' ? substr( $domain, 1 ) : $domain; 
    14351646                if ( substr( $url['host'], -strlen( $domain ) ) != $domain ) 
    14361647                        return false; 
    1437                  
     1648 
    14381649                // Port - supports "port-lists" in the format: "80,8000,8080" 
    14391650                if ( !in_array( $url['port'], explode( ',', $port) ) ) 
    14401651                        return false; 
    1441                  
     1652 
    14421653                // Path - request path must start with path restriction 
    14431654                if ( substr( $url['path'], 0, strlen( $path ) ) != $path ) 
    14441655                        return false; 
    1445                  
     1656 
    14461657                return true; 
    14471658        } 
    1448          
     1659 
     1660        /** 
     1661         * Convert cookie name and value back to header string. 
     1662         * 
     1663         * @access public 
     1664         * @since 2.8.0 
     1665         * 
     1666         * @return string Header encoded cookie name and value. 
     1667         */ 
    14491668        function getHeaderValue() { 
    14501669                if ( empty( $this->name ) || empty( $this->value ) ) 
    14511670                        return ''; 
    14521671                 
    14531672                return $this->name . '=' . urlencode( $this->value ); 
    14541673        } 
    1455          
     1674 
     1675        /** 
     1676         * Retrieve cookie header for usage in the rest of the WordPress HTTP API. 
     1677         * 
     1678         * @access public 
     1679         * @since 2.8.0 
     1680         * 
     1681         * @return string 
     1682         */ 
    14561683        function getFullHeader() { 
    14571684                return 'Cookie: ' . $this->getHeaderValue(); 
    14581685        } 
    14591686} 
    14601687 
    14611688/** 
     1689 * Implementation for deflate and gzip transfer encodings. 
     1690 * 
     1691 * Includes RFC 1950, RFC 1951, and RFC 1952. 
     1692 * 
     1693 * @since 2.8 
     1694 * @package WordPress 
     1695 * @subpackage HTTP 
     1696 */ 
     1697class WP_Http_Encoding { 
     1698 
     1699        /** 
     1700         * Compress raw string using the deflate format. 
     1701         * 
     1702         * Supports the RFC 1951 standard. 
     1703         * 
     1704         * @since 2.8 
     1705         * 
     1706         * @param string $raw String to compress. 
     1707         * @param int $level Optional, default is 9. Compression level, 9 is highest. 
     1708         * @param string $supports Optional, not used. When implemented it will choose the right compression based on what the server supports. 
     1709         * @return string|bool False on failure. 
     1710         */ 
     1711        function compress( $raw, $level = 9, $supports = null ) { 
     1712                return gzdeflate( $raw, $level ); 
     1713        } 
     1714 
     1715        /** 
     1716         * Decompression of deflated string. 
     1717         * 
     1718         * Will attempt to decompress using the RFC 1950 standard, and if that fails 
     1719         * then the RFC 1951 standard deflate will be attempted. Finally, the RFC 
     1720         * 1952 standard gzip decode will be attempted. If all fail, then the 
     1721         * original compressed string will be returned. 
     1722         * 
     1723         * @since 2.8 
     1724         * 
     1725         * @param string $compressed String to decompress. 
     1726         * @param int $length The optional length of the compressed data. 
     1727         * @return string|bool False on failure. 
     1728         */ 
     1729        function decompress( $compressed, $length = null ) { 
     1730                $decompressed = gzinflate( $compressed ); 
     1731 
     1732                if( false !== $decompressed ) 
     1733                        return $decompressed; 
     1734 
     1735                $decompressed = gzuncompress( $compressed ); 
     1736 
     1737                if( false !== $decompressed ) 
     1738                        return $decompressed; 
     1739 
     1740                $decompressed = gzdecode( $compressed ); 
     1741 
     1742                if( false !== $decompressed ) 
     1743                        return $decompressed; 
     1744 
     1745                return $compressed; 
     1746        } 
     1747 
     1748        /** 
     1749         * What encoding types to accept and their priority values. 
     1750         * 
     1751         * @since 2.8 
     1752         * 
     1753         * @return string Types of encoding to accept. 
     1754         */ 
     1755        function accept_encoding() { 
     1756                $type = array(); 
     1757                if( function_exists( 'gzinflate' ) ) 
     1758                        $type[] = 'deflate;q=1.0'; 
     1759 
     1760                if( function_exists( 'gzuncompress' ) ) 
     1761                        $type[] = 'compress;q=0.5'; 
     1762 
     1763                if( function_exists( 'gzdecode' ) ) 
     1764                        $type[] = 'gzip;q=0.5'; 
     1765 
     1766                return implode(', ', $type); 
     1767        } 
     1768 
     1769        /** 
     1770         * What enconding the content used when it was compressed to send in the headers. 
     1771         * 
     1772         * @since 2.8 
     1773         * 
     1774         * @return string Content-Encoding string to send in the header. 
     1775         */ 
     1776        function content_encoding() { 
     1777                return 'deflate'; 
     1778        } 
     1779 
     1780        /** 
     1781         * Whether the content be decoded based on the headers. 
     1782         * 
     1783         * @since 2.8 
     1784         * 
     1785         * @param array|string $headers All of the available headers. 
     1786         * @return bool 
     1787         */ 
     1788        function should_decode($headers) { 
     1789                if( is_array( $headers ) ) { 
     1790                        if( array_key_exists('content-encoding', $headers) && ! empty( $headers['content-encoding'] ) ) 
     1791                                return true; 
     1792                } else if( is_string( $headers ) ) { 
     1793                        return ( stripos($headers, 'content-encoding:') !== false ); 
     1794                } 
     1795 
     1796                return false; 
     1797        } 
     1798 
     1799        /** 
     1800         * Whether decompression and compression are supported by the PHP version. 
     1801         * 
     1802         * Each function is tested instead of checking for the zlib extension, to 
     1803         * ensure that the functions all exist in the PHP version and aren't 
     1804         * disabled. 
     1805         * 
     1806         * @since 2.8 
     1807         * 
     1808         * @return bool 
     1809         */ 
     1810        function is_available() { 
     1811                return ( function_exists('gzuncompress') || function_exists('gzdeflate') || 
     1812                                 function_exists('gzinflate') ); 
     1813        } 
     1814} 
     1815 
     1816/** 
    14621817 * Returns the initialized WP_Http Object 
    14631818 * 
    14641819 * @since 2.7.0