WordPress.org

Make WordPress Core

Ticket #8674: 8674.2.diff

File 8674.2.diff, 7.1 KB (added by jacobsantos, 7 years ago)

Better and complete implementation of gzip.

  • 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 */ 
     24class 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/** 
    16144 * WordPress HTTP Class for managing HTTP Transports and making HTTP requests. 
    17145 * 
    18146 * This class is called for the functionality of making HTTP requests and should 
     
    217345                        'httpversion' => apply_filters( 'http_request_version', '1.0'), 
    218346                        'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version ), 
    219347                        'blocking' => true, 
    220                         'headers' => array(), 'body' => null 
     348                        'headers' => array(), 
     349                        'body' => null, 
     350                        'compress' => false, 
     351                        'decompress' = true 
    221352                ); 
    222353 
    223354                $r = wp_parse_args( $args, $defaults ); 
     
    241372                        unset($r['headers']['user-agent']); 
    242373                } 
    243374 
     375                if( WP_Http_Encoding::is_available() ) 
     376                        $r['headers']['Accept-Encoding'] = WP_Http_Encoding::accept_encoding(); 
     377 
    244378                if ( is_null($r['body']) ) { 
    245379                        $r['headers']['Content-Length'] = 0; 
    246380                        $transports = WP_Http::_getTransport($r); 
     
    578712                if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] ) 
    579713                        $process['body'] = WP_Http::chunkTransferDecode($process['body']); 
    580714 
     715                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders) ) 
     716                        $process['body'] = WP_Http_Encoding::decompress( $process['body'] ); 
     717 
    581718                return array('headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response']); 
    582719        } 
    583720 
     
    688825                if ( ! empty( $strResponse ) && isset( $processedHeaders['headers']['transfer-encoding'] ) && 'chunked' == $processedHeaders['headers']['transfer-encoding'] ) 
    689826                        $strResponse = WP_Http::chunkTransferDecode($strResponse); 
    690827 
     828                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders) ) 
     829                        $strResponse = WP_Http_Encoding::decompress( $strResponse ); 
     830 
    691831                return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response']); 
    692832        } 
    693833 
     
    799939                $strResponse = stream_get_contents($handle); 
    800940                $meta = stream_get_meta_data($handle); 
    801941 
     942                fclose($handle); 
     943 
    802944                $processedHeaders = array(); 
    803945                if( isset( $meta['wrapper_data']['headers'] ) ) 
    804946                        $processedHeaders = WP_Http::processHeaders($meta['wrapper_data']['headers']); 
     
    808950                if ( ! empty( $strResponse ) && isset( $processedHeaders['headers']['transfer-encoding'] ) && 'chunked' == $processedHeaders['headers']['transfer-encoding'] ) 
    809951                        $strResponse = WP_Http::chunkTransferDecode($strResponse); 
    810952 
    811                 fclose($handle); 
     953                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders) ) 
     954                        $strResponse = WP_Http_Encoding::decompress( $strResponse ); 
    812955 
    813956                return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response']); 
    814957        } 
     
    9221065                                $theBody = http_chunked_decode($theBody); 
    9231066                } 
    9241067 
     1068                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders) ) 
     1069                        $theBody = http_inflate( $theBody ); 
     1070 
    9251071                $theResponse = array(); 
    9261072                $theResponse['code'] = $info['response_code']; 
    9271073                $theResponse['message'] = get_status_header_desc($info['response_code']); 
     
    10451191                        $theHeaders = array( 'headers' => array() ); 
    10461192                        $theBody = ''; 
    10471193                } 
     1194 
    10481195                $response = array(); 
    10491196                $response['code'] = curl_getinfo( $handle, CURLINFO_HTTP_CODE ); 
    10501197                $response['message'] = get_status_header_desc($response['code']); 
    10511198 
    10521199                curl_close( $handle ); 
    10531200 
     1201                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders) ) 
     1202                        $theBody = WP_Http_Encoding::decompress( $theBody ); 
     1203 
    10541204                return array('headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response); 
    10551205        } 
    10561206