PageRenderTime 56ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/forum/web-optimizer/libs/php/wo.static.php

https://github.com/GreyTeardrop/socionicasys-forum
PHP | 339 lines | 298 code | 1 blank | 40 comment | 43 complexity | e6f76201cdc209cbcfa53285ec12dfab MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-3.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * File from WEBO Site SpeedUp, WEBO Software (http://www.webogroup.com/)
  4. * Sends cache headers among the content of requested file.
  5. * Also adds GZip for known types of files (that can be gzipped).
  6. * Resticted filename to document root only.
  7. * Helps when there is no mod_expires and(or) no mod_deflate on the server.
  8. * License agreement: http://www.webogroup.com/about/EULA.txt
  9. *
  10. **/
  11. /* replace all urls with absolute paths */
  12. function replace_urls ($cached, $filename, $document_root) {
  13. $content = @file_get_contents($filename);
  14. $path = str_replace($document_root, "", $filename);
  15. $path = substr($path, 0, strrpos($path, '/') + 1);
  16. preg_match_all("@url\s*\(['\"\s]*([^\"'\)]+)['\"\s]*\)@", $content, $urls, PREG_SET_ORDER);
  17. $replaced = array();
  18. foreach ($urls as $url) {
  19. $u = $i = $url[1];
  20. if (empty($replaced[$i])) {
  21. switch ($u{0}) {
  22. case '/':
  23. break;
  24. case 'h':
  25. if (substr($u, 0, 5) == 'http:' || substr($u, 0, 6) == 'https:') {
  26. break;
  27. }
  28. case 'd':
  29. if (substr($u, 0, 5) == 'data:') {
  30. break;
  31. }
  32. case 'm':
  33. if (substr($u, 0, 6) == 'mhtml:') {
  34. break;
  35. }
  36. }
  37. $content = str_replace($i, $u, $content);
  38. $replaced[$i] = 1;
  39. }
  40. }
  41. $fp = @fopen($cached, "wb");
  42. if ($fp) {
  43. @fwrite($fp, $content);
  44. @fclose($fp);
  45. }
  46. return $content;
  47. }
  48. /* return heximal number for a decimal one, by jbleau at gmail dot com */
  49. function dec_to_hex ($dec) {
  50. $hex = Array( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5,
  51. 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 'a',
  52. 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e',
  53. 15 => 'f' );
  54. $h = '';
  55. do {
  56. $h = $hex[($dec%16)] . $h;
  57. $dec /= 16;
  58. } while ($dec >= 1);
  59. return $h;
  60. }
  61. /* define gzip levels if they are not defines yet */
  62. $gzip_level_css = empty($gzip_level_css) ? 7 : $gzip_level_css;
  63. $gzip_level_javascript = empty($gzip_level_javascript) ? 7 : $gzip_level_javascript;
  64. $gzip_level_fonts = empty($gzip_level_fonts) ? 7 : $gzip_level_fonts;
  65. $document_root = $_SERVER['DOCUMENT_ROOT'];
  66. /* Avoiding problems with Denwer and others CGI */
  67. if (empty($document_root) || !is_dir($document_root) ||
  68. !is_file($document_root . getenv("SCRIPT_NAME"))) {
  69. $document_root = substr(getenv("SCRIPT_FILENAME"), 0,
  70. strpos(getenv("SCRIPT_FILENAME"), getenv("SCRIPT_NAME")));
  71. }
  72. $document_root = str_replace("\\", "/", realpath($document_root));
  73. /* define website root if it's empty */
  74. $website_root = empty($website_root) ? $document_root : $website_root;
  75. /* calculate extension */
  76. $dot = strrpos($_SERVER['QUERY_STRING'], '.');
  77. $extension = strtolower(substr($_SERVER['QUERY_STRING'],
  78. $dot + 1, strlen($_SERVER['QUERY_STRING']) - $dot));
  79. /* gzip or not this file? */
  80. $gzip = 0;
  81. /* calculate MIME type */
  82. switch ($extension) {
  83. case 'js':
  84. $extension = 'application/x-javascript';
  85. $gzip = 1;
  86. $gzip_level = $gzip_level_javascript;
  87. break;
  88. case 'css':
  89. $extension = 'text/css';
  90. $gzip = 1;
  91. $gzip_level = $gzip_level_css;
  92. break;
  93. case 'jpg':
  94. $extension = 'jpeg';
  95. case 'jpeg':
  96. case 'bmp':
  97. case 'gif':
  98. case 'png':
  99. $extension = 'image/' . $extension;
  100. break;
  101. case 'ico':
  102. $extension = 'image/x-icon';
  103. $gzip = 1;
  104. $gzip_level = $gzip_level_css;
  105. break;
  106. case 'flv':
  107. $extension = 'video/x-flv';
  108. break;
  109. case 'asf':
  110. case 'asx':
  111. case 'wmv':
  112. case 'wma':
  113. case 'wax':
  114. case 'wmx':
  115. case 'wm':
  116. $extension = 'video/x-ms-' . $extension;
  117. break;
  118. case 'swf':
  119. $extension = 'application/x-shockwave-flash';
  120. break;
  121. case 'pdf':
  122. $extension = 'application/pdf';
  123. break;
  124. case 'doc':
  125. $extension = 'application/msword';
  126. break;
  127. case 'rtf':
  128. $extension = 'application/rtf';
  129. break;
  130. case 'xls':
  131. $extension = 'application/vnd.ms-excel';
  132. break;
  133. case 'ppt':
  134. $extension = 'application/vnd.ms-powerpoint';
  135. break;
  136. case 'otf':
  137. $extension = 'application/x-font-opentype';
  138. $gzip = 1;
  139. $gzip_level = $gzip_level_fonts;
  140. break;
  141. case 'ttf':
  142. $extension = 'application/x-font-truetype';
  143. $gzip = 1;
  144. $gzip_level = $gzip_level_fonts;
  145. break;
  146. case 'svg':
  147. $extension = 'image/svg+xml';
  148. $gzip = 1;
  149. $gzip_level = $gzip_level_fonts;
  150. break;
  151. case 'eot':
  152. $extension = 'application/vnd.ms-fontobject';
  153. $gzip = 1;
  154. $gzip_level = $gzip_level_fonts;
  155. break;
  156. case 'woff':
  157. $extension = 'font/woff';
  158. break;
  159. /* protect all other files from viewing */
  160. default:
  161. $extension = '';
  162. break;
  163. }
  164. /* handle cases with relative document root and redirect via .htaccess */
  165. if ($_SERVER['QUERY_STRING']{0} === '/') {
  166. if ($_SERVER['QUERY_STRING']{1} === '/') {
  167. $_SERVER['QUERY_STRING'] = 'http' .
  168. (empty($_SERVER['HTTPS']) ? '' : 's') .
  169. ':' . $_SERVER['QUERY_STRING'];
  170. } else {
  171. $filename = str_replace("\\", "/",
  172. realpath($document_root . $_SERVER['QUERY_STRING']));
  173. }
  174. } elseif (substr($_SERVER['QUERY_STRING'], 0, 4) !== 'http') {
  175. $filename = str_replace("\\", "/",
  176. realpath($website_root . '/' . $_SERVER['QUERY_STRING']));
  177. }
  178. /* get external files */
  179. if (substr($_SERVER['QUERY_STRING'], 0, 4) === 'http') {
  180. $filename = substr(str_replace("\\", "/", dirname(__FILE__)) .
  181. '/' . str_replace(array('/', '?', '&'),
  182. array('-', '-', '-'),
  183. $_SERVER['QUERY_STRING']), 0, 250);
  184. $mtime = @filemtime($filename);
  185. if (!@is_file($filename) || (time() - $mtime > 86400)) {
  186. if (@function_exists('curl_init')) {
  187. /* start curl */
  188. $ch = @curl_init($_SERVER['QUERY_STRING']);
  189. $fp = @fopen($filename, "w");
  190. if ($fp && $ch) {
  191. @curl_setopt($ch, CURLOPT_FILE, $fp);
  192. @curl_setopt($ch, CURLOPT_HEADER, 0);
  193. @curl_setopt($ch, CURLOPT_USERAGENT, "Web Optimizer Downloader");
  194. @curl_setopt($ch, CURLOPT_ENCODING, "");
  195. @curl_setopt($ch, CURLOPT_TIMEOUT, 5);
  196. @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  197. @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  198. @curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  199. @curl_exec($ch);
  200. @curl_close($ch);
  201. @fclose($fp);
  202. }
  203. /* redirect if can't download */
  204. if (!@is_file($filename)) {
  205. header("Location: " . $_SERVER['QUERY_STRING']);
  206. die();
  207. }
  208. /* redirect if no curl */
  209. } else {
  210. header("Location: " . $_SERVER['QUERY_STRING']);
  211. die();
  212. }
  213. }
  214. }
  215. /* check if we inside document root */
  216. if (strpos($filename, $document_root) !== false && !empty($extension)) {
  217. /* set correct content-encoding header */
  218. header('Content-Type: ' . $extension);
  219. $mtime = empty($mtime) ? @filemtime($filename) : $mtime;
  220. $mtime = empty($mtime) ? $_SERVER['REQUEST_TIME'] : $mtime;
  221. $contents = '';
  222. if ($gzip) {
  223. $gz = $xgzip = $deflate = $xdeflate = 0;
  224. if (!empty($_SERVER["HTTP_ACCEPT_ENCODING"])) {
  225. $gz = strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "gzip") !== false ||
  226. !empty($_COOKIE["_wo_gzip"]);
  227. $xgzip = strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "x-gzip") !== false;
  228. $deflate = strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "deflate") !== false;
  229. $xdeflate = strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "x-deflate") !== false;
  230. }
  231. /* Determine used compression method */
  232. $encoding = $gz ? "gzip" : ($xgzip ? "x-gzip" : ($deflate ? "deflate" : ($xdeflate ? "x-deflate" : "")));
  233. $gzip = 0;
  234. if (!empty($encoding)) {
  235. /* Check for buggy versions of Internet Explorer */
  236. if (!empty($_SERVER["HTTP_USER_AGENT"]) &&
  237. !strstr($_SERVER["HTTP_USER_AGENT"], "Opera") &&
  238. preg_match("/^Mozilla\/4\.0 \(compatible; MSIE ([0-9]\.[0-9])/i",
  239. $_SERVER["HTTP_USER_AGENT"], $matches)) {
  240. /* IE6- can loose first 2048 bytes of gzipped content, code from Bitrix */
  241. if (floatval($matches[1]) < 7) {
  242. $contents = str_repeat(" ", 2048) . "\r\n";
  243. }
  244. }
  245. $gzip = 1;
  246. }
  247. }
  248. /* calculate ETag, mimicry to default Apache settings */
  249. $hash = dec_to_hex(@fileinode($filename)) . '-' .
  250. dec_to_hex(@filesize($filename)) . '-' .
  251. dec_to_hex($mtime) . ($gzip ? '-gzip' : '');
  252. if ((isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
  253. stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) == '"' . $hash . '"') ||
  254. (isset($_SERVER['HTTP_IF_MATCH']) &&
  255. stripslashes($_SERVER['HTTP_IF_MATCH']) == '"' . $hash . '"')) {
  256. /* return visit and no modifications, so do not send anything */
  257. header('HTTP/1.0 304 Not Modified');
  258. header('Content-Length: 0');
  259. exit();
  260. } else {
  261. /* set correct Content-Disposition to correct end-filename */
  262. $slash = strrpos($filename, '/');
  263. header('Content-Disposition: inline;filename=' .
  264. substr($filename, $slash + 1, strlen($filename) - $slash) .
  265. ';modification-date="' .
  266. date("r", $mtime) .
  267. '";');
  268. /* set ETag */
  269. header('ETag: "' . $hash . '"');
  270. /* cache timeout */
  271. $timeout = 360000000;
  272. /* set Cache-Control header */
  273. header('Cache-Control: public, max-age=' . $timeout);
  274. if (function_exists('date_default_timezone_set')) {
  275. @date_default_timezone_set(@date_default_timezone_get());
  276. }
  277. /* define cached filename */
  278. $cached = $extension == 'text/css' ? dirname(__FILE__) . '/wss' . md5($filename) . '.css' : $filename;
  279. /* set Expires header */
  280. header('Expires: ' .
  281. gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $timeout). ' GMT');
  282. /* create gzipped file */
  283. if ($gzip) {
  284. /* try to get gzipped content from file */
  285. $extension = strpos($encoding, "gzip") !== false ? 'gz' : 'df';
  286. $compressed = $cached . '.' . $extension;
  287. /* check file's existence and its mtime */
  288. if (!@is_file($compressed) || @filemtime($compressed) !== $mtime || !($contents = @file_get_contents($compressed))) {
  289. $content = @file_get_contents($cached);
  290. if (!empty($content)) {
  291. /* Make compressed contents */
  292. if ($extension === 'gz') {
  293. $contents = @gzencode($content, $gzip_level, FORCE_GZIP);
  294. } else {
  295. $contents = @gzdeflate($content, $gzip_level);
  296. }
  297. if (!empty($contents)) {
  298. $fp = @fopen($compressed, "wb");
  299. if ($fp) {
  300. @fwrite($fp, $contents);
  301. @fclose($fp);
  302. /* set the same mtime for compressed file as for the main one */
  303. @touch($compressed, $mtime);
  304. }
  305. } else {
  306. $contents = $content;
  307. $gzip = 0;
  308. }
  309. /* create CSS file in cache with rewritten urls */
  310. } elseif ($cached != $filename) {
  311. $contents = replace_urls($cached, $filename, $document_root);
  312. $gzip = 0;
  313. } else {
  314. $contents = $content;
  315. }
  316. }
  317. if ($gzip) {
  318. header('Content-Encoding: ' . $encoding);
  319. }
  320. header('Content-Length: ' . strlen($contents));
  321. } else {
  322. $contents = @file_get_contents($cached);
  323. if (empty($contents) && $cached != $filename) {
  324. $contents = replace_urls($cached, $filename, $document_root);
  325. }
  326. }
  327. /* finally output content */
  328. echo $contents;
  329. }
  330. /* else just redirect to resource, maybe server can give it */
  331. } else {
  332. header("Location: " . $_SERVER['QUERY_STRING']);
  333. die();
  334. }
  335. ?>