diff --git a/core/modules/system/src/Controller/CssAssetController.php b/core/modules/system/src/Controller/CssAssetController.php index dc1261d..6cb65ca 100644 --- a/core/modules/system/src/Controller/CssAssetController.php +++ b/core/modules/system/src/Controller/CssAssetController.php @@ -1,106 +1,19 @@ libraryDependencyResolver = $library_dependency_resolver; - $this->assetResolver = $asset_resolver; - $this->themeInitialization = $theme_initialization; - $this->themeManager = $theme_manager; - $this->grouper = $grouper; - $this->optimizer = $optimizer; - $this->dumper = $dumper; + $this->mimeType = 'text/css'; + $this->assetType = 'css'; + parent::construct($library_dependency_resolver, $asset_resolver, $theme_initialization, $theme_manager, $grouper, $optimizer, $dumper; } /** @@ -119,164 +32,10 @@ public static function create(ContainerInterface $container) { } /** - * Generates a derivative, given a style and image path. - * - * After generating an image, transfer it to the requesting agent. - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. - * @param $file_name - * The file to deliver. - * - * @return \Symfony\Component\HttpFoundation\BinaryFileResponse|\Symfony\Component\HttpFoundation\Response - * The transferred file as response or some error response. - * - * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException - * Thrown when the user does not have access to the file. - * @throws \Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException - * Thrown when the file is still being generated. - */ - public function deliver(Request $request, $file_name) { - $theme = $request->query->get('theme'); - $active_theme = $this->themeInitialization->initTheme($theme); - $this->themeManager->setActiveTheme($active_theme); - - // While the libraries are taken from the query parameter, the URL as a - // whole is validated against a hash of the CSS assets later on. - $libraries = $this->libraryDependencyResolver->getLibrariesWithDependencies($request->query->get('libraries')); - $css_assets = $this->assetResolver->getCssFromLibraries($libraries, TRUE); - - // Group the assets. - $css_groups = $this->grouper->group($css_assets); - - // Now optimize (concatenate + minify) and dump each asset group, unless - // that was already done, in which case it should appear in - // drupal_css_cache_files. - // Drupal contrib can override this default CSS aggregator to keep the same - // grouping, optimizing and dumping, but change the strategy that is used to - // determine when the aggregate should be rebuilt (e.g. mtime, HTTPS …). - $css_assets = array(); - $libraries = []; - - $base_name = basename($file_name, '.css'); - - $file_parts = explode('_', $base_name); - // The group delta is the second segment of the filename, if it's not there - // then the filename is invalid. - if (!isset($file_parts[1]) || !is_numeric($file_parts[1])) { - throw new BadRequestHttpException('Invalid filename'); - } - $group_delta = $file_parts[1]; - - // The hash is the third segment of the filename. - if (!isset($file_parts[2])) { - throw new BadRequestHttpException('Invalid filename'); - } - $hash = $file_parts[2]; - - // If the group being requested does not exist, assume an invalid filename. - if (!isset($css_groups[$group_delta])) { - throw new BadRequestHttpException('Invalid filename'); - } - $css_group = $css_groups[$group_delta]; - - // Only groups that are preprocessed will be requested, so don't try to - // process ones that aren't. - if (!$css_group['preprocess']) { - throw new BadRequestHttpException('Invalid filename'); - } - $key = $this->generateHash($css_groups); - - // The hash from the library definitions in code may not match the hash from - // the URL. This can be for three reasons: - // 1. Someone has requested an outdated URL, i.e. from a cached page, which - // matches a different version of the code base. - // 2. Someone has requrested an outdated URL during a deployment. This is - // the same case as #1 but a much shorter window. - // 3. Someone is attempting to craft an invalid URL in order to conduct a - // denial of service attack on the site. - // - // @todo: we could potentially hash the library definitions with the secret - // key to create an HMAC, so that only valid combinations of libraries are - // allowed. - // For now treat all of these the same, but if there's no match, don't write - // to the filesystem. - $match = TRUE; - - $uri = 'public://css/' . $file_name; - if ($key !== $hash) { - // The file requested may have been written to disk by the time we got - // here. If it hasn't, and the hashes don't match, it's possible that a - // file matching the code base for this request already exists on disk, so - // use the filename matching this code base, not the one that generated - // the original filename for the request. - if (!file_exists($uri)) { - $uri = 'public://css/' . 'css_' . $group_delta . '_' . $hash . '.css'; - } - // Either way, we didn't get a match. - $match = FALSE; - } - $headers = [ - 'Content-Type' => 'text/css', - // Headers sent from PHP can never perfectly match those sent when the - // file is served by the filesystem, so ensure this request does not get - // cached in either the browser or reverse proxies. Subsequent requests - // for the file will be served from disk and be cached. This is done to - // avoid situations such as where one CDN endpoint is serving a version - // cached from PHP, while another is serving a version cached from disk. - // Should there be any discrepancy in behaviour between those files, this - // can make debugging very difficult. - 'Cache-control' => 'private, no-store', - ]; - - if (!file_exists($uri)) { - // Optimize each asset within the group. - $data = ''; - foreach ($css_group['items'] as $css_asset) { - $data .= $this->optimizer->optimize($css_asset); - } - // Per the W3C specification at - // http://www.w3.org/TR/REC-CSS2/cascade.html#at-import, @import - // rules must precede any other style, so we move those to the - // top. - $regexp = '/@import[^;]+;/i'; - preg_match_all($regexp, $data, $matches); - $data = preg_replace($regexp, '', $data); - $data = implode('', $matches[0]) . $data; - // Dump the optimized CSS for this group into an aggregate file. - if ($match) { - $uri = $this->dumper->dump($data, 'css', $uri); - } - $headers = [ - 'Content-Type' => 'text/css', - 'Cache-control' => 'private, no-store', - ]; - // Generate response. - $response = new Response($data, 200, $headers); - return $response; - } - else { - return new BinaryFileResponse($uri, 200, $headers); - } - } - - /** - * Generate a hash for a given group of CSS assets. - * - * @param array $css_group - * A group of CSS assets. - * - * @return string - * A hash to uniquely identify the given group of CSS assets. + * {@inheritdoc} */ - protected function generateHash(array $css_group) { - $normalized = $css_group; - foreach ($normalized as $order => $group) { - foreach ($group['items'] as $key => $asset) { - unset($normalized[$order]['items'][$key]['weight']); - } - } - return hash('sha256', serialize($normalized)); + protected function getAssetsFromLibraries($libraries) { + return $this->assetResolver->getCssAssets($libraries, TRUE); } } diff --git a/core/modules/system/src/Routing/AssetRoutes.php b/core/modules/system/src/Routing/AssetRoutes.php index 841fc67..4a46446 100644 --- a/core/modules/system/src/Routing/AssetRoutes.php +++ b/core/modules/system/src/Routing/AssetRoutes.php @@ -65,6 +65,15 @@ public function routes() { '_access' => 'TRUE', ) ); + $routes['system.js_asset'] = new Route( + '/' . $directory_path . '/js/{file_name}', + array( + '_controller' => 'Drupal\system\Controller\JsAssetController::deliver', + ), + array( + '_access' => 'TRUE', + ) + ); return $routes; }