Download the PHP package rosell-dk/htaccess-capability-tester without Composer
On this page you can find all versions of the php package rosell-dk/htaccess-capability-tester. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package htaccess-capability-tester
htaccess-capability-tester
Detect .htaccess capabilities through live tests.
There are cases where the only way to to learn if a given .htaccess capability is enabled / supported on a system is by examining it "from the outside" through a HTTP request. This library is build to handle such testing easily.
This is what happens behind the scenes:
- Some test files for a given test are put on the server (at least an .htaccess file)
- The test is triggered by doing a HTTP request
- The response is interpreted
Usage
To use the library, you must provide a path to where the test files are going to be put and the corresponding URL that they can be reached. Besides that, you just need to pick one of the tests that you want to run.
While having a reliable moduleLoaded() method is a great improvement over current state of affairs, beware that it is possible that the server has ie mod_rewrite enabled, but at the same time has disallowed using ie the "RewriteRule" directive in .htaccess files. This is why the library has the rewriteWorks() method and similar methods for testing various capabilites fully (check the API overview below). Providing tests for all kinds of functionality, would however be too much for any library. Instead this library makes it a breeze to define a custom test and run it through the customTest($def) method. To learn more, check out the Running your own custom tests document.
API overview
Test methods in HtaccessCapabilityTester
All the test methods returns a test result, which is true for success, false for failure or null for inconclusive.
The tests have the following in common:
- If the server has been set up to ignore .htaccess files entirely, the result will be failure.
- If the server has been set up to disallow the directive being tested (AllowOverride), the result is failure (both when configured to ignore and when configured to go fatal)
- A 403 Forbidden results in inconclusive. Why? Because it could be that the server has been set up to forbid access to files matching a pattern that our test file unluckily matches. In most cases, this is unlikely, as most tests requests files with harmless-looking file extensions (often a "request-me.txt"). A few of the tests however requests a "test.php", which is more likely to be denied.
- A 404 Not Found results in inconclusive
- If the request fails completely (ie timeout), the result is inconclusive
Most tests are implemented as a definition such as the one accepted in customTest(). This means that if you want one of the tests provided by this library to work slightly differently, you can easily grab the code in the corresponding class in the Testers directory, make your modification and call customTest().
addTypeWorks()
Tests if the *AddType* directive works.
Implementation (YAML definition):
contentDigestWorks()
Implementation (YAML definition):
crashTest($rules, $subdir)
Test if some rules makes the server "crash" (respond with 500 Internal Server Error for requests to files in the folder).
You pass the rules that you want to check.
You can optionally pass in a subdir for the tests. If you do not do that, a hash of the rules will be used.
Implementation (PHP):
customTest($definition)
Allows you to run a custom test. Check out README.md for instructions
directoryIndexWorks()
Tests if DirectoryIndex works.
Implementation (YAML definition):
headerSetWorks()
Tests if setting a response header works using the *Header* directive.
Implementation (YAML definition):
htaccessEnabled()
Apache can be configured to ignore *.htaccess* files altogether. This method tests if the *.htaccess* file is processed at all
The method works by trying out a series of subtests until a conclusion is reached. It will never come out inconclusive.
How does it work?
- The first strategy is testing a series of features, such as `rewriteWorks()`. If any of them works, well, then the *.htaccess* must have been processed.
- Secondly, the `serverSignatureWorks()` is tested. The "ServerSignature" directive is special because it is in core and cannot be disabled with AllowOverride. If this test comes out as a failure, it is so *highly likely* that the .htaccess has not been processed, that we conclude that it has not.
- Lastly, if all other methods failed, we try calling `crashTest()` on an .htaccess file that we on purpose put syntax errors in. If it crashes, the .htaccess file must have been proccessed. If it does not crash, it has not. This last method is bulletproof - so why not do it first? Because it might generate an entry in the error log.
Main part of implementation:
innocentRequestWorks()
Tests if an innocent request to a text file works. Most tests use this test when they get a 500 Internal Error, in order to decide if this is a general problem (general problem => inconclusive, specific problem => failure).
Implementation (YAML definition):
moduleLoaded($moduleName)
Tests if a given module is loaded. Note that you in most cases would want to not just know if a module is loaded, but also ensure that the directives you are using are allowed. So for example, instead of calling `moduleLoaded("rewrite")`, you should probably call `rewriteWorks()`;
Implementation:
The method has many ways to test if a module is loaded, based on what works. If for example setting headers has been established to be working and we want to know if "setenvif" module is loaded, the following .htaccess rules will be tested, and the response will be examined.
passingInfoFromRewriteToScriptThroughEnvWorks()
Say you have a rewrite rule that points to a PHP script and you would like to pass some information along to the PHP. Usually, you will just pass it in the query string. But this won't do if the information is sensitive. In that case, there are some tricks available. The trick being tested here tells the RewriteRule directive to set an environment variable, which in many setups can be picked up in the script.
Implementation (YAML definition):
passingInfoFromRewriteToScriptThroughRequestHeaderWorks()
Say you have a rewrite rule that points to a PHP script and you would like to pass some information along to the PHP. Usually, you will just pass it in the query string. But this won't do if the information is sensitive. In that case, there are some tricks available. The trick being tested here tells the RewriteRule directive to set an environment variable which a RequestHeader directive picks up on and passes on to the script in a request header.
Implementation (YAML definition):
rewriteWorks()
Tests if rewriting works.
Implementation (YAML definition):
requestHeaderWorks()
Tests if a request header can be set using the *RequestHeader* directive.
Implementation (YAML definition):
serverSignatureWorks()
Tests if the *ServerSignature* directive works.
Implementation (YAML definition):
Other methods in HtaccessCapabilityTester
setHttpRequester($requester)
This allows you to use another object for making HTTP requests than the standard one provided by this library. The standard one uses `file_get_contents` to make the request and is implemented in `SimpleHttpRequester.php`. You might for example prefer to use *curl* or, if you are making a Wordpress plugin, you might want to use the one provided by the Wordpress framework.
setTestFilesLineUpper($testFilesLineUpper)
This allows you to use another object for lining up the test files than the standard one provided by this library. The standard one uses `file_put_contents` to save files and is implemented in `SimpleTestFileLineUpper.php`. You will probably not need to swap the test file line-upper.
Stable API?
The 0.9 release is just about right. I do not expect any changes in the part of the API that is mentioned above. So, if you stick to that, it should still work, when the 1.0 release comes.
Changes in the new 0.9 release:
- Request failures (such as timeout) results in inconclusive.
- If you have implemented your own HttpRequester rather than using the default, you need to update it. It must now return status code "0" if the request failed (ie timeout)
Expected changes in the 1.0 release:
- TestResult class might be disposed off so the "internal" Tester classes also returns bool|null.
- Throw custom exception when test file cannot be created
Platforms
Works on (at least):
- OS: Ubuntu (22.04, 20.04), Windows (2022, 2019), Mac OS (13, 12, 11, 10.15)
- PHP: 5.6 - 8.2
Each new release will be tested on all combinations of OSs and PHP versions that are supported by GitHub-hosted runners. Except that we do not below PHP 5.6.\ Status:
Testing consists of running the unit tests. The code in this library has pretty good code coverage (~90% coverage).
We also test future versions of PHP monthly, in order to catch problems early.\ Status:
Installation
Require the library with Composer, like this: