PageRenderTime 61ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/administrator/components/com_extplorer/fetchscript.php

https://github.com/cavila/Astica
PHP | 268 lines | 179 code | 33 blank | 56 comment | 55 complexity | 40ddcc9e560b62ee9723b33edff3a182 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * This file is used to send gzipped Javascripts and Stylesheets to the browser
  4. *
  5. * It expects three parameters:
  6. *
  7. * gzip (can be 1 or 0, for yes or no; default: 0)
  8. * subdir[INDEX] (relative directory from /components/com_virtuemart/js)
  9. * file[INDEX] (filename only)
  10. * where INDEX is the actual number of the file to be included, so you can include multiple scripts at a time
  11. *
  12. * @version $Id: fetchscript.php 196 2011-06-14 08:00:04Z soeren $
  13. * @package eXtplorer
  14. * @copyright Copyright (C) 2006-2007 Soeren Eberhardt. All rights reserved.
  15. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  16. * VirtueMart is free software. This version may have been modified pursuant
  17. * to the GNU General Public License, and as distributed it includes or
  18. * is derivative of works licensed under the GNU General Public License or
  19. * other free or open source software licenses.
  20. *
  21. * http://virtuemart.net
  22. */
  23. /**
  24. * Initialise GZIP
  25. * @author Mambo / Joomla Project
  26. */
  27. function initGzip() {
  28. global $do_gzip_compress;
  29. $gzip = isset( $_GET['gzip'] ) ? (boolean)$_GET['gzip'] : false;
  30. $do_gzip_compress = FALSE;
  31. if ($gzip) {
  32. $phpver = phpversion();
  33. $useragent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
  34. $canZip = isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '';
  35. $gzip_check = 0;
  36. $zlib_check = 0;
  37. $gz_check = 0;
  38. $zlibO_check = 0;
  39. $sid_check = 0;
  40. if ( strpos( $canZip, 'gzip' ) !== false) {
  41. $gzip_check = 1;
  42. }
  43. if ( extension_loaded( 'zlib' ) ) {
  44. $zlib_check = 1;
  45. }
  46. if ( function_exists('ob_gzhandler') ) {
  47. $gz_check = 1;
  48. }
  49. if ( ini_get('zlib.output_compression') ) {
  50. $zlibO_check = 1;
  51. }
  52. if ( $phpver >= '4.0.4pl1' && ( strpos($useragent,'compatible') !== false || strpos($useragent,'Gecko') !== false ) ) {
  53. // Check for gzip header or norton internet securities
  54. if ( ( $gzip_check || isset( $_SERVER['---------------']) ) && $zlib_check && $gz_check && !$zlibO_check ) {
  55. // You cannot specify additional output handlers if
  56. // zlib.output_compression is activated here
  57. ob_start( 'ob_gzhandler' );
  58. return;
  59. }
  60. } else if ( $phpver > '4.0' ) {
  61. if ( $gzip_check ) {
  62. if ( $zlib_check ) {
  63. $do_gzip_compress = TRUE;
  64. ob_start();
  65. ob_implicit_flush(0);
  66. header( 'Content-Encoding: gzip' );
  67. return;
  68. }
  69. }
  70. }
  71. }
  72. ob_start();
  73. }
  74. /**
  75. * Perform GZIP
  76. * @author Mambo / Joomla! project
  77. */
  78. function doGzip() {
  79. global $do_gzip_compress;
  80. if ( $do_gzip_compress ) {
  81. /**
  82. *Borrowed from php.net!
  83. */
  84. $gzip_contents = ob_get_contents();
  85. ob_end_clean();
  86. $gzip_size = strlen($gzip_contents);
  87. $gzip_crc = crc32($gzip_contents);
  88. $gzip_contents = gzcompress($gzip_contents, 9);
  89. $gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);
  90. echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
  91. echo $gzip_contents;
  92. echo pack('V', $gzip_crc);
  93. echo pack('V', $gzip_size);
  94. } else {
  95. ob_end_flush();
  96. }
  97. }
  98. /**
  99. * This function fixes the URLs used in the CSS file
  100. * This is necessary, because this file is (usually) located somewhere else than the CSS file! That makes
  101. * relative URL references point to wrong directories - so we need to fix that!
  102. */
  103. function cssUrl( $ref, $subdir ) {
  104. $ref = str_replace( "'", '', stripslashes( $ref ));
  105. $ref = trim( str_replace( '"', '', $ref) );
  106. // Absolute References don't need to be fixed
  107. if( substr( $ref, 0, 4 ) == 'http' ) {
  108. return 'url( "'. $ref.'" )';
  109. }
  110. chdir( dirname( __FILE__ ).'/'.$subdir );
  111. $ref = str_replace( dirname( __FILE__ ), '', realpath( $ref ));
  112. $ref = str_replace( "\\", '/', $ref );
  113. return 'url( "'. substr( $ref, 1 ).'" )';
  114. }
  115. /**
  116. * Checks and sets HTTP headers for conditional HTTP requests
  117. * Borrowed from DokuWiki (/lib/exe/fetch.php)
  118. * @author Simon Willison <swillison@gmail.com>
  119. * @link http://simon.incutio.com/archive/2003/04/23/conditionalGet
  120. */
  121. function http_conditionalRequest($timestamp){
  122. // A PHP implementation of conditional get, see
  123. // http://fishbowl.pastiche.org/archives/001132.html
  124. $last_modified = gmdate( 'D, d M Y H:i:s', $timestamp ) . ' GMT';
  125. $etag = '"'.md5($last_modified).'"';
  126. // Send the headers
  127. header("Last-Modified: $last_modified");
  128. header("ETag: $etag");
  129. // See if the client has provided the required headers
  130. $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
  131. stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
  132. false;
  133. $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
  134. stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) :
  135. false;
  136. if (!$if_modified_since && !$if_none_match) {
  137. return;
  138. }
  139. // At least one of the headers is there - check them
  140. if ($if_none_match && $if_none_match != $etag) {
  141. return; // etag is there but doesn't match
  142. }
  143. if ($if_modified_since && $if_modified_since != $last_modified) {
  144. return; // if-modified-since is there but doesn't match
  145. }
  146. // Nothing has changed since their last request - serve a 304 and exit
  147. header('HTTP/1.0 304 Not Modified');
  148. exit;
  149. }
  150. initGzip();
  151. $base_dir = dirname( __FILE__ );
  152. $subdirs = @$_GET['subdir'];
  153. if( !is_array( $subdirs ) && !empty( $subdirs )) {
  154. $subdirs = array( $subdirs );
  155. }
  156. $files = @$_GET['file'];
  157. if( !is_array( $files ) && !empty( $files )) {
  158. $files = array( $files );
  159. }
  160. if( empty( $files ) || sizeof($files) != sizeof( $subdirs )) {
  161. header("HTTP/1.0 400 Bad Request");
  162. echo 'Bad request';
  163. exit;
  164. }
  165. $countFiles = sizeof($files);
  166. $newest_mdate = 0;
  167. for( $i = 0; $i < $countFiles; $i++ ) {
  168. if( empty( $files[$i] )) continue;
  169. $file = $files[$i];
  170. $subdir = $subdirs[$i];
  171. $dir = realpath( $base_dir . '/' . $subdir );
  172. $file = $dir . '/' . basename( $file );
  173. if( !file_exists( $file ) || (!stristr( $dir, $base_dir ) && !stristr( $dir, "/usr/share/javascript") && !stristr( $dir, "/usr/share/yui")) ) {
  174. if( $countFiles == 1 ) {
  175. header("HTTP/1.0 404 Not Found");
  176. echo 'Not Found';
  177. exit;
  178. }
  179. continue;
  180. }
  181. $newest_mdate = max( filemtime( $file ), $newest_mdate );
  182. }
  183. // This function quits the page load if the browser has a cached version of the requested script.
  184. // It then returns a 304 Not Modified header
  185. http_conditionalRequest( $newest_mdate );
  186. // here we need to send the script or stylesheet
  187. $processed_files = 0;
  188. for( $i = 0; $i < $countFiles; $i++ ) {
  189. $file = addslashes($files[$i]);// fix by colonelxc
  190. $subdir = $subdirs[$i];
  191. $dir = realpath( $base_dir . '/' . $subdir );
  192. $file = $dir . '/' . basename( $file );
  193. if( !file_exists( $file ) || (!stristr( $dir, $base_dir ) && !stristr( $dir, "/usr/share/javascript") && !stristr( $dir, "/usr/share/yui")) || !is_readable( $file )) {
  194. continue;
  195. }
  196. $processed_files++;
  197. $fileinfo = pathinfo( $file );
  198. switch ( $fileinfo['extension']) {
  199. case 'css':
  200. $mime_type = 'text/css';
  201. header( 'Content-Type: '.$mime_type.';');
  202. $css = implode( '', file( $file ));
  203. $str_css = preg_replace("/url\((.+?)\)/ie","cssUrl('\\1', '$subdir')", $css);
  204. echo $str_css;
  205. break;
  206. case 'js':
  207. $mime_type = 'application/x-javascript';
  208. header( 'Content-Type: '.$mime_type.';');
  209. readfile( $file );
  210. break;
  211. default:
  212. continue;
  213. }
  214. }
  215. if( $processed_files == 0 ) {
  216. if( !file_exists( $file ) ) {
  217. header("HTTP/1.0 404 Not Found");
  218. echo 'Not Found';
  219. exit;
  220. }
  221. if( !is_readable( $file ) ) {
  222. header("HTTP/1.0 500 Internal Server Error");
  223. echo "Could not read ".basename($file)." - bad permissions?";
  224. exit;
  225. }
  226. }
  227. // Tell the user agent to cache this script/stylesheet for an hour
  228. $age = 3600;
  229. header( 'Expires: '.gmdate( 'D, d M Y H:i:s', time()+ $age ) . ' GMT' );
  230. header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', @filemtime( $file ) ) . ' GMT' );
  231. header( 'Cache-Control: public, max-age='.$age.', must-revalidate, post-check=0, pre-check=0' );
  232. header( 'Pragma: public' );
  233. doGzip();
  234. exit;
  235. ?>