| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- <?php
- /**
- * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- * @link http://cakephp.org CakePHP(tm) Project
- * @since 2.2.0
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\Routing\Filter;
- use Cake\Core\Plugin;
- use Cake\Event\Event;
- use Cake\Network\Request;
- use Cake\Network\Response;
- use Cake\Routing\DispatcherFilter;
- use Cake\Utility\Inflector;
- /**
- * Filters a request and tests whether it is a file in the webroot folder or not and
- * serves the file to the client if appropriate.
- *
- */
- class AssetFilter extends DispatcherFilter {
- /**
- * Default priority for all methods in this filter
- * This filter should run before the request gets parsed by router
- *
- * @var int
- */
- protected $_priority = 9;
- /**
- * Checks if a requested asset exists and sends it to the browser
- *
- * @param \Cake\Event\Event $event containing the request and response object
- * @return \Cake\Network\Response if the client is requesting a recognized asset, null otherwise
- * @throws NotFoundException When asset not found
- */
- public function beforeDispatch(Event $event) {
- $request = $event->data['request'];
- $url = urldecode($request->url);
- if (strpos($url, '..') !== false || strpos($url, '.') === false) {
- return;
- }
- $assetFile = $this->_getAssetFile($url);
- if ($assetFile === null || !file_exists($assetFile)) {
- return null;
- }
- $response = $event->data['response'];
- $event->stopPropagation();
- $response->modified(filemtime($assetFile));
- if ($response->checkNotModified($request)) {
- return $response;
- }
- $pathSegments = explode('.', $url);
- $ext = array_pop($pathSegments);
- $this->_deliverAsset($request, $response, $assetFile, $ext);
- return $response;
- }
- /**
- * Builds asset file path based off url
- *
- * @param string $url Asset URL
- * @return string Absolute path for asset file
- */
- protected function _getAssetFile($url) {
- $parts = explode('/', $url);
- $pluginPart = [];
- for ($i = 0; $i < 2; $i++) {
- if (!isset($parts[$i])) {
- break;
- }
- $pluginPart[] = Inflector::camelize($parts[$i]);
- $plugin = implode('/', $pluginPart);
- if ($plugin && Plugin::loaded($plugin)) {
- $parts = array_slice($parts, $i + 1);
- $fileFragment = implode(DS, $parts);
- $pluginWebroot = Plugin::path($plugin) . 'webroot' . DS;
- return $pluginWebroot . $fileFragment;
- }
- }
- }
- /**
- * Sends an asset file to the client
- *
- * @param \Cake\Network\Request $request The request object to use.
- * @param \Cake\Network\Response $response The response object to use.
- * @param string $assetFile Path to the asset file in the file system
- * @param string $ext The extension of the file to determine its mime type
- * @return void
- */
- protected function _deliverAsset(Request $request, Response $response, $assetFile, $ext) {
- $compressionEnabled = $response->compress();
- if ($response->type($ext) === $ext) {
- $contentType = 'application/octet-stream';
- $agent = $request->env('HTTP_USER_AGENT');
- if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
- $contentType = 'application/octetstream';
- }
- $response->type($contentType);
- }
- if (!$compressionEnabled) {
- $response->header('Content-Length', filesize($assetFile));
- }
- $response->cache(filemtime($assetFile));
- $response->sendHeaders();
- readfile($assetFile);
- if ($compressionEnabled) {
- ob_end_flush();
- }
- }
- }
|