PHP code example of rosell-dk / htaccess-capability-tester
1. Go to this page and download the library: Download rosell-dk/htaccess-capability-tester library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
rosell-dk / htaccess-capability-tester example snippets
use HtaccessCapabilityTester\HtaccessCapabilityTester;
$hct = new HtaccessCapabilityTester($baseDir, $baseUrl);
if ($hct->moduleLoaded('headers')) {
// mod_headers is loaded (tested in a real .htaccess by using the "IfModule" directive)
}
if ($hct->rewriteWorks()) {
// rewriting works
}
if ($hct->htaccessEnabled() === false) {
// Apache has been configured to ignore .htaccess files
}
// A bunch of other tests are available - see API
/**
* @param string $htaccessRules The rules to check
* @param string $subSubDir subdir for the test files. If not supplied, a fingerprint of the rules will be used
*/
public function __construct($htaccessRules, $subSubDir = null)
{
if (is_null($subSubDir)) {
$subSubDir = hash('md5', $htaccessRules);
}
$test = [
'subdir' => 'crash-tester/' . $subSubDir,
'subtests' => [
[
'subdir' => 'the-suspect',
'files' => [
['.htaccess', $htaccessRules],
['request-me.txt', 'thanks'],
],
'request' => [
'url' => 'request-me.txt',
'bypass-standard-error-handling' => ['all']
],
'interpretation' => [
['success', 'status-code', 'not-equals', '500'],
]
],
[
'subdir' => 'the-innocent',
'files' => [
['.htaccess', '# I am no trouble'],
['request-me.txt', 'thanks'],
],
'request' => [
'url' => 'request-me.txt',
'bypass-standard-error-handling' => ['all']
],
'interpretation' => [
// The suspect crashed. But if the innocent crashes too, we cannot judge
['inconclusive', 'status-code', 'equals', '500'],
// The innocent did not crash. The suspect is guilty!
['failure'],
]
],
]
];
parent::__construct($test);
}
// If we can find anything that works, well the .htaccess must have been proccesed!
if ($hct->serverSignatureWorks() // Override: None, Status: Core, REQUIRES PHP
|| $hct->contentDigestWorks() // Override: Options, Status: Core
|| $hct->addTypeWorks() // Override: FileInfo, Status: Base, Module: mime
|| $hct->directoryIndexWorks() // Override: Indexes, Status: Base, Module: mod_dir
|| $hct->rewriteWorks() // Override: FileInfo, Status: Extension, Module: rewrite
|| $hct->headerSetWorks() // Override: FileInfo, Status: Extension, Module: headers
) {
$status = true;
} else {
// The serverSignatureWorks() test is special because if it comes out as a failure,
// we can be *almost* certain that the .htaccess has been completely disabled
$serverSignatureWorks = $hct->serverSignatureWorks();
if ($serverSignatureWorks === false) {
$status = false;
$info = 'ServerSignature directive does not work - and it is in core';
} else {
// Last bullet in the gun:
// Try an .htaccess with syntax errors in it.
// (we do this lastly because it may generate an entry in the error log)
$crashTestResult = $hct->crashTest('aoeu', 'htaccess-enabled-malformed-htaccess');
if ($crashTestResult === false) {
// It crashed, - which means .htaccess is processed!
$status = true;
$info = 'syntax error in an .htaccess causes crash';
} elseif ($crashTestResult === true) {
// It did not crash. So the .htaccess is not processed, as syntax errors
// makes servers crash
$status = false;
$info = 'syntax error in an .htaccess does not cause crash';
} elseif (is_null($crashTestResult)) {
// It did crash. But so did a request to an innocent text file in a directory
// without a .htaccess file in it. Something is making all requests fail and
// we cannot judge.
$status = null;
$info = 'all requests results in 500 Internal Server Error';
}
}
}
return new TestResult($status, $info);
<IfModule mod_setenvif.c>
Header set X-Response-Header-Test: 1
</IfModule>
<IfModule !mod_setenvif.c>
Header set X-Response-Header-Test: 0
</IfModule>
yaml
subdir: pass-info-from-rewrite-to-script-through-env
files:
- filename: '.htaccess'
content: |
<IfModule mod_rewrite.c>
# Testing if we can pass environment variable from .htaccess to script in a RewriteRule
# We pass document root, because that can easily be checked by the script
RewriteEngine On
RewriteRule ^test\.php$ - [E=PASSTHROUGHENV:%{DOCUMENT_ROOT},L]
</IfModule>
- filename: 'test.php'
content: |
/**
* Get environment variable set with mod_rewrite module
* Return false if the environment variable isn't found
*/
function getEnvPassedInRewriteRule($envName) {
// Environment variables passed through the REWRITE module have "REWRITE_" as a prefix
// (in Apache, not Litespeed, if I recall correctly).
// Multiple iterations causes multiple REWRITE_ prefixes, and we get many environment variables set.
// We simply look for an environment variable that ends with what we are looking for.
// (so make sure to make it unique)
$len = strlen($envName);
foreach ($_SERVER as $key => $item) {
if (substr($key, -$len) == $envName) {
return $item;
}
}
return false;
}
$result = getEnvPassedInRewriteRule('PASSTHROUGHENV');
if ($result === false) {
echo '0';
exit;
}
echo ($result == $_SERVER['DOCUMENT_ROOT'] ? '1' : '0');
request:
url: 'test.php'
interpretation:
- ['success', 'body', 'equals', '1']
- ['failure', 'body', 'equals', '0']
- ['inconclusive', 'body', 'begins-with', '']
- ['inconclusive']
yaml
subdir: pass-info-from-rewrite-to-script-through-request-header
files:
- filename: '.htaccess'
content: |
<IfModule mod_rewrite.c>
RewriteEngine On
# Testing if we can pass an environment variable through a request header
# We pass document root, because that can easily be checked by the script
<IfModule mod_headers.c>
RequestHeader set PASSTHROUGHHEADER "%{PASSTHROUGHHEADER}e" env=PASSTHROUGHHEADER
</IfModule>
RewriteRule ^test\.php$ - [E=PASSTHROUGHHEADER:%{DOCUMENT_ROOT},L]
</IfModule>
- filename: 'test.php'
content: |
if (isset($_SERVER['HTTP_PASSTHROUGHHEADER'])) {
echo ($_SERVER['HTTP_PASSTHROUGHHEADER'] == $_SERVER['DOCUMENT_ROOT'] ? 1 : 0);
exit;
}
echo '0';
request:
url: 'test.php'
interpretation:
- ['success', 'body', 'equals', '1']
- ['failure', 'body', 'equals', '0']
- ['inconclusive', 'body', 'begins-with', '']
- ['inconclusive']
yaml
subdir: request-header
files:
- filename: '.htaccess'
content: |
<IfModule mod_headers.c>
# Certain hosts seem to strip non-standard request headers,
# so we use a standard one to avoid a false negative
RequestHeader set User-Agent "request-header-test"
</IfModule>
- filename: 'test.php'
content: |
if (isset($_SERVER['HTTP_USER_AGENT'])) {
echo $_SERVER['HTTP_USER_AGENT'] == 'request-header-test' ? 1 : 0;
} else {
echo 0;
}
request:
url: 'test.php'
interpretation:
- ['success', 'body', 'equals', '1']
- ['failure', 'body', 'equals', '0']
- ['inconclusive', 'body', 'begins-with', '']