Completed
Push — master ( 41603f...2cbafc )
by Bjørn
02:30
created

ModuleLoadedTester::getServerSignatureBasedTest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 28
c 3
b 0
f 0
dl 0
loc 42
ccs 8
cts 8
cp 1
rs 9.472
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace HtaccessCapabilityTester\Testers;
4
5
use \HtaccessCapabilityTester\TestResult;
6
7
/**
8
 * Class for testing if a module is loaded.
9
 *
10
 * @package    HtaccessCapabilityTester
11
 * @author     Bjørn Rosell <[email protected]>
12
 * @since      Class available since 0.7
13
 */
14
class ModuleLoadedTester extends AbstractTester
15
{
16
17
    /* @var string A valid Apache module name (ie "rewrite") */
18
    protected $moduleName;
19
20
    /**
21
     * Constructor.
22
     *
23
     * @return void
24
     */
25 14
    public function __construct($moduleName)
26
    {
27 14
        $this->moduleName = $moduleName;
28 14
    }
29
30
    /**
31
     * Child classes must implement this method, which tells which subdir the
32
     * test files are to be put.
33
     *
34
     * @return  string  A subdir for the test files
35
     */
36 12
    public function getSubDir()
37
    {
38 12
        return 'module-loaded/' . $this->moduleName;
39
    }
40
41
    /**
42
     * Register the test files using the "registerTestFile" method
43
     *
44
     * @return  void
45
     */
46 14
    public function registerTestFiles()
47
    {
48
        // No test files for this test
49 14
    }
50
51 12
    private function getServerSignatureBasedTest()
52
    {
53
        // Test files, method : Using ServerSignature
54
        // --------------------------------------------------
55
        // Requires (in order not to be inconclusive):
56
        // - Override: All
57
        // - Status: Core
58
        // - Directives: ServerSignature, IfModule
59
        // - PHP?: Yes
60
61
        $php = <<<'EOD'
62 12
<?php
63
if (isset($_SERVER['SERVER_SIGNATURE']) && ($_SERVER['SERVER_SIGNATURE'] != '')) {
64
    echo 1;
65
} else {
66
    echo 0;
67
}
68
EOD;
69
70
        $htaccess = <<<'EOD'
71 12
# The beauty of this trick is that ServerSignature is available in core.
72
# (it requires no modules and cannot easily be made forbidden)
73
# However, it requires PHP to check for the effect
74
75
ServerSignature Off
76
<IfModule mod_xxx.c>
77
ServerSignature On
78
</IfModule>
79
EOD;
80
81 12
        $htaccess = str_replace('mod_xxx', 'mod_' . $this->moduleName, $htaccess);
82
83
        return [
84 12
            'subdir' => $this->getSubDir() . '/server-signature',
85
            'files' => [
86 12
                ['.htaccess', $htaccess],
87 12
                ['test.php', $php],
88
            ],
89 12
            'request' => 'test.php',
90
            'interpretation' => [
91
                ['success', 'body', 'equals', '1'],
92
                ['failure', 'body', 'equals', '0'],
93
                // This time we do not fail for 500 because it is very unlikely that any of the
94
                // directives used are forbidden
95
            ]
96
        ];
97
    }
98
99
    /**
100
     *  @return  array
101
     */
102 2
    private function getRewriteBasedTest()
103
    {
104
        // Test files, method: Using Rewrite
105
        // --------------------------------------------------
106
        // Requires (in order not to be inconclusive)
107
        // - Module: mod_rewrite
108
        // - Override: FileInfo
109
        // - Directives: RewriteEngine, RewriteRule and IfModule
110
        // - PHP?: No
111
112
        $htaccess = <<<'EOD'
113 2
RewriteEngine On
114
<IfModule mod_xxx.c>
115
    RewriteRule ^request-me\.txt$ 1.txt [L]
116
</IfModule>
117
<IfModule !mod_xxx.c>
118
    RewriteRule ^request-me\.txt$ 0.txt [L]
119
</IfModule>
120
EOD;
121
122 2
        $htaccess = str_replace('mod_xxx', 'mod_' . $this->moduleName, $htaccess);
123
124
        return [
125 2
            'subdir' => $this->getSubDir() . '/rewrite',
126
            'files' => [
127 2
                ['.htaccess', $htaccess],
128
                ['0.txt', '0'],
129
                ['1.txt', '1'],
130
                ['request-me.txt', 'Redirect failed even though rewriting has been proven to work. Strange!'],
131
            ],
132 2
            'request' => 'request-me.txt',
133
            'interpretation' => [
134
                ['success', 'body', 'equals', '1'],
135
                ['failure', 'body', 'equals', '0'],
136
                //['inconclusive', 'status-code', 'not-equals', '200'],
137
            ]
138
        ];
139
    }
140
141
    /**
142
     *  @return  array
143
     */
144 2
    private function getHeaderSetBasedTest()
145
    {
146
147
        // Test files, method: Using Response Header
148
        // --------------------------------------------------
149
        // Requires (in order not to be inconclusive)
150
        // - Module: mod_headers
151
        // - Override: FileInfo
152
        // - Directives: Header and IfModule
153
        // - PHP?: No
154
155
        $htaccess = <<<'EOD'
156 2
<IfModule mod_xxx.c>
157
    Header set X-Response-Header-Test: 1
158
</IfModule>
159
<IfModule !mod_xxx.c>
160
    Header set X-Response-Header-Test: 0
161
</IfModule>
162
EOD;
163
164 2
        $htaccess = str_replace('mod_xxx', 'mod_' . $this->moduleName, $htaccess);
165
166
        return [
167 2
            'subdir' => $this->getSubDir() . '/header-set',
168
            'files' => [
169 2
                ['.htaccess', $htaccess],
170
                ['request-me.txt', 'thanks'],
171
            ],
172 2
            'request' => 'request-me.txt',
173
            'interpretation' => [
174
                ['success', 'headers', 'contains-key-value', 'X-Response-Header-Test', '1'],
175
                ['failure', 'headers', 'contains-key-value', 'X-Response-Header-Test', '0'],
176
            ]
177
        ];
178
    }
179
180
    /**
181
     *  @return  array
182
     */
183 2
    private function getContentDigestBasedTest()
184
    {
185
        // Test files, method: Using ContentDigest
186
        // --------------------------------------------------
187
        //
188
        // Requires (in order not to be inconclusive)
189
        // - Module: None - its in core
190
        // - Override: Options
191
        // - Directives: ContentDigest
192
        // - PHP?: No
193
194
        $htaccess = <<<'EOD'
195 2
<IfModule mod_xxx.c>
196
    ContentDigest On
197
</IfModule>
198
<IfModule !mod_xxx.c>
199
    ContentDigest Off
200
</IfModule>
201
EOD;
202
203 2
        $htaccess = str_replace('mod_xxx', 'mod_' . $this->moduleName, $htaccess);
204
205
        return [
206 2
            'subdir' => $this->getSubDir() . '/content-digest',
207
            'files' => [
208 2
                ['.htaccess', $htaccess],
209
                ['request-me.txt', 'thanks'],
210
            ],
211 2
            'request' => 'request-me.txt',
212
            'interpretation' => [
213
                ['success', 'headers', 'contains-key', 'Content-MD5'],
214
                ['failure', 'headers', 'not-contains-key', 'Content-MD5'],
215
            ]
216
        ];
217
    }
218
219
    /**
220
     *  @return  array
221
     */
222 2
    private function getDirectoryIndexBasedTest()
223
    {
224
        // Test files, method: Using DirectoryIndex
225
        // --------------------------------------------------
226
        //
227
        // Requires (in order not to be inconclusive)
228
        // - Module: mod_dir (Status: Base)
229
        // - Override: Indexes
230
        // - Directives: DirectoryIndex
231
        // - PHP?: No
232
233
        $htaccess = <<<'EOD'
234 2
<IfModule mod_xxx.c>
235
    DirectoryIndex 1.html
236
</IfModule>
237
<IfModule !mod_xxx.c>
238
    DirectoryIndex 0.html
239
</IfModule>
240
EOD;
241
242 2
        $htaccess = str_replace('mod_xxx', 'mod_' . $this->moduleName, $htaccess);
243
244
        return [
245 2
            'subdir' => $this->getSubDir() . '/directory-index',
246
            'files' => [
247 2
                ['.htaccess', $htaccess],
248
                ['0.html', '0'],
249
                ['1.html', '1'],
250
            ],
251 2
            'request' => '',        // empty - in order to request the index
252
            'interpretation' => [
253
                ['success', 'body', 'equals', '1'],
254
                ['failure', 'body', 'equals', '0'],
255
            ]
256
        ];
257
    }
258
259
260
    /**
261
     *  @return  array
262
     */
263 2
    private function getAddTypeBasedTest()
264
    {
265
        // Test files, method: Using AddType
266
        // --------------------------------------------------
267
        //
268
        // Requires (in order not to be inconclusive)
269
        // - Module: mod_mime
270
        // - Override: FileInfo
271
        // - Directives: AddType and IfModule
272
        // - PHP?: No
273
274
        $htaccess = <<<'EOD'
275 2
<IfModule mod_xxx.c>
276
    AddType image/gif .test
277
</IfModule>
278
<IfModule !mod_xxx.c>
279
    AddType image/jpeg .test
280
</IfModule>
281
EOD;
282
283 2
        $htaccess = str_replace('mod_xxx', 'mod_' . $this->moduleName, $htaccess);
284
285
        return [
286 2
            'subdir' => $this->getSubDir() . '/add-type',
287
            'files' => [
288 2
                ['.htaccess', $htaccess],
289
                ['request-me.test', 'hi'],
290
            ],
291 2
            'request' => 'request-me.test',
292
            'interpretation' => [
293
                ['success', 'headers', 'contains-key-value', 'Content-Type', 'image/gif'],
294
                ['failure', 'headers', 'contains-key-value', 'Content-Type', 'image/jpeg'],
295
            ]
296
        ];
297
    }
298
299
    /**
300
     *  @return  array
301
     */
302
    private function getLastTest()
0 ignored issues
show
Unused Code introduced by
The method getLastTest() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
303
    {
304
        return [
305
            'subdir' => $this->getSubDir() . '/last-test',
306
            'files' => [
307
                ['request-me.test', '0'],
308
            ],
309
            'request' => 'request-me.test',
310
            'interpretation' => [
311
                ['inconclusive'],
312
            ]
313
        ];
314
    }
315
316
    /**
317
     * @return  bool|null
318
     */
319 12
    private function run2()
320
    {
321 12
        $hct = $this->getHtaccessCapabilityTester();
322
323 12
        $testResult = $hct->customTest($this->getServerSignatureBasedTest());
324 12
        if (!is_null($testResult)) {
325
            // PHP
326 2
            return $testResult;
327
        }
328
329 10
        if ($hct->contentDigestWorks()) {
330
            // Override: Options
331 2
            return $hct->customTest($this->getContentDigestBasedTest());
332
        }
333
334 8
        if ($hct->addTypeWorks()) {
335
            // Override: FileInfo, Status: Base (mod_mime)
336 2
            return $hct->customTest($this->getAddTypeBasedTest());
337
        }
338
339 6
        if ($hct->directoryIndexWorks()) {
340
            // Override: Indexes, Status: Base (mod_dir)
341 2
            return $hct->customTest($this->getDirectoryIndexBasedTest());
342
        }
343
344 4
        if ($hct->rewriteWorks()) {
345
            // Override: FileInfo, Module: mod_rewrite
346 2
            return $hct->customTest($this->getRewriteBasedTest());
347
        }
348
349 2
        if ($hct->headerSetWorks()) {
350
            //Override: FileInfo, Module: mod_headers
351 2
            return $hct->customTest($this->getHeaderSetBasedTest());
352
        }
353
        return null;
354
    }
355
356
    /**
357
     *  Run the test.
358
     *
359
     * @param  string  $baseDir  Directory on the server where the test files can be put
360
     * @param  string  $baseUrl  The base URL of the test files
361
     *
362
     * @return TestResult   Returns a test result
363
     */
364 14
    public function run($baseDir, $baseUrl)
365
    {
366 14
        $this->prepareForRun($baseDir, $baseUrl);
367
368 14
        $hct = $this->getHtaccessCapabilityTester();
369
370 14
        $htaccessEnabledTest = $hct->htaccessEnabled();
371 14
        if ($htaccessEnabledTest === false) {
372 1
            return new TestResult(false, '.htaccess files are ignored');
373 13
        } elseif (is_null($htaccessEnabledTest)) {
0 ignored issues
show
introduced by
The condition is_null($htaccessEnabledTest) is always false.
Loading history...
374
            // We happen to know that if that test cannot establish anything,
375
            // then none of the usual weapons works - we can surrender
376 1
            return new TestResult(null, 'no methods available - we surrender early');
377
        }
378
379 12
        $status = $this->run2();
380 12
        if (is_null($status)) {
381
            return new TestResult(null, 'no methods worked');
382
        } else {
383 12
            return new TestResult($status, '');
384
        }
385
    }
386
}
387