WebP Express CloudHost.es Fix v0.25.9-cloudhost

 Fixed bulk conversion getting stuck on missing files
 Added robust error handling and timeout protection
 Improved JavaScript response parsing
 Added file existence validation
 Fixed missing PHP class imports
 Added comprehensive try-catch error recovery

🔧 Key fixes:
- File existence checks before conversion attempts
- 30-second timeout protection per file
- Graceful handling of 500 errors and JSON parsing issues
- Automatic continuation to next file on failures
- Cache busting for JavaScript updates

🎯 Result: Bulk conversion now completes successfully even with missing files

🚀 Generated with Claude Code (https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-23 10:22:32 +02:00
commit 37cf714058
553 changed files with 55249 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
<?php
namespace HtaccessCapabilityTester\Tests;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\HttpRequesterInterface;
use HtaccessCapabilityTester\TestFilesLineUpperInterface;
use HtaccessCapabilityTester\TestResult;
use HtaccessCapabilityTester\TestResultCache;
use HtaccessCapabilityTester\Testers\AbstractTester;
class FakeServer implements TestFilesLineUpperInterface, HttpRequesterInterface
{
/** @var array Files on the server */
private $files;
/** @var array Files as a map, by filename */
private $filesMap;
/** @var bool If .htaccess processing is disabled */
private $htaccessDisabled = false;
/** @var bool If all directives should be disallowed (but .htaccess still read) */
private $disallowAllDirectives = false;
/** @var bool If server should go fatal about forbidden directives */
private $fatal = false;
/** @var bool If all requests should crash! (500) */
private $crashAll = false;
/** @var bool If access is denied for all requests */
private $accessAllDenied = false;
/** @var bool Returns the php text file rather than "Sorry, this server cannot process PHP!" */
private $handlePHPasText = false;
/** @var bool If all requests fail (without response code) */
private $failAll = false;
/** @var array Predefined responses for certain urls */
private $responses;
public function lineUp($files)
{
$this->files = $files;
$this->filesMap = [];
foreach ($files as $file) {
list($filename, $content) = $file;
$this->filesMap[$filename] = $content;
}
//$m = new SetRequestHeaderTester();
//$m->putFiles('');
//print_r($files);
}
public function makeHttpRequest($url)
{
$body = '';
$statusCode = '200';
$headers = [];
if ($this->failAll) {
return new HttpResponse('', '0', []);
}
//echo 'Fakeserver request:' . $url . "\n";
if (isset($this->responses[$url])) {
//echo 'predefined: ' . $url . "\n";
return $this->responses[$url];
}
if ($this->crashAll) {
return new HttpResponse('', '500', []);
}
if (($this->disallowAllDirectives) && ($this->fatal)) {
$urlToHtaccessInSameFolder = dirname($url) . '/.htaccess';
$doesFolderContainHtaccess = isset($this->filesMap[$urlToHtaccessInSameFolder]);
if ($doesFolderContainHtaccess) {
return new HttpResponse('', '500', []);
}
}
if ($this->accessAllDenied) {
// TODO: what body?
return new HttpResponse('', '403', []);
}
//$simplyServeRequested = ($this->htaccessDisabled || ($this->disallowAllDirectives && (!$this->fatal)));
// Simply return the file that was requested
if (isset($this->filesMap[$url])) {
$isPhpFile = (strrpos($url, '.php') == strlen($url) - 4);
if ($isPhpFile && ($this->handlePHPasText)) {
return new HttpResponse('Sorry, this server cannot process PHP!', '200', []); ;
} else {
return new HttpResponse($this->filesMap[$url], '200', []); ;
}
} else {
return new HttpResponse('Not found', '404', []);
}
//return new HttpResponse('Not found', '404', []);
}
/**
* Disallows all directives, but do still process .htaccess.
*
* In essence: Fail, if the folder contains an .htaccess file
*
* @param string $fatal fatal|nonfatal
*/
public function disallowAllDirectives($fatal)
{
$this->disallowAllDirectives = true;
$this->fatal = ($fatal = 'fatal');
}
public function disableHtaccess()
{
$this->htaccessDisabled = true;
}
public function denyAllAccess()
{
$this->accessAllDenied = true;
}
public function makeAllCrash()
{
$this->crashAll = true;
}
public function failAllRequests()
{
$this->failAll = true;
}
public function handlePHPasText()
{
$this->handlePHPasText = true;
}
// TODO: denyAccessToPHP
/**
* @param array $responses
*/
public function setResponses($responses)
{
$this->responses = $responses;
}
public function connectHCT($hct)
{
TestResultCache::clear();
$hct->setTestFilesLineUpper($this);
$hct->setHttpRequester($this);
}
/**
* @param AbstractTester $tester
* @return TestResult
*/
public function runTester($tester)
{
TestResultCache::clear();
$tester->setTestFilesLineUpper($this);
$tester->setHttpRequester($this);
return $tester->run('', '');
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace HtaccessCapabilityTester\Tests;
use HtaccessCapabilityTester\HtaccessCapabilityTester;
class Helper
{
public static function getTesterUsingFakeServer($fakeServer)
{
$hct = new HtaccessCapabilityTester('', '');
$hct->setTestFilesLineUpper($fakeServer);
$hct->setHttpRequester($fakeServer);
return $hct;
}
}

View File

@@ -0,0 +1,142 @@
<?php
/*
subdir: rewrite
files:
- filename: '.htaccess'
content: |
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^0\.txt$ 1\.txt [L]
</IfModule>
- filename: '0.txt'
content: '0'
- filename: '1.txt'
content: '1'
request:
url: '0.txt'
interpretation:
- [success, body, equals, '1']
- [failure, body, equals, '0']
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
| success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HtaccessCapabilityTester;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class HtaccessCapabilityTesterTest extends BasisTestCase
{
public function testHeaderSetWorksSuccess()
{
$hct = new HtaccessCapabilityTester('', '');
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/header-set/request-me.txt' => new HttpResponse(
'hi',
'200',
['X-Response-Header-Test' => 'test']
)
]);
$fakeServer->connectHCT($hct);
$this->assertTrue($hct->headerSetWorks());
}
public function testRequestHeaderWorksSuccess()
{
$hct = new HtaccessCapabilityTester('', '');
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/request-header/test.php' => new HttpResponse('1', '200', [])
]);
$fakeServer->connectHCT($hct);
$this->assertTrue($hct->requestHeaderWorks());
}
public function testRequestHeaderWorksFailure1()
{
$hct = new HtaccessCapabilityTester('', '');
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/request-header/test.php' => new HttpResponse('0', '200', [])
]);
$fakeServer->connectHCT($hct);
$this->assertFalse($hct->requestHeaderWorks());
}
public function testPassingThroughRequestHeaderSuccess()
{
$hct = new HtaccessCapabilityTester('', '');
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/pass-info-from-rewrite-to-script-through-request-header/test.php' =>
new HttpResponse('1', '200', [])
]);
$fakeServer->connectHCT($hct);
$this->assertTrue($hct->passingInfoFromRewriteToScriptThroughRequestHeaderWorks());
}
public function testPassingThroughEnvSuccess()
{
$hct = new HtaccessCapabilityTester('', '');
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/pass-info-from-rewrite-to-script-through-env/test.php' =>
new HttpResponse('1', '200', [])
]);
$fakeServer->connectHCT($hct);
$this->assertTrue($hct->passingInfoFromRewriteToScriptThroughEnvWorks());
}
public function testModuleLoadedWhenNotLoaded()
{
$hct = new HtaccessCapabilityTester('', '');
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/rewrite/0.txt' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/rewrite/request-me.txt' => new HttpResponse('0', '200', []),
]);
$fakeServer->connectHCT($hct);
$this->assertFalse($hct->moduleLoaded('setenvif'));
}
public function testModuleLoadedWhenLoaded()
{
$hct = new HtaccessCapabilityTester('', '');
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/rewrite/0.txt' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/rewrite/request-me.txt' => new HttpResponse('1', '200', []),
]);
$fakeServer->connectHCT($hct);
$this->assertTrue($hct->moduleLoaded('setenvif'));
}
//
}

View File

@@ -0,0 +1,51 @@
<?php
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class HttpResponseTest extends TestCase
{
public function test1()
{
$r = new HttpResponse('hi', '200', [
'x-test' => 'test'
]);
$this->assertTrue($r->hasHeader('x-test'));
$this->assertTrue($r->hasHeader('X-Test'));
$this->assertTrue($r->hasHeaderValue('X-Test', 'test'));
}
public function test2()
{
$r = new HttpResponse('hi', '200', [
'x-test1' => 'value1, value2',
'x-test2' => 'value1,value2'
]);
$this->assertTrue($r->hasHeaderValue('X-Test1', 'value2'));
$this->assertTrue($r->hasHeaderValue('X-Test2', 'value2'));
}
public function test3()
{
$r = new HttpResponse('hi', '200', [
'content-md5' => 'aaoeu'
]);
$this->assertTrue($r->hasHeader('Content-MD5'));
$this->assertTrue($r->hasHeader('content-md5'));
}
public function test4()
{
$r = new HttpResponse('hi', '200', [
'Content-MD5' => 'aaoeu'
]);
$this->assertTrue($r->hasHeader('Content-MD5'));
$this->assertTrue($r->hasHeader('content-md5'));
}
//
}

View File

@@ -0,0 +1,94 @@
<?php
/*
subdir: add-type
files:
- filename: '.htaccess'
content: |
<IfModule mod_mime.c>
AddType image/gif .test
</IfModule>
- filename: 'request-me.test'
content: 'hi'
request:
url: 'request-me.test'
interpretation:
- ['success', 'headers', 'contains-key-value', 'Content-Type', 'image/gif']
- ['inconclusive', 'status-code', 'not-equals', '200']
- ['failure', 'headers', 'not-contains-key-value', 'Content-Type', 'image/gif']
----
Tested:
| Case | Test result
| ------------------------------ | ------------------
| .htaccess disabled | failure
| forbidden directives (fatal) | failure
| access denied | inconclusive
| directive has no effect | failure
| it works | success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\AddTypeTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class AddTypeTesterTest extends BasisTestCase
{
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new AddTypeTester());
$this->assertFailure($testResult);
}
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new AddTypeTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new AddTypeTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the directive has no effect.
* This could happen when:
* - The directive is forbidden (non-fatal)
* - The module is not loaded
*/
public function testDirectiveHasNoEffect()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/add-type/request-me.test' => new HttpResponse('hi', '200', [])
]);
$testResult = $fakeServer->runTester(new AddTypeTester());
$this->assertFailure($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/add-type/request-me.test' => new HttpResponse('hi', '200', ['Content-Type' => 'image/gif'])
]);
$testResult = $fakeServer->runTester(new AddTypeTester());
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HtaccessCapabilityTester;
use HtaccessCapabilityTester\TestResult;
use HtaccessCapabilityTester\Testers\RewriteTester;
use HtaccessCapabilityTester\Testers\AbstractTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class BasisTestCase extends TestCase
{
protected function assertSuccess($testResult)
{
$this->assertTrue($testResult->status, $testResult->info);
}
protected function assertFailure($testResult)
{
$this->assertFalse($testResult->status, $testResult->info);
}
protected function assertInconclusive($testResult)
{
$this->assertNull($testResult->status, $testResult->info);
}
/**
*
* @param TestResult $testResult
* @param string $expectedResult failure|success|inconclusive
*
*/
/*
protected function assertTestResult($testResult, $expectedResult)
{
if ($expectedResult == 'failure') {
$this->assertFalse($testResult->status);
} elseif ($expectedResult == 'success') {
$this->assertTrue($testResult->status);
} elseif ($expectedResult == 'inconclusive') {
$this->assertNull($testResult->status);
}
}*/
/**
* @param AbstractTester $tester
* @param array $expectedBehaviour
* @param FakeServer $fakeServer
*/
/*
protected function behaviourOnFakeServer($tester, $expectedBehaviour, $fakeServer)
{
$tester->setTestFilesLineUpper($fakeServer);
$tester->setHttpRequester($fakeServer);
// $hct = Helper::getTesterUsingFakeServer($fakeServer);
if (isset($expectedBehaviour['htaccessDisabled'])) {
$fakeServer->disallowAllDirectives = true;
$testResult = $tester->run('', '');
$this->assertTestResult($testResult, );
$this->assertFailure($testResult->status);
}
}*/
}

View File

@@ -0,0 +1,135 @@
<?php
/*
subdir: content-digest
subtests:
- subdir: on
files:
- filename: '.htaccess'
content: |
ContentDigest On
- filename: 'request-me.txt'
content: 'hi'
request:
url: 'request-me.txt'
interpretation:
- ['failure', 'headers', 'not-contains-key', 'Content-MD5'],
- subdir: off
files:
- filename: '.htaccess'
content: |
ContentDigest Off
- filename: 'request-me.txt'
content: 'hi'
request:
url: 'request-me.txt'
interpretation:
- ['failure', 'headers', 'contains-key', 'Content-MD5']
- ['inconclusive', 'status-code', 'not-equals', '200']
- ['success', 'status-code', 'equals', '200']
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure (Required override: Options)
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
| success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\ContentDigestTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class ContentDigestTesterTest extends BasisTestCase
{
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new ContentDigestTester());
$this->assertFailure($testResult);
}
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new ContentDigestTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new ContentDigestTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the directive has no effect.
* This could happen when:
* - The directive is forbidden (non-fatal)
* - The module is not loaded
*
* Test no effect when server is setup to content-digest
*/
public function testDirectiveHasNoEffect1()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/content-digest/on/request-me.txt' => new HttpResponse('hi', '200', ['Content-MD5' => 'aaoeu']),
'/content-digest/off/request-me.txt' => new HttpResponse('hi', '200', ['Content-MD5' => 'aaoeu']),
]);
$testResult = $fakeServer->runTester(new ContentDigestTester());
$this->assertFailure($testResult);
}
/** Test no effect when server is setup NOT to content-digest
*/
public function testDirectiveHasNoEffect2()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/content-digest/on/request-me.txt' => new HttpResponse('hi', '200', []),
'/content-digest/off/request-me.txt' => new HttpResponse('hi', '200', []),
]);
$testResult = $fakeServer->runTester(new ContentDigestTester());
$this->assertFailure($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/content-digest/on/request-me.txt' => new HttpResponse(
'hi',
'200',
['Content-MD5' => 'aaoeu']
),
'/content-digest/off/request-me.txt' => new HttpResponse('hi', '200', [])
]);
$testResult = $fakeServer->runTester(new ContentDigestTester());
$this->assertSuccess($testResult);
}
public function testRequestFailure()
{
$fakeServer = new FakeServer();
$fakeServer->failAllRequests();
$testResult = $fakeServer->runTester(new ContentDigestTester());
$this->assertInconclusive($testResult);
}
}

View File

@@ -0,0 +1,114 @@
<?php
/*
subdir: 'crash-tester/xxx' # xxx is a subdir for the specific crash-test
subtests:
- subdir: the-suspect
files:
- filename: '.htaccess'
content: # the rules goes here
- filename: 'request-me.txt'
content: 'thanks'
request:
url: 'request-me.txt'
bypass-standard-error-handling': ['all']
interpretation:
- [success, body, equals, '1']
- [failure, body, equals, '0']
- [success, status-code, not-equals, '500']
- subdir: the-innocent
files:
- filename: '.htaccess'
content: '# I am no trouble'
- filename: 'request-me.txt'
content: '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]
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | success! (nothing crashes)
access denied | success! (nothing crashes. In case there is both errors and
access denied, the response is 500. This is however
only tested on Apache 2.4.29)
all requests crash | inconclusive (even innocent request crashes means that we cannot
conclude that the rules are "crashy", or that they are not
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\CrashTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class CrashTesterTest extends BasisTestCase
{
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new CrashTester(''));
$this->assertSuccess($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new CrashTester(''));
$this->assertSuccess($testResult);
}
public function testWhenAllRequestsCrashes()
{
$fakeServer = new FakeServer();
$fakeServer->makeAllCrash();
$testResult = $fakeServer->runTester(new CrashTester(''));
$this->assertInconclusive($testResult);
}
public function testWhenAllRequestsCrashes2()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/crash-tester/test/the-suspect/request-me.txt' => new HttpResponse('', '500', []),
'/crash-tester/test/the-innocent/request-me.txt' => new HttpResponse('', '500', [])
]);
$testResult = $fakeServer->runTester(new CrashTester('aoeu', 'test'));
$this->assertInconclusive($testResult);
}
public function testWhenRequestCrashesButInnocentDoesNot()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/crash-tester/test/the-suspect/request-me.txt' => new HttpResponse('', '500', []),
'/crash-tester/test/the-innocent/request-me.txt' => new HttpResponse('thanks', '200', [])
]);
$testResult = $fakeServer->runTester(new CrashTester('aoeu', 'test'));
$this->assertFailure($testResult);
}
public function testRequestFailure()
{
$fakeServer = new FakeServer();
$fakeServer->failAllRequests();
$testResult = $fakeServer->runTester(new CrashTester('aoeu', 'test'));
$this->assertInconclusive($testResult);
}
}

View File

@@ -0,0 +1,100 @@
<?php
/*
subdir: directory-index
files:
- filename: '.htaccess'
content: |
<IfModule mod_dir.c>
DirectoryIndex index2.html
</IfModule>
- filename: 'index.html'
content: '0'
- filename: 'index2.html'
content: '1'
request:
url: '' # We request the index, that is why its empty
bypass-standard-error-handling: ['404']
interpretation:
- ['success', 'body', 'equals', '1']
- ['failure', 'body', 'equals', '0']
- ['failure', 'status-code', 'equals', '404'] # "index.html" might not be set to index
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure (highly unlikely, as it is part of core - but still possible)
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
| success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\DirectoryIndexTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class DirectoryIndexTesterTest extends BasisTestCase
{
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new DirectoryIndexTester());
$this->assertFailure($testResult);
}
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new DirectoryIndexTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new DirectoryIndexTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the directive has no effect.
* This could happen when:
* - The directive is forbidden (non-fatal)
* - The module is not loaded
*
*/
public function testDirectiveHasNoEffect()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/directory-index/' => new HttpResponse('0', '200', []),
]);
$testResult = $fakeServer->runTester(new DirectoryIndexTester());
$this->assertFailure($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/directory-index/' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new DirectoryIndexTester());
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,99 @@
<?php
/*
subdir: header-set
files:
- filename: '.htaccess'
content: |
<IfModule mod_headers.c>
Header set X-Response-Header-Test: test
</IfModule>
- filename: 'request-me.txt'
content: 'hi'
request:
url: 'request-me.txt'
interpretation:
- [success, headers, contains-key-value, 'X-Response-Header-Test', 'test'],
- [failure]
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
| success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\HeaderSetTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class HeaderSetTesterTest extends BasisTestCase
{
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new HeaderSetTester());
$this->assertFailure($testResult);
}
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new HeaderSetTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new HeaderSetTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the directive has no effect.
* This could happen when:
* - The directive is forbidden (non-fatal)
* - The module is not loaded
*/
public function testDirectiveHasNoEffect()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/header-set/request-me.txt' => new HttpResponse('hi', '200', [])
]);
$testResult = $fakeServer->runTester(new HeaderSetTester());
$this->assertFailure($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/header-set/request-me.txt' => new HttpResponse(
'hi',
'200',
['X-Response-Header-Test' => 'test']
)
]);
$testResult = $fakeServer->runTester(new HeaderSetTester());
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,124 @@
<?php
/*
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
access denied | inconclusive (it might be allowed to other files)
it works | success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\HtaccessEnabledTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class HtaccessEnabledTesterTest extends BasisTestCase
{
/**
* Test failure when server signature fails
*
*/
public function testSuccessServerSignatureFails()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/server-signature/on/test.php' => new HttpResponse('0', '200', []),
'/server-signature/off/test.php' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new HtaccessEnabledTester());
$this->assertFailure($testResult);
}
/**
* Test success when server signature works.
*
*/
public function testSuccessServerSignatureSucceeds()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/server-signature/on/test.php' => new HttpResponse('1', '200', []),
'/server-signature/off/test.php' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new HtaccessEnabledTester());
$this->assertSuccess($testResult);
}
/**
* Test success when setting a header works.
*/
public function testSuccessHeaderSetSucceeds()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/header-set/request-me.txt' => new HttpResponse(
'hi',
'200',
['X-Response-Header-Test' => 'test']
)
]);
$testResult = $fakeServer->runTester(new HtaccessEnabledTester());
$this->assertSuccess($testResult);
}
/**
* Test success when malformed .htaccess causes 500
*/
public function testSuccessMalformedHtaccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/crash-tester/htaccess-enabled-malformed-htaccess/the-suspect/request-me.txt' =>
new HttpResponse('', '500', []),
'/crash-test/htaccess-enabled-malformed-htaccess/the-innocent/request-me.txt' =>
new HttpResponse('thanks', '200', [])
]);
$testResult = $fakeServer->runTester(new HtaccessEnabledTester());
$this->assertSuccess($testResult);
}
/**
* Test failure when malformed .htaccess causes 500
*/
public function testFailureMalformedHtaccessDoesNotCauseCrash()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/crash-tester/htaccess-enabled-malformed-htaccess/the-suspect/request-me.txt' =>
new HttpResponse('thanks', '200', []),
'/crash-test/htaccess-enabled-malformed-htaccess/the-innocent/request-me.txt' =>
new HttpResponse('thanks', '200', [])
]);
$testResult = $fakeServer->runTester(new HtaccessEnabledTester());
$this->assertFailure($testResult);
}
/**
* Test inconclusive when all crashes
*/
public function testInconclusiveWhenAllCrashes()
{
$fakeServer = new FakeServer();
$fakeServer->makeAllCrash();
$testResult = $fakeServer->runTester(new HtaccessEnabledTester());
$this->assertInconclusive($testResult);
}
public function testRequestFailure()
{
$fakeServer = new FakeServer();
$fakeServer->failAllRequests();
$testResult = $fakeServer->runTester(new HtaccessEnabledTester());
$this->assertInconclusive($testResult);
}
}

View File

@@ -0,0 +1,54 @@
<?php
/*
subdir: innocent-request
files:
- filename: 'request-me.txt'
content: 'thank you my dear'
request:
url: 'request-me.txt'
bypass-standard-error-handling: 'all'
interpretation:
- ['success', 'status-code', 'equals', '200']
- ['inconclusive', 'status-code', 'equals', '403']
- ['inconclusive', 'status-code', 'equals', '404']
- ['failure']
----
Tested:
Server setup | Test result
--------------------------------------------------
access denied | inconclusive (it might be allowed to other files)
always fatal | failure
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\InnocentRequestTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class InnocentRequestTesterTest extends BasisTestCase
{
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new InnocentRequestTester());
$this->assertInconclusive($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$testResult = $fakeServer->runTester(new InnocentRequestTester());
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,257 @@
<?php
/*
subdir: module-loaded
subtests:
- subdir: server-signature
requirements: htaccessEnabled()
files:
- filename: '.htaccess'
content: |
ServerSignature Off
<IfModule mod_xxx.c>
ServerSignature On
</IfModule>
- filename: 'test.php'
content: |
<?php
if (isset($_SERVER['SERVER_SIGNATURE']) && ($_SERVER['SERVER_SIGNATURE'] != '')) {
echo 1;
} else {
echo 0;
}
interpretation:
- ['success', 'body', 'equals', '1']
- ['failure', 'body', 'equals', '0']
- subdir: rewrite
...
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
access denied | inconclusive (it might be allowed to other files)
it works | success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\ModuleLoadedTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class ModuleLoadedTesterTest extends BasisTestCase
{
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertFailure($testResult);
}
public function testInconclusiveWhenAllCrashes()
{
$fakeServer = new FakeServer();
$fakeServer->makeAllCrash();
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertInconclusive($testResult);
}
public function testServerSignatureSucceedsModuleLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/server-signature/on/test.php' => new HttpResponse('1', '200', []),
'/server-signature/off/test.php' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/server-signature/test.php' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertSuccess($testResult);
}
public function testServerSignatureSucceedsModuleNotLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/server-signature/on/test.php' => new HttpResponse('1', '200', []),
'/server-signature/off/test.php' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/server-signature/test.php' => new HttpResponse('0', '200', [])
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertFailure($testResult);
}
public function testContentDigestWorksModuleLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/content-digest/on/request-me.txt' => new HttpResponse(
'hi',
'200',
['Content-MD5' => 'aaoeu']
),
'/content-digest/off/request-me.txt' => new HttpResponse('hi', '200', []),
'/module-loaded/setenvif/content-digest/request-me.txt' => new HttpResponse(
'',
'200',
['Content-MD5' => 'aoeu']
)
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertSuccess($testResult);
}
public function testContentDigestWorksModuleNotLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/content-digest/on/request-me.txt' => new HttpResponse(
'hi',
'200',
['Content-MD5' => 'aaoeu']
),
'/content-digest/off/request-me.txt' => new HttpResponse('hi', '200', []),
'/module-loaded/setenvif/content-digest/request-me.txt' => new HttpResponse('', '200', [])
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertFailure($testResult);
}
public function testAddTypeWorksModuleLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/add-type/request-me.test' => new HttpResponse(
'hi',
'200',
['Content-Type' => 'image/gif']
),
'/module-loaded/setenvif/add-type/request-me.test' => new HttpResponse(
'hi',
'200',
['Content-Type' => 'image/gif']
)
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertSuccess($testResult);
}
public function testAddTypeWorksModuleNotLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/add-type/request-me.test' => new HttpResponse(
'hi',
'200',
['Content-Type' => 'image/gif']
),
'/module-loaded/setenvif/add-type/request-me.test' => new HttpResponse(
'hi',
'200',
['Content-Type' => 'image/jpeg']
)
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertFailure($testResult);
}
public function testDirectoryIndexWorksModuleLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/directory-index/' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/directory-index/' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertSuccess($testResult);
}
public function testDirectoryIndexWorksModuleNotLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/directory-index/' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/directory-index/' => new HttpResponse('0', '200', [])
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertFailure($testResult);
}
public function testRewriteWorksModuleLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/rewrite/0.txt' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/rewrite/request-me.txt' => new HttpResponse('1', '200', []),
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertSuccess($testResult);
}
public function testRewriteWorksModuleNotLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/rewrite/0.txt' => new HttpResponse('1', '200', []),
'/module-loaded/setenvif/rewrite/request-me.txt' => new HttpResponse('0', '200', []),
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertFailure($testResult);
}
public function testHeaderSetWorksModuleLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/header-set/request-me.txt' => new HttpResponse(
'hi',
'200',
['X-Response-Header-Test' => 'test']
),
'/module-loaded/setenvif/header-set/request-me.txt' => new HttpResponse(
'thanks',
'200',
['X-Response-Header-Test' => '1']
),
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertSuccess($testResult);
}
public function testHeaderSetWorksModuleNotLoaded()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/header-set/request-me.txt' => new HttpResponse(
'hi',
'200',
['X-Response-Header-Test' => 'test']
),
'/module-loaded/setenvif/header-set/request-me.txt' => new HttpResponse(
'thanks',
'200',
['X-Response-Header-Test' => '0']
),
]);
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertFailure($testResult);
}
public function testRequestFailure()
{
$fakeServer = new FakeServer();
$fakeServer->failAllRequests();
$testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
$this->assertInconclusive($testResult);
}
}

View File

@@ -0,0 +1,143 @@
<?php
/*
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: |
<?php
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', '<?php']
- ['inconclusive']
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
php is unprocessed | inconclusive
directive works | success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\PassInfoFromRewriteToScriptThroughEnvTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class PassInfoFromRewriteToScriptThroughEnvTesterTest extends BasisTestCase
{
/* can't do this test, it would require processing PHP
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughEnvTester());
$this->assertFailure($testResult);
}*/
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughEnvTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughEnvTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the magic is not working
* This could happen when:
* - Any of the directives are forbidden (non-fatal)
* - Any of the modules are not loaded
* - Perhaps these advanced features are not working on all platforms
* (does LiteSpeed ie support these this?)
*/
public function testMagicNotWorking()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/pass-info-from-rewrite-to-script-through-env/test.php' =>
new HttpResponse('0', '200', [])
]);
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughEnvTester());
$this->assertFailure($testResult);
}
public function testPHPNotProcessed()
{
$fakeServer = new FakeServer();
$fakeServer->handlePHPasText();
$testResult = $fakeServer->runTester(
new PassInfoFromRewriteToScriptThroughEnvTester()
);
$this->assertInconclusive($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/pass-info-from-rewrite-to-script-through-env/test.php' =>
new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(
new PassInfoFromRewriteToScriptThroughEnvTester()
);
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,129 @@
<?php
/*
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: |
<?php
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', '<?php']
- ['inconclusive']
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
php is unprocessed | inconclusive
directive works | success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\PassInfoFromRewriteToScriptThroughRequestHeaderTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class PassInfoFromRewriteToScriptThroughRequestHeaderTesterTest extends BasisTestCase
{
/* can't do this test, it would require processing PHP
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughRequestHeaderTester());
$this->assertFailure($testResult);
}*/
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughRequestHeaderTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughRequestHeaderTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the magic is not working
* This could happen when:
* - Any of the directives are forbidden (non-fatal)
* - Any of the modules are not loaded
* - Perhaps these advanced features are not working on all platforms
* (does LiteSpeed ie support these this?)
*/
public function testMagicNotWorking()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/pass-info-from-rewrite-to-script-through-request-header/test.php' =>
new HttpResponse('0', '200', [])
]);
$testResult = $fakeServer->runTester(new PassInfoFromRewriteToScriptThroughRequestHeaderTester());
$this->assertFailure($testResult);
}
public function testPHPNotProcessed()
{
$fakeServer = new FakeServer();
$fakeServer->handlePHPasText();
$testResult = $fakeServer->runTester(
new PassInfoFromRewriteToScriptThroughRequestHeaderTester()
);
$this->assertInconclusive($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/pass-info-from-rewrite-to-script-through-request-header/test.php' =>
new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(
new PassInfoFromRewriteToScriptThroughRequestHeaderTester()
);
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,123 @@
<?php
/*
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: |
<?php
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', '<?php'],
TODO:
TEST: php_flag engine off
https://stackoverflow.com/questions/1271899/disable-php-in-directory-including-all-sub-directories-with-htaccess
TEST: RemoveHandler and RemoveType (https://electrictoolbox.com/disable-php-apache-htaccess/)
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
php is unprocessed | inconclusive
directive works | success
TODO:
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\RequestHeaderTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class RequestHeaderTesterTest extends BasisTestCase
{
/* can't do this test, it would require processing PHP
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new RequestHeaderTester());
$this->assertFailure($testResult);
}*/
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new RequestHeaderTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new RequestHeaderTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the directive has no effect.
* This could happen when:
* - The directive is forbidden (non-fatal)
* - The module is not loaded
*/
public function testDirectiveHasNoEffect()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/request-header/test.php' => new HttpResponse('0', '200', [])
]);
$testResult = $fakeServer->runTester(new RequestHeaderTester());
$this->assertFailure($testResult);
}
public function testPHPNotProcessed()
{
$fakeServer = new FakeServer();
$fakeServer->handlePHPasText();
$testResult = $fakeServer->runTester(new RequestHeaderTester());
$this->assertInconclusive($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/request-header/test.php' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new RequestHeaderTester());
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,98 @@
<?php
/*
subdir: rewrite
files:
- filename: '.htaccess'
content: |
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^0\.txt$ 1\.txt [L]
</IfModule>
- filename: '0.txt'
content: '0'
- filename: '1.txt'
content: '1'
request:
url: '0.txt'
interpretation:
- [success, body, equals, '1']
- [failure, body, equals, '0']
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | failure
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
| success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\RewriteTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class RewriteTesterTest extends BasisTestCase
{
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new RewriteTester());
$this->assertFailure($testResult);
}
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new RewriteTester());
$this->assertFailure($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new RewriteTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the directive has no effect.
* This could happen when:
* - The directive is forbidden (non-fatal)
* - The module is not loaded
*/
public function testDirectiveHasNoEffect()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/rewrite/0.txt' => new HttpResponse('0', '200', [])
]);
$testResult = $fakeServer->runTester(new RewriteTester());
$this->assertFailure($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/rewrite/0.txt' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new RewriteTester());
$this->assertSuccess($testResult);
}
}

View File

@@ -0,0 +1,148 @@
<?php
/*
subdir: server-signature
subtests:
- subdir: on
files:
- filename: '.htaccess'
content: |
ServerSignature On
- filename: 'test.php'
content: |
<?php
if (isset($_SERVER['SERVER_SIGNATURE']) && ($_SERVER['SERVER_SIGNATURE'] != '')) {
echo 1;
} else {
echo 0;
}
request:
url: 'test.php'
interpretation:
- ['inconclusive', 'body', 'isEmpty']
- ['inconclusive', 'status-code', 'not-equals', '200']
- ['failure', 'body', 'equals', '0']
- subdir: off
files:
- filename: '.htaccess'
content: |
ServerSignature Off
- filename: 'test.php'
content: |
<?php
if (isset($_SERVER['SERVER_SIGNATURE']) && ($_SERVER['SERVER_SIGNATURE'] != '')) {
echo 0;
} else {
echo 1;
}
request:
url: 'test.php'
interpretation:
- ['inconclusive', 'body', 'isEmpty']
- ['success', 'body', 'equals', '1']
- ['failure', 'body', 'equals', '0']
- ['inconclusive']
----
Tested:
Server setup | Test result
--------------------------------------------------
.htaccess disabled | failure
forbidden directives (fatal) | inconclusive (special!)
access denied | inconclusive (it might be allowed to other files)
directive has no effect | failure
| success
*/
namespace HtaccessCapabilityTester\Tests\Testers;
use HtaccessCapabilityTester\HttpResponse;
use HtaccessCapabilityTester\Testers\ServerSignatureTester;
use HtaccessCapabilityTester\Tests\FakeServer;
use PHPUnit\Framework\TestCase;
class ServerSignatureTesterTest extends BasisTestCase
{
/*
can't do this test as our fake server does not execute PHP
public function testHtaccessDisabled()
{
$fakeServer = new FakeServer();
$fakeServer->disableHtaccess();
$testResult = $fakeServer->runTester(new ServerSignatureTester());
$this->assertFailure($testResult);
}*/
public function testDisallowedDirectivesFatal()
{
$fakeServer = new FakeServer();
$fakeServer->disallowAllDirectives('fatal');
$testResult = $fakeServer->runTester(new ServerSignatureTester());
$this->assertFailure($testResult);
// SPECIAL!
// As ServerSignature is in core and AllowOverride is None, the tester assumes
// that this does not happen. The 500 must then be another problem, which is why
// it returns inconclusive
//$this->assertInconclusive($testResult);
}
public function testAccessAllDenied()
{
$fakeServer = new FakeServer();
$fakeServer->denyAllAccess();
$testResult = $fakeServer->runTester(new ServerSignatureTester());
$this->assertInconclusive($testResult);
}
/**
* Test when the directive has no effect.
* This could happen when:
* - The directive is forbidden (non-fatal)
* - The module is not loaded
*
* This tests when ServerSignature is set, and the directive has no effect.
*/
public function testDirectiveHasNoEffect1()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/server-signature/on/test.php' => new HttpResponse('1', '200', []),
'/server-signature/off/test.php' => new HttpResponse('0', '200', [])
]);
$testResult = $fakeServer->runTester(new ServerSignatureTester());
$this->assertFailure($testResult);
}
/**
* This tests when ServerSignature is unset, and the directive has no effect.
*/
public function testDirectiveHasNoEffect2()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/server-signature/on/test.php' => new HttpResponse('0', '200', []),
'/server-signature/off/test.php' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new ServerSignatureTester());
$this->assertFailure($testResult);
}
public function testSuccess()
{
$fakeServer = new FakeServer();
$fakeServer->setResponses([
'/server-signature/on/test.php' => new HttpResponse('1', '200', []),
'/server-signature/off/test.php' => new HttpResponse('1', '200', [])
]);
$testResult = $fakeServer->runTester(new ServerSignatureTester());
$this->assertSuccess($testResult);
}
}