1
0
mirror of https://github.com/mrclay/minify.git synced 2025-08-11 16:44:44 +02:00

Work on: Issue 120, Issue 170, Issue 152, Issue 125, Issue 134, Issue 143

Broke some tests
This commit is contained in:
Steve Clay
2010-05-10 07:44:40 +00:00
parent f4c688b338
commit 02dbf14c8e
17 changed files with 259 additions and 111 deletions

View File

@@ -16,12 +16,14 @@ See UPGRADING.txt for instructions.
INSTALLATION AND USAGE:
1. Place the /min/ directory as a child of your DOCUMENT_ROOT
directory: i.e. you will have: /home/user/www/public_html/min
directory: i.e. you will have: /home/user/www/min
2. Open http://yourdomain/min/ in a web browser. This will forward
you to the Minify URI Builder application, which will help you
quickly start using Minify to serve content on your site.
See the User Guide: http://code.google.com/p/minify/wiki/UserGuide
UNIT TESTING:
@@ -36,12 +38,6 @@ components with more verbose output.)
3. Remove /min_unit_tests/ from your DOCUMENT_ROOT when you are done.
EXTRAS:
The min_extras folder contains files for benchmarking using Apache ab on Windows
and a couple single-use tools. DO NOT place this on your production server.
FILE ENCODINGS
Minify *should* work fine with files encoded in UTF-8 or other 8-bit

View File

@@ -1,4 +1,13 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^([a-z]=.*) index.php?$1 [L,NE]
</IfModule>
# You may need RewriteBase on some servers
#RewriteBase /min
# rewrite URLs like "/min/f=..." to "/min/?f=..."
RewriteRule ^([bfg]=.*) index.php?$1 [L,NE]
</IfModule>
<IfModule mod_env.c>
# In case AddOutputFilterByType has been added
SetEnv no-gzip
</IfModule>

View File

@@ -66,14 +66,14 @@ to the /js and /themes/default directories, use:
$min_serveOptions['minApp']['allowDirs'] = array('//js', '//themes/default');
GROUPS: FASTER PERFORMANCE AND BETTER URLS
GROUPS: NICER URLS
For the best performance, edit groupsConfig.php to pre-specify groups of files
For nicer URLs, edit groupsConfig.php to pre-specify groups of files
to be combined under preset keys. E.g., here's an example configuration in
groupsConfig.php:
return array(
'js' => array('//js/Class.js', '//js/email.js')
return array(
'js' => array('//js/Class.js', '//js/email.js')
);
This pre-selects the following files to be combined under the key "js":

View File

@@ -202,7 +202,7 @@ var MUB = {
$('#sources').html('');
$('#add button').click(MUB.addButtonClick);
// make easier to copy text out of
$('#uriHtml, #groupConfig').click(function () {
$('#uriHtml, #groupConfig, #symlinkOpt').click(function () {
this.select();
}).focus(function () {
this.select();
@@ -223,10 +223,9 @@ var MUB = {
return false;
}).attr({title:'Add file +'});
} else {
// copy bookmarklet code into href
var bmUri = location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1);
// setup bookmarklet 1
$.ajax({
url : '../?f=' + bmUri
url : '../?f=' + location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1)
,success : function (code) {
$('#bm')[0].href = code
.replace('%BUILDER_URL%', location.href)
@@ -237,6 +236,14 @@ var MUB = {
$.browser.msie && $('#getBm p:last').append(' Sorry, not supported in MSIE!');
MUB.addButtonClick();
}
// setup bookmarklet 2
$.ajax({
url : '../?f=' + location.pathname.replace(/\/[^\/]*$/, '/bm2.js').substr(1)
,success : function (code) {
$('#bm2')[0].href = code.replace(/\n/g, ' ');
}
,dataType : 'text'
});
MUB.checkRewrite();
}
};

14
min/builder/bm2.js Normal file
View File

@@ -0,0 +1,14 @@
javascript:(function(){
var d = document
,c = d.cookie
,m = c.match(/\bminDebug=([^; ]+)/)
,v = m ? decodeURIComponent(m[1]) : ''
,p = prompt('Debug Minify URIs on "' + location.hostname + '" \ncontaining: (empty to disable)', v)
;
if (p === null) return;
p = p.replace(/\s+/g, '');
v = (p === '')
? 'minDebug=; expires=Fri, 27 Jul 2001 02:47:11 UTC; path=/'
: 'minDebug=' + encodeURIComponent(p) + '; path=/';
d.cookie = v;
})();

View File

@@ -8,6 +8,20 @@ if (phpversion() < 5) {
$encodeOutput = (function_exists('gzdeflate')
&& !ini_get('zlib.output_compression'));
// recommend $min_symlinks setting for Apache UserDir
$symlinkOption = '';
if (0 === strpos($_SERVER["SERVER_SOFTWARE"], 'Apache/')
&& preg_match('@^/\\~(\\w+)/@', $_SERVER['REQUEST_URI'], $m)
) {
$userDir = DIRECTORY_SEPARATOR . $m[1] . DIRECTORY_SEPARATOR;
if (false !== strpos(__FILE__, $userDir)) {
$sm = array();
$sm["//~{$m[1]}"] = dirname(dirname(__FILE__));
$array = str_replace('array (', 'array(', var_export($sm, 1));
$symlinkOption = "\$min_symlinks = $array;";
}
}
require dirname(__FILE__) . '/../config.php';
if (! $min_enableBuilder) {
@@ -18,8 +32,8 @@ if (! $min_enableBuilder) {
ob_start();
?>
<!DOCTYPE HTML>
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<title>Minify URI Builder</title>
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<style type="text/css">
body {margin:1em 60px;}
h1, h2, h3 {margin-left:-25px; position:relative;}
@@ -39,14 +53,24 @@ b {color:#c00}
.topWarning a {color:#fff;}
</style>
<body>
<?php if ($symlinkOption): ?>
<div class=topNote><strong>Note:</strong> It looks like you're running Minify in a user
directory. You may need the following option in /min/config.php to have URIs
correctly rewritten in CSS output:
<br><textarea id=symlinkOpt rows=3 cols=80 readonly><?php echo htmlspecialchars($symlinkOption); ?></textarea>
</div>
<?php endif; ?>
<p class=topWarning id=jsDidntLoad><strong>Uh Oh.</strong> Minify was unable to
serve the Javascript for this app. <a href="http://code.google.com/p/minify/wiki/Debugging">Enable
FirePHP debugging</a> and request the <a id=builderScriptSrc href=#>Minify URL</a> directly.
serve the Javascript for this app. To troubleshoot this,
<a href="http://code.google.com/p/minify/wiki/Debugging">enable FirePHP debugging</a>
and request the <a id=builderScriptSrc href=#>Minify URL</a> directly. Hopefully the
FirePHP console will report the cause of the error.
</p>
<?php if (! isset($min_cachePath)): ?>
<p class=topNote><strong>Note:</strong> Please set <code>$min_cachePath</code>
in /min/config.php to improve performance.</p>
<p class=topNote><strong>Note:</strong> You can set <code>$min_cachePath</code>
in /min/config.php to slightly improve performance.</p>
<?php endIf; ?>
<p id=minRewriteFailed class="hide"><strong>Note:</strong> Your webserver does not seem to
@@ -111,14 +135,21 @@ in your list, and move any others to the top of the first file in your list
<p>If you desire, you can use Minify URIs in imports and they will not be touched
by Minify. E.g. <code>@import "<span class=minRoot>/min/?</span>g=css2";</code></p>
<h3>Debug Mode</h3>
<p>When /min/config.php has <code>$min_allowDebugFlag = <strong>true</strong>;</code>
you can get debug output by appending <code>&amp;debug</code> to a Minify URL, or
by sending the cookie <code>minDebug=&lt;match&gt;</code>, where <code>minDebug=&lt;match&gt;</code>
should match the Minify URIs you'd like to debug. This bookmarklet will allow you to
set this cookie.</p>
<p><a id=bm2>Minify Debug</a> <small>(right-click, add to bookmarks)</small></p>
</div><!-- #app -->
<hr>
<p>Need help? Search or post to the <a class=ext
href="http://groups.google.com/group/minify">Minify discussion list</a>.</p>
<p><small>This app is minified :) <a class=ext
href="http://code.google.com/p/minify/source/browse/trunk/min/builder/index.php">view
source</a></small></p>
<p>Need help? Check the <a href="http://code.google.com/p/minify/w/list?can=3">wiki</a>,
or post to the <a class=ext href="http://groups.google.com/group/minify">discussion
list</a>.</p>
<p><small>This app is minified :)</small></p>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
@@ -163,9 +194,22 @@ $(function () {
</script>
</body>
<?php
$content = ob_get_clean();
$serveOpts = array(
'content' => ob_get_contents()
// setup Minify
set_include_path(dirname(__FILE__) . '/../lib' . PATH_SEPARATOR . get_include_path());
require 'Minify.php';
if (0 === stripos(PHP_OS, 'win')) {
Minify::setDocRoot(); // we may be on IIS
}
Minify::setCache(
isset($min_cachePath) ? $min_cachePath : ''
,$min_cacheFileLocking
);
Minify::$uploaderHoursBehind = $min_uploaderHoursBehind;
Minify::serve('Page', array(
'content' => $content
,'id' => __FILE__
,'lastModifiedTime' => max(
// regenerate cache if either of these change
@@ -174,17 +218,4 @@ $serveOpts = array(
)
,'minifyAll' => true
,'encodeOutput' => $encodeOutput
);
ob_end_clean();
set_include_path(dirname(__FILE__) . '/../lib' . PATH_SEPARATOR . get_include_path());
require 'Minify.php';
if (0 === stripos(PHP_OS, 'win')) {
Minify::setDocRoot(); // we may be on IIS
}
Minify::setCache(isset($min_cachePath) ? $min_cachePath : null);
Minify::$uploaderHoursBehind = $min_uploaderHoursBehind;
Minify::serve('Page', $serveOpts);
));

View File

@@ -7,22 +7,12 @@
*/
/**
* In 'debug' mode, Minify can combine files with no minification and
* add comments to indicate line #s of the original files.
*
* To allow debugging, set this option to true and add "&debug=1" to
* a URI. E.g. /min/?f=script1.js,script2.js&debug=1
*/
$min_allowDebugFlag = false;
/**
* Set to true to log messages to FirePHP (Firefox Firebug addon).
* Set to false for no error logging (Minify may be slightly faster).
* @link http://www.firephp.org/
*
* If you want to use a custom error logger, set this to your logger
* If you want to use a custom error logger, set this to your logger
* instance. Your object should have a method log(string $message).
*
* @todo cache system does not have error logging yet.
@@ -30,6 +20,21 @@ $min_allowDebugFlag = false;
$min_errorLogger = false;
/**
* To allow debugging, you must set this option to true.
*
* Once true, you can send the cookie minDebug to request debug mode output. The
* cookie value should match the URIs you'd like to debug. E.g. to debug
* /min/f=file1.js send the cookie minDebug=file1.js
* You can manually enable debugging by appending "&debug" to a URI.
* E.g. /min/?f=script1.js,script2.js&debug
*
* In 'debug' mode, Minify combines files with no minification and adds comments
* to indicate line #s of the original files.
*/
$min_allowDebugFlag = false;
/**
* Allow use of the Minify URI Builder app. If you no longer need
* this, set to false.

View File

@@ -35,8 +35,15 @@ foreach ($min_symlinks as $uri => $target) {
$min_serveOptions['minApp']['allowDirs'][] = $target;
}
if ($min_allowDebugFlag && isset($_GET['debug'])) {
$min_serveOptions['debug'] = true;
if ($min_allowDebugFlag) {
if (! empty($_COOKIE['minDebug'])
&& false !== strpos($_SERVER['REQUEST_URI'], $_COOKIE['minDebug'])) {
$min_serveOptions['debug'] = true;
}
// allow GET to override
if (isset($_GET['debug'])) {
$min_serveOptions['debug'] = true;
}
}
if ($min_errorLogger) {

View File

@@ -75,9 +75,8 @@ class HTTP_ConditionalGet {
/**
* @param array $spec options
*
* 'isPublic': (bool) if true, the Cache-Control header will contain
* "public", allowing proxies to cache the content. Otherwise "private" will
* be sent, allowing only browser caching. (default false)
* 'isPublic': (bool) if false, the Cache-Control header will contain
* "private", allowing only browser caching. (default false)
*
* 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers
* will be sent with content. This is recommended.
@@ -150,7 +149,10 @@ class HTTP_ConditionalGet {
} elseif (isset($spec['contentHash'])) { // Use the hash as the ETag
$this->_setEtag($spec['contentHash'] . $etagAppend, $scope);
}
$this->_headers['Cache-Control'] = "max-age={$maxAge}, {$scope}";
$privacy = ($scope === 'private')
? ', private'
: '';
$this->_headers['Cache-Control'] = "max-age={$maxAge}{$privacy}";
// invalidate cache if disabled, otherwise check
$this->cacheIsValid = (isset($spec['invalidate']) && $spec['invalidate'])
? false
@@ -332,11 +334,8 @@ class HTTP_ConditionalGet {
if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
return false;
}
$ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
if (false !== ($semicolon = strrpos($ifModifiedSince, ';'))) {
// IE has tacked on extra data to this header, strip it
$ifModifiedSince = substr($ifModifiedSince, 0, $semicolon);
}
// strip off IE's extra data (semicolon)
list($ifModifiedSince) = explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE'], 2);
if (strtotime($ifModifiedSince) >= $this->_lmTime) {
// Apache 2.2's behavior. If there was no ETag match, send the
// non-encoded version of the ETag value.

View File

@@ -171,7 +171,8 @@ class JSMin {
}
if (ord($this->a) <= self::ORD_LF) {
throw new JSMin_UnterminatedStringException(
"Unterminated String: {$str}");
"JSMin: Unterminated String at byte "
. $this->inputIndex . ": {$str}");
}
$str .= $this->a;
if ($this->a === '\\') {
@@ -198,7 +199,8 @@ class JSMin {
$pattern .= $this->a;
} elseif (ord($this->a) <= self::ORD_LF) {
throw new JSMin_UnterminatedRegExpException(
"Unterminated RegExp: {$pattern}");
"JSMin: Unterminated RegExp at byte "
. $this->inputIndex .": {$pattern}");
}
$this->output .= $this->a;
}
@@ -310,7 +312,9 @@ class JSMin {
return ' ';
}
} elseif ($get === null) {
throw new JSMin_UnterminatedCommentException("Unterminated Comment: /*{$comment}");
throw new JSMin_UnterminatedCommentException(
"JSMin: Unterminated comment at byte "
. $this->inputIndex . ": /*{$comment}");
}
$comment .= $get;
}

View File

@@ -227,6 +227,8 @@ class Minify {
);
if (self::$_options['maxAge'] > 0) {
$cgOptions['maxAge'] = self::$_options['maxAge'];
} elseif (self::$_options['debug']) {
$cgOptions['invalidate'] = true;
}
$cg = new HTTP_ConditionalGet($cgOptions);
if ($cg->cacheIsValid) {
@@ -267,7 +269,7 @@ class Minify {
// the goal is to use only the cache methods to sniff the length and
// output the content, as they do not require ever loading the file into
// memory.
$cacheId = 'minify_' . self::_getCacheId();
$cacheId = self::_getCacheId();
$fullCacheId = (self::$_options['encodeMethod'])
? $cacheId . '.gz'
: $cacheId;
@@ -489,7 +491,12 @@ class Minify {
if ($minifier) {
self::$_controller->loadMinifier($minifier);
// get source content and minify it
$pieces[] = call_user_func($minifier, $source->getContent(), $options);
try {
$pieces[] = call_user_func($minifier, $source->getContent(), $options);
} catch (Exception $e) {
throw new Exception("Exception in " . $source->getId() .
": " . $e->getMessage());
}
} else {
$pieces[] = $source->getContent();
}
@@ -515,17 +522,23 @@ class Minify {
*
* Any settings that could affect output are taken into consideration
*
* @param string $prefix
*
* @return string
*/
protected static function _getCacheId()
protected static function _getCacheId($prefix = 'minify')
{
return md5(serialize(array(
$name = preg_replace('/[^a-zA-Z0-9\\.=_,]/', '', self::$_controller->selectionId);
$name = preg_replace('/\\.+/', '.', $name);
$name = substr($name, 0, 250 - 34 - strlen($prefix));
$md5 = md5(serialize(array(
Minify_Source::getDigest(self::$_controller->sources)
,self::$_options['minifiers']
,self::$_options['minifierOptions']
,self::$_options['postprocessor']
,self::$_options['bubbleCssImports']
)));
return "{$prefix}_{$name}_{$md5}";
}
/**

View File

@@ -144,6 +144,15 @@ abstract class Minify_Controller_Base {
*/
public $sources = array();
/**
* The setupSources() method may choose to set this, making it easier to
* recognize a particular set of sources/settings in the cache folder. It
* will be filtered and truncated to make the final cache id <= 250 bytes.
*
* @var string short name to place inside cache id
*/
public $selectionId = '';
/**
* Mix in default controller options with user-given options
*

View File

@@ -40,7 +40,8 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
$this->log("A group configuration for \"{$_GET['g']}\" was not set");
return $options;
}
$this->selectionId = "g=" . $_GET['g'];
$files = $cOptions['groups'][$_GET['g']];
// if $files is a single object, casting will break it
if (is_object($files)) {
@@ -70,7 +71,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
// respond to. Ideally there should be only one way to reference a file.
if (// verify at least one file, files are single comma separated,
// and are all same extension
! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f'])
! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f'], $m)
// no "//"
|| strpos($_GET['f'], '//') !== false
// no "\"
@@ -81,11 +82,13 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
$this->log("GET param 'f' invalid (see MinApp.php line 63)");
return $options;
}
$ext = ".{$m[1]}";
$files = explode(',', $_GET['f']);
if ($files != array_unique($files)) {
$this->log("Duplicate files specified");
return $options;
}
if (isset($_GET['b'])) {
// check for validity
if (preg_match('@^[^/]+(?:/[^/]+)*$@', $_GET['b'])
@@ -104,6 +107,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
foreach ((array)$cOptions['allowDirs'] as $allowDir) {
$allowDirs[] = realpath(str_replace('//', $_SERVER['DOCUMENT_ROOT'] . '/', $allowDir));
}
$basenames = array(); // just for cache id
foreach ($files as $file) {
$path = $_SERVER['DOCUMENT_ROOT'] . $base . $file;
$file = realpath($path);
@@ -115,8 +119,10 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
return $options;
} else {
$sources[] = $this->_getFileSource($file, $cOptions);
$basenames[] = basename($file, $ext);
}
}
$this->selectionId = implode(',', $basenames) . $ext;
}
if ($sources) {
$this->sources = $sources;

View File

@@ -40,14 +40,19 @@ class Minify_Controller_Page extends Minify_Controller_Base {
$sourceSpec = array(
'filepath' => $options['file']
);
$f = $options['file'];
} else {
// strip controller options
$sourceSpec = array(
'content' => $options['content']
,'id' => $options['id']
);
$f = $options['id'];
unset($options['content'], $options['id']);
}
// something like "builder,index.php" or "directory,file.html"
$this->selectionId = strtr(substr($f, 1 + strlen(dirname(dirname($f)))), '/\\', ',,');
if (isset($options['minifyAll'])) {
// this will be the 2nd argument passed to Minify_HTML::minify()
$sourceSpec['minifyOptions'] = array(

4
min_unit_tests/.htaccess Normal file
View File

@@ -0,0 +1,4 @@
<IfModule mod_env.c>
# In case AddOutputFilterByType has been added
SetEnv no-gzip
</IfModule>

View File

@@ -29,7 +29,7 @@ function test_Minify()
'Vary' => 'Accept-Encoding',
'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified),
'ETag' => "\"pub{$lastModified}\"",
'Cache-Control' => 'max-age=1800, public',
'Cache-Control' => 'max-age=1800',
'_responseCode' => 'HTTP/1.0 304 Not Modified',
)
);
@@ -49,7 +49,7 @@ function test_Minify()
assertTrue(
! class_exists('Minify_CSS', false)
&& ! class_exists('Minify_Cache', false)
&& ! class_exists('Minify_Cache_File', false)
,'Minify : cache, and minifier classes aren\'t loaded for 304s'
);
@@ -70,11 +70,13 @@ function test_Minify()
'Vary' => 'Accept-Encoding',
'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified),
'ETag' => "\"pub{$lastModified}\"",
'Cache-Control' => 'max-age=86400, public',
'Cache-Control' => 'max-age=86400',
'Content-Length' => strlen($content),
'Content-Type' => 'application/x-javascript; charset=utf-8',
)
);
unset($_SERVER['HTTP_IF_NONE_MATCH']);
unset($_SERVER['HTTP_IF_MODIFIED_SINCE']);
$output = Minify::serve('Files', array(
'files' => array(
$minifyTestPath . '/email.js'
@@ -185,7 +187,7 @@ function test_Minify()
'Vary' => 'Accept-Encoding',
'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified),
'ETag' => "\"pub{$lastModified}\"",
'Cache-Control' => 'max-age=0, public',
'Cache-Control' => 'max-age=0',
'Content-Length' => strlen($expectedContent),
'Content-Type' => 'text/css; charset=utf-8',
)

View File

@@ -1,5 +1,7 @@
<?php
//phpinfo(); exit();
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
// called directly
if (isset($_GET['getOutputCompression'])) {
@@ -9,6 +11,10 @@ if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
if (isset($_GET['hello'])) {
// try to disable (may not work)
ini_set('zlib.output_compression', '0');
$type = ($_GET['hello'] == 'js')
? 'application/x-javascript'
: "text/{$_GET['hello']}";
header("Content-Type: {$type}");
echo 'World!';
exit();
}
@@ -60,42 +66,73 @@ function test_environment()
echo "!WARN: environment : zlib.output_compression is enabled in php.ini"
. " or .htaccess.\n";
}
$fp = fopen($thisUrl . '?hello=1', 'r', false, stream_context_create(array(
'http' => array(
'method' => "GET",
'header' => "Accept-Encoding: deflate, gzip\r\n"
)
)));
$meta = stream_get_meta_data($fp);
$passed = true;
foreach ($meta['wrapper_data'] as $i => $header) {
if ((preg_match('@^Content-Length: (\\d+)$@i', $header, $m) && $m[1] !== '6')
|| preg_match('@^Content-Encoding:@i', $header, $m)
) {
$passed = false;
break;
}
}
$streamContents = stream_get_contents($fp);
if ($passed && $streamContents !== 'World!') {
$passed = false;
}
assertTrue(
$passed
,'environment : PHP/server does not auto-HTTP-encode content'
$testJs = _test_environment_getHello($thisUrl . '?hello=js');
$passed = assertTrue(
$testJs['length'] == 6
,'environment : PHP/server should not auto-encode application/x-javascript output'
);
fclose($fp);
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
if (! $passed) {
echo "\nReturned content should be 6 bytes and not HTTP encoded.\n"
. "Headers returned by: {$thisUrl}?hello=1\n\n";
var_export($meta['wrapper_data']);
$testCss = _test_environment_getHello($thisUrl . '?hello=css');
$passed = $passed && assertTrue(
$testCss['length'] == 6
,'environment : PHP/server should not auto-encode text/css output'
);
$testHtml = _test_environment_getHello($thisUrl . '?hello=html');
$passed = $passed && assertTrue(
$testHtml['length'] == 6
,'environment : PHP/server should not auto-encode text/html output'
);
if (! $passed) {
$testFake = _test_environment_getHello($thisUrl . '?hello=faketype');
if ($testFake['length'] == 6) {
echo "!NOTE: environment : Server does not auto-encode arbitrary types. This\n"
. " may indicate that the auto-encoding is caused by Apache's \n"
. " AddOutputFilterByType.";
}
}
}
function _test_environment_getHello($url)
{
$fp = fopen($url, 'r', false, stream_context_create(array(
'http' => array(
'method' => "GET",
'timeout' => '10',
'header' => "Accept-Encoding: deflate, gzip\r\n",
)
)));
$meta = stream_get_meta_data($fp);
$encoding = '';
$length = 0;
foreach ($meta['wrapper_data'] as $i => $header) {
if (preg_match('@^Content-Length:\\s*(\\d+)$@i', $header, $m)) {
$length = $m[1];
} elseif (preg_match('@^Content-Encoding:\\s*(\\S+)$@i', $header, $m)) {
if ($m[1] !== 'identity') {
$encoding = $m[1];
}
}
}
$streamContents = stream_get_contents($fp);
fclose($fp);
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
if ($length != 6) {
echo "\nReturned content should be 6 bytes and not HTTP encoded.\n"
. "Headers returned by: {$url}\n\n";
var_export($meta['wrapper_data']);
echo "\n\n";
}
}
return array(
'length' => $length
,'encoding' => $encoding
,'bytes' => $streamContents
);
}
test_environment();