[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 abstract class CelerityResourceController extends PhabricatorController { 4 5 protected function buildResourceTransformer() { 6 return null; 7 } 8 9 public function shouldRequireLogin() { 10 return false; 11 } 12 13 public function shouldRequireEnabledUser() { 14 return false; 15 } 16 17 public function shouldAllowPartialSessions() { 18 return true; 19 } 20 21 abstract public function getCelerityResourceMap(); 22 23 protected function serveResource($path, $package_hash = null) { 24 // Sanity checking to keep this from exposing anything sensitive, since it 25 // ultimately boils down to disk reads. 26 if (preg_match('@(//|\.\.)@', $path)) { 27 return new Aphront400Response(); 28 } 29 30 $type = CelerityResourceTransformer::getResourceType($path); 31 $type_map = self::getSupportedResourceTypes(); 32 33 if (empty($type_map[$type])) { 34 throw new Exception('Only static resources may be served.'); 35 } 36 37 $dev_mode = PhabricatorEnv::getEnvConfig('phabricator.developer-mode'); 38 39 if (AphrontRequest::getHTTPHeader('If-Modified-Since') && !$dev_mode) { 40 // Return a "304 Not Modified". We don't care about the value of this 41 // field since we never change what resource is served by a given URI. 42 return $this->makeResponseCacheable(new Aphront304Response()); 43 } 44 45 $is_cacheable = (!$dev_mode) && 46 $this->isCacheableResourceType($type); 47 48 $cache = null; 49 $data = null; 50 if ($is_cacheable) { 51 $cache = PhabricatorCaches::getImmutableCache(); 52 53 $request_path = $this->getRequest()->getPath(); 54 $cache_key = $this->getCacheKey($request_path); 55 56 $data = $cache->getKey($cache_key); 57 } 58 59 if ($data === null) { 60 $map = $this->getCelerityResourceMap(); 61 62 if ($map->isPackageResource($path)) { 63 $resource_names = $map->getResourceNamesForPackageName($path); 64 if (!$resource_names) { 65 return new Aphront404Response(); 66 } 67 68 try { 69 $data = array(); 70 foreach ($resource_names as $resource_name) { 71 $data[] = $map->getResourceDataForName($resource_name); 72 } 73 $data = implode("\n\n", $data); 74 } catch (Exception $ex) { 75 return new Aphront404Response(); 76 } 77 } else { 78 try { 79 $data = $map->getResourceDataForName($path); 80 } catch (Exception $ex) { 81 return new Aphront404Response(); 82 } 83 } 84 85 $xformer = $this->buildResourceTransformer(); 86 if ($xformer) { 87 $data = $xformer->transformResource($path, $data); 88 } 89 90 if ($cache) { 91 $cache->setKey($cache_key, $data); 92 } 93 } 94 95 $response = new AphrontFileResponse(); 96 $response->setContent($data); 97 $response->setMimeType($type_map[$type]); 98 99 // NOTE: This is a piece of magic required to make WOFF fonts work in 100 // Firefox. Possibly we should generalize this. 101 if ($type == 'woff') { 102 // We could be more tailored here, but it's not currently trivial to 103 // generate a comprehensive list of valid origins (an install may have 104 // arbitrarily many Phame blogs, for example), and we lose nothing by 105 // allowing access from anywhere. 106 $response->addAllowOrigin('*'); 107 } 108 109 return $this->makeResponseCacheable($response); 110 } 111 112 public static function getSupportedResourceTypes() { 113 return array( 114 'css' => 'text/css; charset=utf-8', 115 'js' => 'text/javascript; charset=utf-8', 116 'png' => 'image/png', 117 'gif' => 'image/gif', 118 'jpg' => 'image/jpeg', 119 'swf' => 'application/x-shockwave-flash', 120 'woff' => 'font/woff', 121 'eot' => 'font/eot', 122 'ttf' => 'font/ttf', 123 ); 124 } 125 126 private function makeResponseCacheable(AphrontResponse $response) { 127 $response->setCacheDurationInSeconds(60 * 60 * 24 * 30); 128 $response->setLastModified(time()); 129 130 return $response; 131 } 132 133 134 /** 135 * Is it appropriate to cache the data for this resource type in the fast 136 * immutable cache? 137 * 138 * Generally, text resources (which are small, and expensive to process) 139 * are cached, while other types of resources (which are large, and cheap 140 * to process) are not. 141 * 142 * @param string Resource type. 143 * @return bool True to enable caching. 144 */ 145 private function isCacheableResourceType($type) { 146 $types = array( 147 'js' => true, 148 'css' => true, 149 ); 150 151 return isset($types[$type]); 152 } 153 154 private function getCacheKey($path) { 155 return 'celerity:'.$path; 156 } 157 158 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |