Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php // Uncomment when debugging. // error_reporting(E_ALL | E_STRICT); // ini_set('display_errors', 'on'); if (!defined('MINIFY_BASE_DIR')) { define('MINIFY_BASE_DIR', realpath($_SERVER['DOCUMENT_ROOT'])); } if (!defined('MINIFY_CACHE_DIR')) { define('MINIFY_CACHE_DIR', sys_get_temp_dir()); } if (!defined('MINIFY_ENCODING')) { define('MINIFY_ENCODING', 'utf-8'); } if (!defined('MINIFY_MAX_FILES')) { define('MINIFY_MAX_FILES', 64); } if (!defined('MINIFY_REWRITE_CSS_URLS')) { define('MINIFY_REWRITE_CSS_URLS', true); } if (!defined('MINIFY_USE_CACHE')) { define('MINIFY_USE_CACHE', false); } class Minify { const TYPE_CSS = 'text/css'; const TYPE_JS = 'text/javascript'; protected $files = array(); protected $type = self::TYPE_JS; // -- Public Static Methods -------------------------------------------------- public static function handleRequest() { // 404 if no files were requested. if (!isset($_GET['files']) && !isset($_GET['fsid']) && !isset($_GET['dir'])) { header('HTTP/1.0 404 Not Found'); exit; } if( isset( $_GET['files'] ) ) { $files = array_map('trim', explode(',', $_GET['files'], MINIFY_MAX_FILES)); } else { $files = array(); } // resolving files from fsid if ( isset($_GET['fsid']) && isset($_GET['type']) && isset( $_GET['sb'] ) ) { require_once( './'. $_GET['sb'] .'/minify_config.php' ); $bin = decbin( $_GET['fsid'] ); while( strlen( $bin ) > 0 ) { if ( substr( $bin, -1 ) == 1 ) { $files[] = $config[$_GET['type']][0]; } array_shift( $config[$_GET['type']] ); $bin = substr( $bin, 0, -1 ); } } $basedir = $_GET['base']; //adding files the basic way while(list($key,$file) = each($files)) { $files[$key] = $basedir.$file; } //adding files from a directory if( isset($_GET['dir']) ) { if( strpos($_GET['dir'], '.') === false) { // allow to handle multiple dirs if (strpos($_GET['dir'], ',')) { $dirs = explode(',', $_GET['dir']); } else { $dirs = array($_GET['dir']); } foreach ($dirs as $dir) { $filelist = scandir(MINIFY_BASE_DIR . $basedir . $dir); foreach($filelist as $file) { if(strpos($file, '.') !== 0 && is_file(MINIFY_BASE_DIR . $basedir . $dir .'/' . $file)) { $files[] = $basedir . $dir .'/'. $file; } } } } } // 404 if the $files array is empty for some weird reason. if (!count($files)) { header('HTTP/1.0 404 Not Found'); exit; } // Determine the content type based on the extension of the first file // requested. $type = preg_match('/\.js$/iD', $files[0]) ? self::TYPE_JS : self::TYPE_CSS; // Minify and spit out the result. try { $minify = new Minify($type, $files); header("Content-Type: $type;charset=".MINIFY_ENCODING); $minify->browserCache(); echo $minify->combine(!(@$_GET['min'] === 'false')); exit; } catch (MinifyException $e) { header('HTTP/1.0 404 Not Found'); echo htmlentities($e->getMessage()); exit; } } public static function minify($string, $type = self::TYPE_JS) { return $type === self::TYPE_JS ? self::minifyJS($string) : self::minifyCSS($string); } // -- Protected Static Methods ----------------------------------------------- protected static function minifyCSS($css) { // Compress whitespace. $css = preg_replace('/\s+/', ' ', $css); // Remove comments. $css = preg_replace('/\/\*.*?\*\//', '', $css); return trim($css); } protected static function minifyJS($js) { require_once dirname(__FILE__).'/lib/jsmin.php'; return JSMin::minify($js)."\n\n"; } protected static function rewriteCSSUrls($css, $path) { $relativePath = preg_replace('/([\(\),\s\'"])/', '\\\$1', str_replace(MINIFY_BASE_DIR, '', $path)); $relativePath = str_replace('//','/',$relativePath); $css = preg_replace('/url\(\s*[\'"]?\/?(.+?)[\'"]?\s*\)/i', 'url(/assets/base.v9/css/../../.$relativePath.'/$1)', $css); return preg_replace('@'.$relativePath.'/http://@i','http://',$css); } // -- Public Instance Methods ------------------------------------------------ public function __construct($type = self::TYPE_JS, $files = array()) { if ($type !== self::TYPE_JS && $type !== self::TYPE_CSS) { throw new MinifyInvalidArgumentException('Invalid argument ($type): '. $type); } $this->type = $type; if (count((array) $files)) { $this->addFile($files); } } public function addFile($files) { $files = @array_map(array($this, 'resolveFilePath'), (array) $files); $this->files = array_unique(array_merge($this->files, $files)); } public function browserCache() { $hash = $this->getHash(); $lastModified = $this->getLastModified(); $lastModifiedGMT = gmdate('D, d M Y H:i:s', $lastModified).' GMT'; // Check/set the ETag. $etag = $hash.'_'.$lastModified; if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { if (strpos($_SERVER['HTTP_IF_NONE_MATCH'], $etag) !== false) { header("Last-Modified: $lastModifiedGMT", true, 304); exit; } } header('ETag: "'.$etag.'"'); // Check If-Modified-Since. if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { if ($lastModified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { header("Last-Modified: $lastModifiedGMT", true, 304); exit; } } header("Last-Modified: $lastModifiedGMT"); return false; } public function combine($minify = true) { // Return contents from server cache if possible. if (MINIFY_USE_CACHE) { if ($cacheResult = $this->serverCache(true)) { return $cacheResult; } } // Combine contents. $combined = array(); foreach($this->files as $file) { if ($this->type === self::TYPE_CSS && MINIFY_REWRITE_CSS_URLS) { // Rewrite relative CSS URLs. $combined[] = self::rewriteCSSUrls(file_get_contents($file), dirname($file)); } else { $combined[] = file_get_contents($file); } } $combined = $minify ? self::minify(implode("\n", $combined), $this->type) : implode("\n", $combined); // Save combined contents to the cache. if (MINIFY_USE_CACHE) { $cacheFile = MINIFY_CACHE_DIR.'/minify_'.$this->getHash(); @file_put_contents($cacheFile, $combined, LOCK_EX); } return $combined; } public function getFiles() { return $this->files; } public function getHash() { return hash('md5', implode('', $this->files)); } public function getLastModified() { $lastModified = 0; // Get the timestamp of the most recently modified file. foreach($this->files as $file) { $modified = filemtime($file); if ($modified !== false && $modified > $lastModified) { $lastModified = $modified; } } return $lastModified; } public function removeFile($files) { $files = @array_map(array($this, 'resolveFilePath'), (array) $files); $this->files = array_diff($this->files, $files); } public function serverCache($return = false) { $cacheFile = MINIFY_CACHE_DIR.'/minify_'.$this->getHash(); $lastModified = $this->getLastModified(); if (is_file($cacheFile) && $lastModified <= filemtime($cacheFile)) { if ($return) { return file_get_contents($cacheFile); } else { echo file_get_contents($cacheFile); exit; } } return false; } // -- Protected Instance Methods --------------------------------------------- protected function resolveFilePath($file) { // Is this a URL? if (preg_match('/^https?:\/\//i', $file)) { if (!$parsedUrl = parse_url(/assets/base.v9/css/../../$file)) { throw new MinifyInvalidUrlException("Invalid URL: $file"); } // Does the server name match the local server name? if (!isset($parsedUrl['host']) || $parsedUrl['host'] != $_SERVER['SERVER_NAME']) { throw new MinifyInvalidUrlException('Non-local URL not supported: '. $file); } // Get the file's absolute path. $filepath = MINIFY_BASE_DIR.$parsedUrl['path']; } else { // Get the file's absolute path. $filepath = MINIFY_BASE_DIR.'/'.$file; } // Ensure that the file exists, that the path is under the base directory, // that the file's extension is either '.css' or '.js', and that the file is // actually readable. if (!$filepath || //!is_file($filepath) || //!is_readable($filepath) || !preg_match('/^'.preg_quote(MINIFY_BASE_DIR, '/').'/', $filepath) || !preg_match('/\.(?:css|js)$/iD', $filepath)) { // Even when the file exists, we still throw a // MinifyFileNotFoundException in order to try to prevent an information // disclosure vulnerability. // CHANGED: DONT throw file not found exception, show only the existing files instead throw new MinifyFileNotFoundException("File not found: $file"); } return $filepath; } } // -- Exception Classes -------------------------------------------------------- class MinifyException extends Exception {} class MinifyFileNotFoundException extends MinifyException {} class MinifyInvalidArgumentException extends MinifyException {} class MinifyInvalidUrlException extends MinifyException {} // -- Global Scope ------------------------------------------------------------- if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) { Minify::handleRequest(); } ?>
Advertisement
Add Comment
Please, Sign In to add comment