Make WordPress Core


Ignore:
Timestamp:
01/22/2009 09:16:11 PM (16 years ago)
Author:
westi
Message:

First pass compression support for the HTTP API. See #8674 props jacobsantos.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/http.php

    r10359 r10410  
    1212 * @author Jacob Santos <wordpress@santosj.name>
    1313 */
     14
     15/**
     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}
    14142
    15143/**
     
    233361            'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version ),
    234362            'blocking' => true,
    235             'headers' => array(), 'body' => null
     363            'headers' => array(),
     364            'body' => null,
     365            'compress' => false,
     366            'decompress' => true
    236367        );
    237368
     
    256387            unset($r['headers']['user-agent']);
    257388        }
     389
     390        if( WP_Http_Encoding::is_available() )
     391            $r['headers']['Accept-Encoding'] = WP_Http_Encoding::accept_encoding();
    258392
    259393        if ( is_null($r['body']) ) {
     
    596730            $process['body'] = WP_Http::chunkTransferDecode($process['body']);
    597731
     732        if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders) )
     733            $process['body'] = WP_Http_Encoding::decompress( $process['body'] );
     734
    598735        return array('headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response']);
    599736    }
     
    706843            $strResponse = WP_Http::chunkTransferDecode($strResponse);
    707844
     845        if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders) )
     846            $strResponse = WP_Http_Encoding::decompress( $strResponse );
     847
    708848        return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response']);
    709849    }
     
    818958        $meta = stream_get_meta_data($handle);
    819959
     960        fclose($handle);
     961
    820962        $processedHeaders = array();
    821963        if( isset( $meta['wrapper_data']['headers'] ) )
     
    827969            $strResponse = WP_Http::chunkTransferDecode($strResponse);
    828970
    829         fclose($handle);
     971        if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders) )
     972            $strResponse = WP_Http_Encoding::decompress( $strResponse );
    830973
    831974        return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response']);
     
    9401083                $theBody = http_chunked_decode($theBody);
    9411084        }
     1085
     1086        if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders) )
     1087            $theBody = http_inflate( $theBody );
    9421088
    9431089        $theResponse = array();
     
    10751221            $theBody = '';
    10761222        }
     1223
    10771224        $response = array();
    10781225        $response['code'] = curl_getinfo( $handle, CURLINFO_HTTP_CODE );
     
    10811228        curl_close( $handle );
    10821229
     1230        if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders) )
     1231            $theBody = WP_Http_Encoding::decompress( $theBody );
     1232
    10831233        return array('headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response);
    10841234    }
Note: See TracChangeset for help on using the changeset viewer.