Browse Source

Don't 404 extensions that could be handled by routing.

Fixes an error in #2750 where routed extensions would always return
404's for plugin requests. When a file extenion could be handled by
router, AssetDispatcher cannot 404 the request.

Refs #3305
mark_story 12 years ago
parent
commit
749f2b99d9

+ 8 - 3
lib/Cake/Routing/Filter/AssetDispatcher.php

@@ -55,10 +55,17 @@ class AssetDispatcher extends DispatcherFilter {
 			return null;
 		}
 
+		$pathSegments = explode('.', $url);
+		$ext = array_pop($pathSegments);
+		$isFile = file_exists($assetFile);
+		if (in_array($ext, Router::extensions()) && !$isFile) {
+			return null;
+		}
+
 		$response = $event->data['response'];
 		$event->stopPropagation();
 
-		if (!file_exists($assetFile)) {
+		if (!$isFile) {
 			$response->statusCode(404);
 			$response->send();
 			return $response;
@@ -69,8 +76,6 @@ class AssetDispatcher extends DispatcherFilter {
 			return $response;
 		}
 
-		$pathSegments = explode('.', $url);
-		$ext = array_pop($pathSegments);
 		$this->_deliverAsset($response, $assetFile, $ext);
 		return $response;
 	}

+ 32 - 0
lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php

@@ -84,6 +84,38 @@ class AssetDispatcherTest extends CakeTestCase {
 	}
 
 /**
+ * AssetDispatcher should not 404 extensions that could be handled
+ * by Routing.
+ *
+ * @return void
+ */
+	public function testNoHandleRoutedExtension() {
+		$filter = new AssetDispatcher();
+		$response = $this->getMock('CakeResponse', array('_sendHeader'));
+		Configure::write('Asset.filter', array(
+			'js' => '',
+			'css' => ''
+		));
+		App::build(array(
+			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+		), App::RESET);
+		Router::parseExtensions('json');
+		Router::connect('/test_plugin/api/v1/:action', array('controller' => 'api'));
+		CakePlugin::load('TestPlugin');
+
+		$request = new CakeRequest('test_plugin/api/v1/forwarding.json');
+		$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+		$this->assertNull($filter->beforeDispatch($event));
+		$this->assertFalse($event->isStopped(), 'Events for routed extensions should not be stopped');
+
+		$request = new CakeRequest('test_plugin/api/v1/forwarding.png');
+		$event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+		$this->assertSame($response, $filter->beforeDispatch($event));
+		$this->assertTrue($event->isStopped());
+	}
+
+/**
  * Tests that $response->checkNotModified() is called and bypasses
  * file dispatching
  *