/** * Load the content of the given item. ($element MUST be an absolute path!) * * Note that this function does 'fixup' the loaded content, which MAY result in recursive * invocation of this function to load each of the dectected sub-items. This way we can easily handle * 'flattening' CSS which uses the @import statement, etc. */ function load_one($type, $http_base, $base, $root, $element) { global $do_not_load; $uri = path_remove_dot_segments($base . '/' . $element); $path = str_replace("\\", '/', realpath($uri)); /* Windows can handle '/' so we're OK with the replace here; makes strpos() below work on all platforms */ /* * only allow a load when the CSS/JS is indeed within document-root: * * as path_remove_dot_segments() will remove ALL '../' directory bits, any attempt to grab, say, * ../../../../../../../../../etc/passwd * will fail as path_remove_dot_segments() will have DAMAGED the path and $element * does not point within the $root path any more! */ $my_content = null; if (is_file($path) && strpos($path, $root) === 0) { //echo "<pre>$type, $http_base, \n$base, \n$root, $element, \n$uri --> $path, " . strpos($path, $root); $my_content = ''; if (!$do_not_load) { $my_content = file_get_contents($path); } } else { send_response_status_header(404); // Not Found die("\n" . get_response_code_string(404) . " - Combiner: not a legal path: {$type}, {$http_base}, \n{$base}, \n{$root}, {$element}, \n{$uri} --> {$path}, " . strpos($path, $root)); } if ($my_content === false) { send_response_status_header(404); // Not Found die("\n" . get_response_code_string(404) . " - Combiner: failed to load data from file: type='{$type}', element='{$element}'\n"); } switch ($type) { case 'css': /* * Before we go and optimize the CSS (or not), we fix up the CSS for IE7/8/... by adding the * * behavior: url(PIE.php); * * line in every definition which has a 'border-radius'. * * We do it this way to ensure all styles are patched correctly; previously this was done by hand in the * various CSS files, resulting in quite a few ommisions in the base css files and also the templates' ones. * * As we now force all CSS+JS requests through here, we can easily fix this kind of oddity very consistently * by performing the fix in code, right here. * * As the result is cached, this effort is only required once. Which would happen at install time when * you run the 'cache priming' action, resulting in a fully set up cache when you go 'live'. */ $my_content = fixup_css($my_content, $http_base, $type, $base, $root, $element); break; default: $my_content = fixup_js($my_content, $http_base, $type, $base, $root, $element); break; } return $my_content; }
/** * Convert any path (absolute or relative) to a fully qualified URL */ function makeAbsoluteURI($path) { $reqpage = filterParam4FullFilePath($_SERVER['PHP_SELF']); $page = array(); if (strpos($path, '://')) { if (strpos($path, '?') === false || strpos($path, '://') < strpos($path, '?')) { /* * parse_url can only parse URLs, not relative paths. * * http://bugs.php.net/report.php?manpage=function.parse-url#Notes */ $page = parse_url($path); if (isset($page[PHP_URL_SCHEME])) { return $path; } /* * We do NOT accept 'URL's like * * www.example.com/path.ext * * as input: we treat the entire string as a path (and a relative one at that)! */ } } /* * Expect input which is a subset of * * /path/file.exe?query#fragment * * with either absolute or relative path/file.ext as the mandatory part. */ $idx = strpos($path, '?'); if ($idx !== false) { $page[PHP_URL_PATH] = substr($path, 0, $idx); $path = substr($path, $idx + 1); $idx = strpos($path, '#'); if ($idx !== false) { $page[PHP_URL_QUERY] = substr($path, 0, $idx); $page[PHP_URL_FRAGMENT] = substr($path, $idx + 1); } else { $page[PHP_URL_QUERY] = $path; } } else { $page[PHP_URL_PATH] = $path; } $path = $page[PHP_URL_PATH]; if (strpos($path, '/') === 0) { //already absolute } else { /* * Convert relative path to absolute by prepending the current request path * (which is absolute) and a '../' basedir-similar. * * This way also provides for relative paths which don't start with './' but * simply say something like * relpath/file.ext * which will produce a dotted absolute path like this: * /current_request_path/reqfile.php/../relpath/file.ext * which is fine: the ../ will remove the reqfile.php component and we're left * with a neatly formatted absolute path! */ $page[PHP_URL_PATH] = $_SERVER['PHP_SELF'] . '/../' . $path; } $page[PHP_URL_PATH] = path_remove_dot_segments($page[PHP_URL_PATH]); // fill in the holes... assume defaults from the current request. if (empty($page[PHP_URL_SCHEME])) { if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || strpos(strtolower($_SERVER['SERVER_PROTOCOL']), 'https') === 0 || intval($_SERVER["SERVER_PORT"]) == 443) { $page[PHP_URL_SCHEME] = 'https'; } else { $page[PHP_URL_SCHEME] = 'http'; } } if (empty($page[PHP_URL_HOST])) { $page[PHP_URL_HOST] = $_SERVER["SERVER_NAME"]; } if (empty($page[PHP_URL_PORT])) { /* Only set the port number when it is non-standard: */ $portno = intval($_SERVER["SERVER_PORT"]); if ($portno != 0 && ($page[PHP_URL_SCHEME] == 'http' && $portno == 80) && ($page[PHP_URL_SCHEME] == 'https' && $portno == 443)) { $page[PHP_URL_PORT] = $portno; } } $url = ''; if (!empty($page[PHP_URL_SCHEME])) { $url = $page[PHP_URL_SCHEME] . '://'; } if (!empty($page[PHP_URL_USER])) { $url .= $page[PHP_URL_USER]; if (!empty($page[PHP_URL_PASS])) { $url .= ':' . $page[PHP_URL_PASS]; } $url .= '@'; } if (!empty($page[PHP_URL_HOST])) { $url .= $page[PHP_URL_HOST]; } $url .= $page[PHP_URL_PATH]; if (!empty($page[PHP_URL_QUERY])) { $url .= '?' . $page[PHP_URL_QUERY]; } if (!empty($page[PHP_URL_FRAGMENT])) { $url .= '#' . $page[PHP_URL_FRAGMENT]; } return $url; }