Changeset 952

Show
Ignore:
Timestamp:
07/25/08 04:21:51 (2 months ago)
Author:
arnoschn
Message:

#52: adding gzip encoding support to the pagecaching. Supports the alias x-gzip.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/arnoschn/cache/lib/AkActionController/AkCacheHandler.php

    r899 r952  
    195195        $cacheId = $this->_buildCacheId($path, $language); 
    196196        $cacheGroup = $this->_buildCacheGroup(); 
    197         return $this->_cache_store->remove($cacheId,$cacheGroup); 
    198     } 
    199     function cachePage($content, $path = null, $language = null) 
     197        $notGzippedRes=$this->_cache_store->remove($cacheId,$cacheGroup); 
     198        $gZippedCacheId = $this->_scopeWithGzip($cacheId); 
     199        $gzippedRes=$this->_cache_store->remove($gZippedCacheId,$cacheGroup); 
     200        return ($notGzippedRes || $gzippedRes); 
     201    } 
     202    function cachePage($content, $path = null, $language = null, $gzipped=false) 
    200203    { 
    201204        if (!($this->_cachingAllowed() && $this->_perform_caching)) return; 
    202205         
    203206        $cacheId = $this->_buildCacheId($path, $language); 
     207        if ($gzipped) { 
     208            $cacheId = $this->_scopeWithGzip($cacheId); 
     209        } 
    204210        $cacheGroup = $this->_buildCacheGroup(); 
    205211        $content = $this->_modifyCacheContent($content); 
     
    209215    function _modifyCacheContent($content) 
    210216    { 
     217         
    211218        $headers = $this->_controller->Response->_headers_sent; 
    212219        $headerString = serialize($headers); 
     
    277284        return true; 
    278285    } 
    279      
     286 
     287    function _scopeWithGzip($cacheId) 
     288    { 
     289        $cacheId = 'gzip' . DS . $cacheId; 
     290        return $cacheId; 
     291    } 
    280292    function afterPageCache() 
    281293    { 
    282         $this->_controller->handleResponse(); 
    283         $contents = ob_get_flush(); 
    284          
    285         $this->cachePage($contents); 
     294        $encodings = $this->_getAcceptedEncodings(); 
     295        $xgzip = false; 
     296        $gzip = false; 
     297        if (($gzip=in_array('gzip',$encodings)) || ($xgzip=in_array('x-gzip',$encodings))) { 
     298            $this->_controller->Response->addHeader('Content-Encoding',$xgzip?'x-gzip':'gzip'); 
     299            $gzip = $gzip || $xgzip; 
     300            $this->_controller->handleResponse(); 
     301            $contents = ob_get_flush(); 
     302            /** 
     303             *  Caching unzipped content 
     304             */ 
     305            $this->cachePage($contents,null,null,false); 
     306            $contents = $this->_gzipCache($contents); 
     307        } else { 
     308            $this->_controller->handleResponse(); 
     309            $contents = ob_get_flush(); 
     310            /** 
     311             *  Caching gzipped content 
     312             */ 
     313            $gzippedContents = $this->_gzipCache($contents); 
     314            $this->cachePage($gzippedContents,null,null,true); 
     315        } 
     316        $this->cachePage($contents,null,null,$gzip); 
    286317        return true; 
    287          
     318    } 
     319     
     320    function _gzipCache($cache) 
     321    { 
     322        $pre ='\x1f\x8b\x08\x00\x00\x00\x00\x00'; 
     323        $size = strlen($cache); 
     324        $gzipped = gzcompress($cache, 9); 
     325        $gzipped = substr($gzipped, 0, $size); 
     326        $gzipped = $pre.$gzipped; 
     327        return $gzipped; 
    288328    } 
    289329     
     
    320360        return $this->_lastCacheId; 
    321361    } 
    322      
     362    function _getAcceptedEncodings() 
     363    { 
     364        $encodings = isset($_SERVER['HTTP_ACCEPT_ENCODING'])?$_SERVER['HTTP_ACCEPT_ENCODING']:''; 
     365        $encodings = preg_split('/\s*,\s*/',$encodings); 
     366        return $encodings; 
     367    } 
    323368    function &getCachedPage($path = null,$forcedLanguage = null) 
    324369    { 
     
    331376            } 
    332377            $cacheId = $this->_buildCacheId($path, $forcedLanguage); 
     378            $encodings = $this->_getAcceptedEncodings(); 
     379            if (($gzip=in_array('gzip',$encodings)) || ($xgzip=in_array('x-gzip',$encodings))) { 
     380                $cacheId = $this->_scopeWithGzip($cacheId); 
     381            } 
    333382            $cacheGroup = $this->_buildCacheGroup(); 
    334383            $cache = $this->_cache_store->get($cacheId, $cacheGroup); 
     
    577626    function _addExtension($path, $extension) 
    578627    { 
    579         if (!empty($extension)) { 
     628        if (!empty($extension) && substr($path,-strlen($extension))!==$extension) { 
    580629            $path = $path.'.'.$extension; 
    581630        } 
     
    622671    } 
    623672     
    624      
    625673    /** 
    626674     * @access protected 
  • branches/arnoschn/cache/lib/AkCache/AkCachedPage.php

    r849 r952  
    66    var $_headerSeparator; 
    77    var $_options; 
     8    var $_encodingAliases = array('gzip','x-gzip', 'compress', 'x-compress'); 
    89    function __construct(&$contents, $header_separator, $options = array()) 
    910    { 
     
    7172        $headers = @unserialize($headersSerialized); 
    7273        $headers = !is_array($headers)?array():$headers; 
     74        $acceptedEncodings = $this->_getAcceptedEncodings(); 
    7375        if ($sendHeaders) { 
    7476            foreach ($headers as $header) { 
    75                 header($header); 
     77                 
     78                header($this->_handleEncodingAliases($header, $acceptedEncodings)); 
    7679            } 
    7780             
     
    8689        } 
    8790        $exit?exit:null; 
     91    } 
     92    function _handleEncodingAliases($header, $acceptedEncodings) 
     93    { 
     94        $parts = split(': ',$header); 
     95        if (strtolower($parts[0])=='content-encoding' &&  
     96            isset($parts[1]) && 
     97            in_array($parts[1],$this->_encodingAliases)) { 
     98            $acceptedEncodings = array_intersect($acceptedEncodings,$this->_encodingAliases); 
     99            if (isset($acceptedEncodings[0])) { 
     100                $header =$parts[0].': '.$acceptedEncodings[0]; 
     101            } 
     102        } 
     103        return $header; 
     104    } 
     105    function _getAcceptedEncodings() 
     106    { 
     107        $encodings = isset($_SERVER['HTTP_ACCEPT_ENCODING'])?$_SERVER['HTTP_ACCEPT_ENCODING']:''; 
     108        $encodings = preg_split('/\s*,\s*/',$encodings); 
     109        return $encodings; 
    88110    } 
    89111     
  • branches/arnoschn/cache/lib/AkRequest.php

    r902 r952  
    696696        if (preg_match('/^([^\.]+)\.(.+)$/', @$_REQUEST['ak'], $matches)) { 
    697697            $this->_format = isset($matches[2])?$matches[2]:null; 
    698             $_REQUEST['ak'] = $matches[1]; 
    699             $this->_request['ak'] = $matches[1]; 
     698            $_REQUEST['ak'] = $matches[0]; 
     699            $this->_request['ak'] = $matches[0]; 
    700700        } 
    701701    } 
  • branches/arnoschn/cache/lib/AkUnitTest/AkTestApplication.php

    r899 r952  
    9898        $_SERVER['HTTP_X_REQUESTED_WITH']='xmlhttprequest'; 
    9999    } 
     100    function setAcceptEncoding($encoding) 
     101    { 
     102        $_SERVER['HTTP_ACCEPT_ENCODING']=$encoding; 
     103    } 
    100104    function &getHeader($name) 
    101105    { 
     
    123127        $_REQUEST = array(); 
    124128        $_POST = array(); 
     129         
    125130    } 
    126131     
     
    129134        $this->_reset(); 
    130135        $this->_response = null; 
     136        $this->_cacheHeaders = array(); 
    131137        $this->_setConstants($constants); 
    132138        $parts = parse_url($url); 
     
    165171            $res=true; 
    166172        } 
    167         return $res; 
     173        $this->_cleanUp(); 
     174        return $res; 
     175    } 
     176    function _cleanUp() 
     177    { 
     178        unset($_SERVER['HTTP_IF_MODIFIED_SINCE']); 
     179        unset($_SERVER['HTTP_X_REQUESTED_WITH']); 
     180        unset($_SERVER['HTTP_ACCEPT_ENCODING']); 
    168181    } 
    169182    function post($url, $data = null, $constants = array(), $controllerVars = array()) 
  • branches/arnoschn/cache/test/unit/lib/AkActionController/_page_caching.php

    r897 r952  
    3333        $this->assertText('/^\s*$/'); 
    3434        $this->assertResponse(200); 
    35         $this->_assertPageCached('/page_caching/ok'); 
     35        $this->assertTrue($this->_assertPageCached('/page_caching/ok')); 
    3636         
    3737         
    3838    } 
     39    function test_should_cache_get_with_ok_status_gzipped_and_unzipped() 
     40    { 
     41        $this->_flushCache('www.example.com'); 
     42         
     43        $this->assertTrue($this->_assertPageNotCached('/page_caching/ok')); 
     44        $this->setAcceptEncoding('gzip'); 
     45        $this->assertTrue($this->_assertPageNotCached('/page_caching/ok')); 
     46        $this->setAcceptEncoding(''); 
     47         
     48        $this->setIp('212.121.121.121'); 
     49        $this->get('http://www.example.com/page_caching/ok'); 
     50        $this->assertFalse($this->getHeader('Content-Encoding')); 
     51        $this->assertResponse(200); 
     52        $this->assertTrue($this->_assertPageCached('/page_caching/ok')); 
     53        $this->setAcceptEncoding('gzip'); 
     54        $this->assertTrue($this->_assertPageCached('/page_caching/ok')); 
     55    } 
     56     
     57    function test_should_cache_get_with_ok_status_gzipped() 
     58    { 
     59        $this->_flushCache('www.example.com'); 
     60        $this->setIp('212.121.121.121'); 
     61        $this->setAcceptEncoding('gzip'); 
     62        $this->get('http://www.example.com/page_caching/ok'); 
     63        $this->assertHeader('Content-Encoding','gzip'); 
     64        $this->assertResponse(200); 
     65        $this->assertTrue($this->_assertPageCached('/page_caching/ok')); 
     66        $this->setAcceptEncoding('gzip'); 
     67        $this->assertTrue($this->_assertPageCached('/page_caching/ok')); 
     68         
     69    } 
     70     
     71    function test_should_cache_get_with_ok_status_xgzipped() 
     72    { 
     73        $this->_flushCache('www.example.com'); 
     74        $this->setIp('212.121.121.121'); 
     75        $this->setAcceptEncoding('x-gzip'); 
     76        $this->get('http://www.example.com/page_caching/ok'); 
     77        $this->assertHeader('Content-Encoding','x-gzip'); 
     78        $this->assertResponse(200); 
     79        $this->assertTrue($this->_assertPageCached('/page_caching/ok')); 
     80        $this->setAcceptEncoding('gzip'); 
     81        $this->assertTrue($this->_assertPageCached('/page_caching/ok')); 
     82         
     83    } 
     84     
    3985    function _getCachedPage($path) 
    4086    { 
     
    5096        return $cachedPage; 
    5197    } 
     98     
    5299    function _assertPageCached($path, $message = false) 
    53100    { 
     
    55102        $this->assertTrue($cachedPage!=false,$message); 
    56103        $this->assertIsA($cachedPage,'AkCachedPage'); 
     104        return $cachedPage!=false && is_a($cachedPage,'AkCachedPage'); 
    57105    } 
    58106    function _assertPageNotCached($path, $message = '%s') 
     
    60108        $cachedPage = $this->_getCachedPage($path); 
    61109        $this->assertTrue($cachedPage==false,$message); 
     110        return $cachedPage==false; 
    62111    } 
    63112    function test_last_modified() 
     
    85134        $this->get('http://www.example.com/page_caching/custom_path'); 
    86135        $this->assertText('Akelos rulez'); 
    87         $this->_assertPageCached('/index.html'); 
     136        $this->assertTrue($this->_assertPageCached('/index.html')); 
    88137    } 
    89138     
     
    91140    { 
    92141        $this->get('http://www.example.com/page_caching/custom_path'); 
    93         $this->_assertPageCached('/index.html'); 
     142        $this->assertTrue($this->_assertPageCached('/index.html')); 
    94143         
    95144        $this->get('http://www.example.com/page_caching/expire_custom_path'); 
    96         $this->_assertPageNotCached('/index.html'); 
     145        $this->assertTrue($this->_assertPageNotCached('/index.html')); 
    97146    } 
    98147     
     
    101150        $controller=$this->getController(); 
    102151        $controller->cachePage('cached content', '/page_caching_test/trailing_slash'); 
    103         $this->_assertPageCached('/page_caching_test/trailing_slash.html'); 
     152        $this->assertTrue($this->_assertPageCached('/page_caching_test/trailing_slash.html')); 
    104153    } 
    105154     
     
    108157        $controller=$this->getController(); 
    109158        $controller->cachePage('cached content', '/page_caching_test/trailing_slash/'); 
    110         $this->_assertPageCached('/page_caching_test/trailing_slash.html'); 
     159        $this->assertTrue($this->_assertPageCached('/page_caching_test/trailing_slash.html')); 
    111160    } 
    112161     
     
    120169                $this->$method($path); 
    121170                if ($this->getHeader('Status') == 200 && $method=='get') { 
    122                     $this->_assertPageCached($path, 'action ok with GET request should be cached'); 
     171                    $this->assertTrue($this->_assertPageCached($path, 'action ok with GET request should be cached')); 
    123172                } else { 
    124                     $this->_assertPageNotCached($path,' action '.$action.' with '.strtoupper($method).' should not be cached'); 
     173                    $this->assertTrue($this->_assertPageNotCached($path,' action '.$action.' with '.strtoupper($method).' should not be cached')); 
    125174                } 
    126175            }