From a65354225e5482866f78ffa8002fcb0b76fa8857 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 29 Dec 2014 21:07:46 -0500 Subject: [PATCH] Don't set content-length when serving assets. Setting content-length on assets causes long pauses when fetching assets that contain PHP code. These assets are invariably larger than their response bodies. By not setting a content-length, we can allow the webserver to calculate it for us. Refs #4916 --- lib/Cake/Routing/Filter/AssetDispatcher.php | 5 ++- .../Routing/Filter/AssetDispatcherTest.php | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Routing/Filter/AssetDispatcher.php b/lib/Cake/Routing/Filter/AssetDispatcher.php index 8778d25fd..3a4908bcf 100644 --- a/lib/Cake/Routing/Filter/AssetDispatcher.php +++ b/lib/Cake/Routing/Filter/AssetDispatcher.php @@ -149,12 +149,11 @@ class AssetDispatcher extends DispatcherFilter { } $response->type($contentType); } - if (!$compressionEnabled) { - $response->header('Content-Length', filesize($assetFile)); - } + $response->length(false); $response->cache(filemtime($assetFile)); $response->send(); ob_clean(); + if ($ext === 'css' || $ext === 'js') { include $assetFile; } else { diff --git a/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php b/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php index 638700535..e9e5b5ddd 100644 --- a/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php +++ b/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php @@ -228,4 +228,39 @@ class AssetDispatcherTest extends CakeTestCase { $this->assertFalse($event->isStopped()); } +/** + * Test asset content length is unset + * + * If content length is unset, then the webserver can figure it out. + * + * @outputBuffering enabled + * @return void + */ + public function testAssetContentLength() { + Router::reload(); + Configure::write('Dispatcher.filters', array('AssetDispatcher')); + App::build(array( + 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS) + )); + + $url = 'theme/test_theme/css/test_asset.css'; + $file = 'View/Themed/TestTheme/webroot/css/test_asset.css'; + + $request = new CakeRequest($url); + $response = $this->getMock('CakeResponse', array('_sendHeader', 'send')); + $event = new CakeEvent('Dispatcher.beforeRequest', $this, compact('request', 'response')); + + $filter = new AssetDispatcher(); + $filter->beforeDispatch($event); + $result = ob_get_clean(); + + $path = CAKE . 'Test' . DS . 'test_app' . DS . str_replace('/', DS, $file); + $file = file_get_contents($path); + $this->assertEquals($file, $result); + + $expected = filesize($path); + $headers = $response->header(); + $this->assertFalse($headers['Content-Length']); + } + }