| 1 |
<?php |
| 2 |
|
| 3 |
// allows putting /static anywhere as long as you put a boostrap.php in it |
| 4 |
if (is_file(__DIR__ . '/bootstrap.php')) { |
| 5 |
$bootstrap_file = __DIR__ . '/bootstrap.php'; |
| 6 |
} else { |
| 7 |
$bootstrap_file = __DIR__ . '/../bootstrap.php'; |
| 8 |
} |
| 9 |
|
| 10 |
$send_400 = function ($content = 'Bad URL') { |
| 11 |
http_response_code(400); |
| 12 |
die($content); |
| 13 |
}; |
| 14 |
|
| 15 |
$send_301 = function ($url) { |
| 16 |
http_response_code(301); |
| 17 |
header("Cache-Control: max-age=31536000"); |
| 18 |
header("Location: $url"); |
| 19 |
exit; |
| 20 |
}; |
| 21 |
|
| 22 |
$app = (require $bootstrap_file); |
| 23 |
/* @var \Minify\App $app */ |
| 24 |
|
| 25 |
if (!$app->config->enableStatic) { |
| 26 |
die('Minify static serving is not enabled. Set $min_enableStatic = true; in config.php'); |
| 27 |
} |
| 28 |
|
| 29 |
require __DIR__ . '/lib.php'; |
| 30 |
|
| 31 |
if (!is_writable(__DIR__)) { |
| 32 |
http_response_code(500); |
| 33 |
die('Directory is not writable.'); |
| 34 |
} |
| 35 |
|
| 36 |
// parse request |
| 37 |
// SCRIPT_NAME = /path/to/minify/static/gen.php |
| 38 |
// REQUEST_URI = /path/to/minify/static/1467084520/b=path/to/minify&f=quick-test.js |
| 39 |
|
| 40 |
// "/path/to/minify/static" |
| 41 |
$root_uri = dirname($_SERVER['SCRIPT_NAME']); |
| 42 |
|
| 43 |
// "/1467084520/b=path/to/minify&f=quick-test.js" |
| 44 |
$uri = substr($_SERVER['REQUEST_URI'], strlen($root_uri)); |
| 45 |
|
| 46 |
if (!preg_match('~^/(\d+)/(.*)$~', $uri, $m)) { |
| 47 |
http_response_code(404); |
| 48 |
die('File not found'); |
| 49 |
} |
| 50 |
|
| 51 |
// "1467084520" |
| 52 |
$requested_cache_dir = $m[1]; |
| 53 |
|
| 54 |
// "b=path/to/minify&f=quick-test.js" |
| 55 |
$query = $m[2]; |
| 56 |
|
| 57 |
// we basically want canonical querystrings because we make a file for each one. |
| 58 |
// manual parsing is the only way to do this. The MinApp controller will validate |
| 59 |
// these parameters anyway. |
| 60 |
$get_params = array(); |
| 61 |
foreach (explode('&', $query) as $piece) { |
| 62 |
if (false === strpos($piece, '=')) { |
| 63 |
$send_400(); |
| 64 |
} |
| 65 |
|
| 66 |
list($key, $value) = explode('=', $piece, 2); |
| 67 |
if (!in_array($key, array('f', 'g', 'b', 'z'))) { |
| 68 |
$send_400(); |
| 69 |
} |
| 70 |
|
| 71 |
if (isset($get_params[$key])) { |
| 72 |
// already used |
| 73 |
$send_400(); |
| 74 |
} |
| 75 |
|
| 76 |
if ($key === 'z' && !preg_match('~^\.(css|js)$~', $value, $m)) { |
| 77 |
$send_400(); |
| 78 |
} |
| 79 |
|
| 80 |
$get_params[$key] = urldecode($value); |
| 81 |
} |
| 82 |
|
| 83 |
$cache_time = Minify\StaticService\get_cache_time(); |
| 84 |
if (!$cache_time) { |
| 85 |
http_response_code(500); |
| 86 |
die('Directory is not writable.'); |
| 87 |
} |
| 88 |
|
| 89 |
$app->env = new Minify_Env(array( |
| 90 |
'get' => $get_params, |
| 91 |
)); |
| 92 |
$ctrl = $app->controller; |
| 93 |
$options = $app->serveOptions; |
| 94 |
$sources = $ctrl->createConfiguration($options)->getSources(); |
| 95 |
if (!$sources) { |
| 96 |
http_response_code(404); |
| 97 |
die('File not found'); |
| 98 |
} |
| 99 |
if ($sources[0]->getId() === 'id::missingFile') { |
| 100 |
$send_400("Bad URL: missing file"); |
| 101 |
} |
| 102 |
|
| 103 |
// we need URL to end in appropriate extension |
| 104 |
$type = $sources[0]->getContentType(); |
| 105 |
$ext = ($type === Minify::TYPE_JS) ? '.js' : '.css'; |
| 106 |
if (substr($query, - strlen($ext)) !== $ext) { |
| 107 |
$send_301("$root_uri/$cache_time/{$query}&z=$ext"); |
| 108 |
} |
| 109 |
|
| 110 |
// fix the cache dir in the URL |
| 111 |
if ($cache_time !== $requested_cache_dir) { |
| 112 |
$send_301("$root_uri/$cache_time/$query"); |
| 113 |
} |
| 114 |
|
| 115 |
$content = $app->minify->combine($sources); |
| 116 |
|
| 117 |
// save and send file |
| 118 |
$file = __DIR__ . "/$cache_time/$query"; |
| 119 |
if (!is_dir(dirname($file))) { |
| 120 |
mkdir(dirname($file), 0777, true); |
| 121 |
} |
| 122 |
|
| 123 |
file_put_contents($file, $content); |
| 124 |
|
| 125 |
header("Content-Type: $type;charset=utf-8"); |
| 126 |
header("Cache-Control: max-age=31536000"); |
| 127 |
echo $content; |
| 128 |
|