Issues (323)

tests/index.php (1 issue)

1
<?php
2
3
// File accessed by http requests sent by the test suite, enabling testing of demo, debugger, extras files.
4
// It makes all errors visible, triggers generation of code-coverage information, and runs the target file,
5
// which is specified as GET param.
6
7
/// @todo inject a custom Logger which logs in a parseable format + known location, so that the test code can check
8
///       the log as part of (or after) test execution
9
10
// In case this file is made available on an open-access server, avoid it being useable by anyone who can not also
11
// write a specific file to disk.
12
// NB: keep filename, cookie name in sync with the code within the TestCase classes sending http requests to this file
13
$idFile = sys_get_temp_dir() . '/phpunit_rand_id.txt';
14
$randId = isset($_COOKIE['PHPUNIT_RANDOM_TEST_ID']) ? $_COOKIE['PHPUNIT_RANDOM_TEST_ID'] : '';
15
$fileId = file_exists($idFile) ? file_get_contents($idFile) : '';
16
if ($randId == '' || $fileId == '' || $fileId !== $randId) {
17
    die('This url can only be accessed by the test suite');
18
}
19
20
// Make errors visible
21
ini_set('display_errors', true);
22
error_reporting(E_ALL);
23
24
// Set up a constant which can be used by demo code to tell if the testuite is in action.
25
// We use a constant because it can not be injected via GET/POST/COOKIE/ENV
26
const TESTMODE = true;
27
28
// Out-of-band information: let the client manipulate the page operations
29
if (isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && extension_loaded('xdebug')) {
30
    // NB: this has to be kept in sync with phunit_coverage.php
31
    $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = '/tmp/phpxmlrpc_coverage';
32
    if (!is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) {
33
        mkdir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']);
34
        chmod($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'], 0777);
35
    }
36
37
    include_once __DIR__ . "/../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/prepend.php";
38
}
39
40
$targetFile = null;
41
$rootDir = dirname(__DIR__);
42
if (isset($_GET['debugger'])) {
43
    if (strpos(realpath($rootDir.'/debugger/'.$_GET['debugger']), realpath($rootDir.'/debugger/')) === 0) {
44
        $targetFile = realpath($rootDir.'/debugger/'.$_GET['debugger']);
45
    }
46
} elseif (isset($_GET['demo'])) {
47
    if (strpos(realpath($rootDir.'/demo/'.$_GET['demo']), realpath($rootDir.'/demo/')) === 0) {
48
        $targetFile = realpath($rootDir.'/demo/'.$_GET['demo']);
49
    }
50
} elseif (isset($_GET['extras'])) {
51
    if (strpos(realpath($rootDir.'/extras/'.$_GET['extras']), realpath($rootDir.'/extras/')) === 0) {
52
        $targetFile = realpath($rootDir.'/extras/'.$_GET['extras']);
53
    }
54
}
55
if ($targetFile) {
56
    include $targetFile;
57
}
58
59
if (isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && extension_loaded('xdebug')) {
60
    include_once __DIR__ . "/../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/append.php";
61
}
62
63
/**
64
 * @param PhpXmlRpc\Server $s
65
 * @return void
66
 */
67
function preflight($s) {
68
    if (isset($_GET['FORCE_DEBUG'])) {
69
        $s->setOption(PhpXmlRpc\Server::OPT_DEBUG, $_GET['FORCE_DEBUG']);
70
    }
71
    if (isset($_GET['RESPONSE_ENCODING'])) {
72
        $s->setOption(PhpXmlRpc\Server::OPT_RESPONSE_CHARSET_ENCODING, $_GET['RESPONSE_ENCODING']);
73
    }
74
    if (isset($_GET['DETECT_ENCODINGS'])) {
75
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_detectencodings = $_GET['DETECT_ENCODINGS'];
76
    }
77
    if (isset($_GET['EXCEPTION_HANDLING'])) {
78
        $s->setOption(PhpXmlRpc\Server::OPT_EXCEPTION_HANDLING, $_GET['EXCEPTION_HANDLING']);
79
    }
80
    if (isset($_GET['FORCE_AUTH'])) {
81
        // We implement both  Basic and Digest auth in php to avoid having to set it up in a vhost.
82
        // Code taken from php.net
83
        // NB: we do NOT check for valid credentials!
84
        if ($_GET['FORCE_AUTH'] == 'Basic') {
85
            if (!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['REMOTE_USER']) && !isset($_SERVER['REDIRECT_REMOTE_USER'])) {
86
                header('HTTP/1.0 401 Unauthorized');
87
                header('WWW-Authenticate: Basic realm="Phpxmlrpc Basic Realm"');
88
                die('Text visible if user hits Cancel button');
89
            }
90
        } elseif ($_GET['FORCE_AUTH'] == 'Digest') {
91
            if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
92
                header('HTTP/1.1 401 Unauthorized');
93
                header('WWW-Authenticate: Digest realm="Phpxmlrpc Digest Realm",qop="auth",nonce="' . uniqid() . '",opaque="' . md5('Phpxmlrpc Digest Realm') . '"');
94
                die('Text visible if user hits Cancel button');
95
            }
96
        }
97
    }
98
    if (isset($_GET['FORCE_REDIRECT'])) {
99
        header('HTTP/1.0 302 Found');
100
        unset($_GET['FORCE_REDIRECT']);
101
        header('Location: ' . $_SERVER['REQUEST_URI'] . (count($_GET) ? '?' . http_build_query($_GET) : ''));
102
        die();
103
    }
104
    if (isset($_GET['SLOW_LORIS']) && $_GET['SLOW_LORIS'] > 0) {
105
        slowLoris((int)$_GET['SLOW_LORIS'], $s);
106
        die();
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
107
    }
108
}
109
110
/**
111
 * Used to test timeouts: send out the payload one chunk every $secs second (10 chunks in total)
112
 * @param int $secs between 1 and 60
113
 * @param PhpXmlrpc\Server $s
114
 */
115
function slowLoris($secs, $s)
116
{
117
    /// @todo as is, this method can not be used by eg. jsonrpc servers. We could look at the value $s::$responseClass
118
    ///       to improve that
119
    $strings = array('<?xml version="1.0"?>','<methodResponse>','<params>','<param>','<value>','<string></string>','</value>','</param>','</params>','</methodResponse>');
120
121
    header('Content-type: xml; charset=utf-8');
122
    foreach($strings as $i => $string) {
123
        echo $string;
124
        flush();
125
        if ($i < count($strings) && $secs > 0 && $secs <= 60) {
126
            sleep($secs);
127
        }
128
    }
129
}
130