public function processRequest() { $path = $this->path; // Sanity checking to keep this from exposing anything sensitive, since it // ultimately boils down to disk reads. if (preg_match('@(//|\\.\\.)@', $path)) { return new Aphront400Response(); } $type = CelerityResourceTransformer::getResourceType($path); $type_map = $this->getSupportedResourceTypes(); if (empty($type_map[$type])) { throw new Exception("Only static resources may be served."); } if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !PhabricatorEnv::getEnvConfig('celerity.force-disk-reads')) { // Return a "304 Not Modified". We don't care about the value of this // field since we never change what resource is served by a given URI. return $this->makeResponseCacheable(new Aphront304Response()); } $root = dirname(phutil_get_library_root('phabricator')); if ($this->package) { $map = CelerityResourceMap::getInstance(); $paths = $map->resolvePackage($this->hash); if (!$paths) { return new Aphront404Response(); } try { $data = array(); foreach ($paths as $package_path) { $data[] = Filesystem::readFile($root . '/webroot/' . $package_path); } $data = implode("\n\n", $data); } catch (Exception $ex) { return new Aphront404Response(); } } else { try { $data = Filesystem::readFile($root . '/webroot/' . $path); } catch (Exception $ex) { return new Aphront404Response(); } } $xformer = new CelerityResourceTransformer(); $xformer->setMinify(PhabricatorEnv::getEnvConfig('celerity.minify')); $xformer->setCelerityMap(CelerityResourceMap::getInstance()); $data = $xformer->transformResource($path, $data); $response = new AphrontFileResponse(); $response->setContent($data); $response->setMimeType($type_map[$type]); return $this->makeResponseCacheable($response); }
public function testTransformation() { $files = dirname(__FILE__) . '/transformer/'; foreach (Filesystem::listDirectory($files) as $file) { $name = basename($file); $data = Filesystem::readFile($files . '/' . $file); $parts = preg_split('/^~~~+\\n/m', $data); $parts = array_merge($parts, array(null)); list($options, $in, $expect) = $parts; $options = PhutilSimpleOptions::parse($options) + array('minify' => false, 'name' => $name); $xformer = new CelerityResourceTransformer(); $xformer->setRawResourceMap(array('/rsrc/example.png' => array('uri' => '/res/hash/example.png'))); $xformer->setMinify($options['minify']); $result = $xformer->transformResource($options['name'], $in); $this->assertEqual(rtrim($expect), rtrim($result), $file); } }
/** * Find text resources (like JS and CSS) and return information about them. * * @param CelerityPhysicalResources Resource map to find text resources for. * @param CelerityResourceTransformer Configured resource transformer. * @return map<string, map<string, string>> Resource information map. */ private function rebuildTextResources(CelerityPhysicalResources $resources, CelerityResourceTransformer $xformer) { $text_map = $resources->findTextResources(); $result_map = array(); foreach ($text_map as $name => $data_hash) { $raw_data = $resources->getResourceData($name); $xformed_data = $xformer->transformResource($name, $raw_data); $data_hash = $resources->getCelerityHash($xformed_data); $hash = $resources->getCelerityHash($data_hash . $name); list($provides, $requires) = $this->getProvidesAndRequires($name, $raw_data); $result_map[$name] = array('hash' => $hash); if ($provides !== null) { $result_map[$name] += array('provides' => $provides, 'requires' => $requires); } } return $result_map; }