/** * Gets the path for the request assets and handles caching/etag responses * Automatically sends a 404 and exits if path doesn't exist or fails a security check * * @param string $contentType * @param Asset $asset Asset to compile. If null, path contents will be ouputed * @param int $lastModified If null, filemtime will be used, should return a unix timestamp */ private function process($contentType, Asset $asset = null, $lastModified = null) { if ($lastModified === null) { $lastModified = filemtime($this->path); } $etag = '"' . sha1($this->path . $lastModified) . '"'; if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { if ($_SERVER['HTTP_IF_NONE_MATCH'] === $etag) { header('HTTP/1.1 304 Not Modified'); exit; } } $dateFormat = 'D, d M Y H:i:s T'; header('Cache-Control: public, max-age=31536000'); header('Expires: ' . gmdate($dateFormat, $lastModified + 31536000)); header('Last-Modified: ' . gmdate($dateFormat, $lastModified)); header('ETag: ' . $etag); header('Content-Type: ' . $contentType . '; charset=utf-8'); $compile = function () use($asset) { if ($asset === null) { return file_get_contents($this->path); } else { header('X-Cached: false'); try { return $asset->compile(); } catch (CompilationException $e) { if (is_array($e->context)) { foreach ($e->context as $key => $value) { printf('/* %s: %s */%s', strtoupper($key), $value, PHP_EOL); } } else { if (is_string($e->context)) { printf('/* %s */%s', $e->context, PHP_EOL); } } echo $e->log; exit(1); } } }; if (isset($_GET['ignore-cache'])) { echo $compile(); } else { echo app('cache')->remember(str_slug($this->path) . '-' . md5($lastModified), 1440, $compile); } exit; }