| Total Complexity | 66 |
| Total Lines | 652 |
| Duplicated Lines | 0 % |
| Changes | 17 | ||
| Bugs | 3 | Features | 6 |
Complex classes like HTTPTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use HTTPTest, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 14 | class HTTPTest extends ServerTest |
||
| 15 | { |
||
| 16 | protected $expectHttp2 = false; |
||
| 17 | |||
| 18 | protected $unsafeMethods = array( |
||
| 19 | 'testCatchExceptions', 'testCatchErrors', 'testUtf8Method', 'testServerComments', |
||
| 20 | 'testExoticCharsetsRequests', 'testExoticCharsetsRequests2', 'testExoticCharsetsRequests3', |
||
| 21 | 'testWrapInexistentUrl', 'testNegativeDebug', 'testTimeout' |
||
| 22 | ); |
||
| 23 | |||
| 24 | /** |
||
| 25 | * Returns all test methods from the base class, except the ones which failed already and the ones which make no sense |
||
| 26 | * to run with different HTTP options. |
||
| 27 | * |
||
| 28 | * @todo (re)introduce skipping of tests which failed when executed individually even if test runs happen as separate processes |
||
| 29 | * @todo reintroduce skipping of tests within the loop |
||
| 30 | * @todo testTimeout is actually good to be tested with proxies etc - but it slows down the testsuite a lot! |
||
| 31 | * @todo see also 'refactor' todo at the top of the class declaration |
||
| 32 | */ |
||
| 33 | public function getSingleHttpTestMethods() |
||
| 34 | { |
||
| 35 | $methods = array(); |
||
| 36 | // as long as we are descendants, get_class_methods will list private/protected methods |
||
| 37 | foreach(get_class_methods('ServerTest') as $method) |
||
| 38 | { |
||
| 39 | if (strpos($method, 'test') === 0 && !in_array($method, $this->unsafeMethods)) |
||
| 40 | { |
||
| 41 | if (!isset(self::$failed_tests[$method])) { |
||
| 42 | $methods[$method] = array($method); |
||
| 43 | } |
||
| 44 | } |
||
| 45 | } |
||
| 46 | |||
| 47 | return $methods; |
||
| 48 | } |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @param \PhpXmlRpc\Response $r |
||
| 52 | * @return void |
||
| 53 | */ |
||
| 54 | protected function validateResponse($r) |
||
| 55 | { |
||
| 56 | if ($this->expectHttp2) { |
||
| 57 | $hr = $r->httpResponse(); |
||
| 58 | $this->assertEquals("2", @$hr['protocol_version'], 'Server response not using http version 2'); |
||
| 59 | } |
||
| 60 | } |
||
| 61 | |||
| 62 | public function testKeepAlives() |
||
| 63 | { |
||
| 64 | if (!function_exists('curl_init')) |
||
| 65 | { |
||
| 66 | $this->markTestSkipped('CURL missing: cannot test http 1.1'); |
||
| 67 | } |
||
| 68 | |||
| 69 | $this->method = 'http11'; |
||
| 70 | $this->client->method = 'http11'; |
||
| 71 | $this->client->keepalive = true; |
||
|
|
|||
| 72 | |||
| 73 | // to successfully test keepalive, we have to reuse the same client for all tests, we can not recreate one on setup/teardown... |
||
| 74 | foreach ($this->getSingleHttpTestMethods() as $methods) { |
||
| 75 | $method = $methods[0]; |
||
| 76 | $this->$method(); |
||
| 77 | } |
||
| 78 | } |
||
| 79 | |||
| 80 | /** |
||
| 81 | * @dataProvider getSingleHttpTestMethods |
||
| 82 | * @param string $method |
||
| 83 | */ |
||
| 84 | public function testRedirects($method) |
||
| 85 | { |
||
| 86 | if (!function_exists('curl_init')) |
||
| 87 | { |
||
| 88 | $this->markTestSkipped('CURL missing: cannot test redirects'); |
||
| 89 | } |
||
| 90 | |||
| 91 | /// @todo replace with setOption when dropping the BC layer |
||
| 92 | $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_ALWAYS); |
||
| 93 | $this->client->setCurlOptions(array(CURLOPT_FOLLOWLOCATION => true, CURLOPT_POSTREDIR => 3)); |
||
| 94 | |||
| 95 | $this->$method(); |
||
| 96 | } |
||
| 97 | |||
| 98 | /** |
||
| 99 | * @dataProvider getSingleHttpTestMethods |
||
| 100 | * @param string $method |
||
| 101 | */ |
||
| 102 | public function testHttp11($method) |
||
| 103 | { |
||
| 104 | if (!function_exists('curl_init')) |
||
| 105 | { |
||
| 106 | $this->markTestSkipped('CURL missing: cannot test http 1.1'); |
||
| 107 | } |
||
| 108 | |||
| 109 | $this->method = 'http11'; // not an error the double assignment! |
||
| 110 | $this->client->method = 'http11'; |
||
| 111 | $this->client->keepalive = false; |
||
| 112 | |||
| 113 | $this->$method(); |
||
| 114 | } |
||
| 115 | |||
| 116 | /** |
||
| 117 | * @dataProvider getSingleHttpTestMethods |
||
| 118 | * @param string $method |
||
| 119 | */ |
||
| 120 | public function testHttp10Curl($method) |
||
| 121 | { |
||
| 122 | if (!function_exists('curl_init')) |
||
| 123 | { |
||
| 124 | $this->markTestSkipped('CURL missing: cannot test http 1.1'); |
||
| 125 | } |
||
| 126 | |||
| 127 | $this->method = 'http10'; // not an error the double assignment! |
||
| 128 | $this->client->method = 'http10'; |
||
| 129 | /// @todo replace with setOption when dropping the BC layer |
||
| 130 | $this->client->keepalive = false; |
||
| 131 | $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_ALWAYS); |
||
| 132 | |||
| 133 | $this->$method(); |
||
| 134 | } |
||
| 135 | |||
| 136 | /** |
||
| 137 | * @dataProvider getAvailableUseCurlOptions |
||
| 138 | */ |
||
| 139 | public function testTimeout($curlOpt) |
||
| 140 | { |
||
| 141 | $this->client->setOption(\PhpXmlRpc\Client::OPT_USE_CURL, $curlOpt); |
||
| 142 | |||
| 143 | // decrease the timeout to avoid slowing down the testsuite too much |
||
| 144 | $this->timeout = 3; |
||
| 145 | |||
| 146 | // the server will wait for 1 second before sending back the response - should pass |
||
| 147 | $m = new xmlrpcmsg('tests.sleep', array(new xmlrpcval(1, 'int'))); |
||
| 148 | // this checks for a non-failed call |
||
| 149 | $time = microtime(true); |
||
| 150 | $this->send($m); |
||
| 151 | $time = microtime(true) - $time; |
||
| 152 | $this->assertGreaterThan(1.0, $time); |
||
| 153 | $this->assertLessThan(2.0, $time); |
||
| 154 | |||
| 155 | // the server will wait for 5 seconds before sending back the response - fail |
||
| 156 | $m = new xmlrpcmsg('tests.sleep', array(new xmlrpcval(5, 'int'))); |
||
| 157 | $time = microtime(true); |
||
| 158 | $r = $this->send($m, array(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerr['http_error'], PhpXmlRpc\PhpXmlRpc::$xmlrpcerr['curl_fail'])); |
||
| 159 | $time = microtime(true) - $time; |
||
| 160 | $this->assertGreaterThan(2.0, $time); |
||
| 161 | $this->assertLessThan(4.0, $time); |
||
| 162 | |||
| 163 | /* |
||
| 164 | // the server will send back the response one chunk per second, waiting 5 seconds in between chunks |
||
| 165 | $m = new xmlrpcmsg('examples.addtwo', array(new xmlrpcval(1, 'int'), new xmlrpcval(2, 'int'))); |
||
| 166 | $this->addQueryParams(array('SLOW_LORIS' => 5)); |
||
| 167 | $time = microtime(true); |
||
| 168 | $this->send($m, array(PhpXmlRpc\PhpXmlRpc::$xmlrpcerr['http_error'], PhpXmlRpc\PhpXmlRpc::$xmlrpcerr['curl_fail'])); |
||
| 169 | $time = microtime(true) - $time; |
||
| 170 | $this->assertGreaterThan(2.0, $time); |
||
| 171 | $this->assertLessThan(4.0, $time); |
||
| 172 | */ |
||
| 173 | |||
| 174 | // pesky case: the server will send back the response one chunk per second, taking 10 seconds in total |
||
| 175 | $m = new xmlrpcmsg('examples.addtwo', array(new xmlrpcval(1, 'int'), new xmlrpcval(2, 'int'))); |
||
| 176 | $this->addQueryParams(array('SLOW_LORIS' => 1)); |
||
| 177 | $time = microtime(true); |
||
| 178 | $this->send($m, array(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerr['http_error'], PhpXmlRpc\PhpXmlRpc::$xmlrpcerr['curl_fail'])); |
||
| 179 | $time = microtime(true) - $time; |
||
| 180 | $this->assertGreaterThan(2.0, $time); |
||
| 181 | $this->assertLessThan(4.0, $time); |
||
| 182 | } |
||
| 183 | |||
| 184 | // *** auth tests *** |
||
| 185 | |||
| 186 | /** |
||
| 187 | * @dataProvider getSingleHttpTestMethods |
||
| 188 | * @param string $method |
||
| 189 | * @todo add a basic-auth test using curl |
||
| 190 | */ |
||
| 191 | public function testBasicAuth($method) |
||
| 192 | { |
||
| 193 | $this->client->setCredentials('test', 'test'); |
||
| 194 | $this->addQueryParams(array('FORCE_AUTH' => 'Basic')); |
||
| 195 | |||
| 196 | $this->$method(); |
||
| 197 | } |
||
| 198 | |||
| 199 | /** |
||
| 200 | * @dataProvider getSingleHttpTestMethods |
||
| 201 | * @param string $method |
||
| 202 | */ |
||
| 203 | public function testDigestAuth($method) |
||
| 204 | { |
||
| 205 | if (!function_exists('curl_init')) |
||
| 206 | { |
||
| 207 | $this->markTestSkipped('CURL missing: cannot test digest auth functionality'); |
||
| 208 | } |
||
| 209 | |||
| 210 | $this->client->setCredentials('test', 'test', CURLAUTH_DIGEST); |
||
| 211 | $this->addQueryParams(array('FORCE_AUTH' => 'Digest')); |
||
| 212 | $this->method = 'http11'; |
||
| 213 | $this->client->method = 'http11'; |
||
| 214 | |||
| 215 | $this->$method(); |
||
| 216 | } |
||
| 217 | |||
| 218 | /// @todo if curl is onboard, add a test for NTLM auth - note that that will require server-side support, |
||
| 219 | /// see eg. https://modntlm.sourceforge.net/ , https://blog.mayflower.de/125-Accessing-NTLM-secured-resources-with-PHP.html |
||
| 220 | |||
| 221 | // *** compression tests *** |
||
| 222 | |||
| 223 | /** |
||
| 224 | * @dataProvider getSingleHttpTestMethods |
||
| 225 | * @param string $method |
||
| 226 | */ |
||
| 227 | public function testDeflate($method) |
||
| 228 | { |
||
| 229 | if (!function_exists('gzdeflate')) |
||
| 230 | { |
||
| 231 | $this->markTestSkipped('Zlib missing: cannot test deflate functionality'); |
||
| 232 | } |
||
| 233 | |||
| 234 | $this->client->accepted_compression = array('deflate'); |
||
| 235 | $this->client->request_compression = 'deflate'; |
||
| 236 | |||
| 237 | $this->$method(); |
||
| 238 | } |
||
| 239 | |||
| 240 | /** |
||
| 241 | * @dataProvider getSingleHttpTestMethods |
||
| 242 | * @param string $method |
||
| 243 | */ |
||
| 244 | public function testGzip($method) |
||
| 245 | { |
||
| 246 | if (!function_exists('gzdeflate')) |
||
| 247 | { |
||
| 248 | $this->markTestSkipped('Zlib missing: cannot test gzip functionality'); |
||
| 249 | } |
||
| 250 | |||
| 251 | $this->client->accepted_compression = array('gzip'); |
||
| 252 | $this->client->request_compression = 'gzip'; |
||
| 253 | |||
| 254 | $this->$method(); |
||
| 255 | } |
||
| 256 | |||
| 257 | /** |
||
| 258 | * @dataProvider getSingleHttpTestMethods |
||
| 259 | * @param string $method |
||
| 260 | */ |
||
| 261 | public function testHttp11Gzip($method) |
||
| 262 | { |
||
| 263 | if (!function_exists('curl_init')) |
||
| 264 | { |
||
| 265 | $this->markTestSkipped('CURL missing: cannot test http 1.1'); |
||
| 266 | } |
||
| 267 | $this->method = 'http11'; // not an error the double assignment! |
||
| 268 | $this->client->method = 'http11'; |
||
| 269 | $this->client->keepalive = false; |
||
| 270 | $this->client->accepted_compression = array('gzip'); |
||
| 271 | $this->client->request_compression = 'gzip'; |
||
| 272 | |||
| 273 | $this->$method(); |
||
| 274 | } |
||
| 275 | |||
| 276 | /** |
||
| 277 | * @dataProvider getSingleHttpTestMethods |
||
| 278 | * @param string $method |
||
| 279 | */ |
||
| 280 | public function testHttp11Deflate($method) |
||
| 281 | { |
||
| 282 | if (!function_exists('curl_init')) |
||
| 283 | { |
||
| 284 | $this->markTestSkipped('CURL missing: cannot test http 1.1'); |
||
| 285 | } |
||
| 286 | $this->method = 'http11'; // not an error the double assignment! |
||
| 287 | $this->client->method = 'http11'; |
||
| 288 | $this->client->keepalive = false; |
||
| 289 | $this->client->accepted_compression = array('deflate'); |
||
| 290 | $this->client->request_compression = 'deflate'; |
||
| 291 | |||
| 292 | $this->$method(); |
||
| 293 | } |
||
| 294 | |||
| 295 | // *** https tests *** |
||
| 296 | |||
| 297 | /** |
||
| 298 | * @dataProvider getSingleHttpTestMethods |
||
| 299 | * @param string $method |
||
| 300 | * @todo bring back tests for sslversion values 1 to 5, once we figure out how to make curl actually enforce those |
||
| 301 | */ |
||
| 302 | public function testHttpsCurl($method) |
||
| 303 | { |
||
| 304 | if (!function_exists('curl_init')) |
||
| 305 | { |
||
| 306 | $this->markTestSkipped('CURL missing: cannot test https functionality'); |
||
| 307 | } |
||
| 308 | else if ($this->args['HTTPSSERVER'] == '') |
||
| 309 | { |
||
| 310 | $this->markTestSkipped('HTTPS SERVER definition missing: cannot test https'); |
||
| 311 | } |
||
| 312 | |||
| 313 | $this->client->server = $this->args['HTTPSSERVER']; |
||
| 314 | $this->method = 'https'; |
||
| 315 | $this->client->method = 'https'; |
||
| 316 | $this->client->path = $this->args['HTTPSURI']; |
||
| 317 | /// @todo replace with setOptions when dropping the BC layer |
||
| 318 | $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']); |
||
| 319 | $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']); |
||
| 320 | $this->client->setSSLVersion($this->args['SSLVERSION']); |
||
| 321 | |||
| 322 | // It seems that curl will happily always use http2 whenever it has it compiled in. We thus force http 1.1 |
||
| 323 | // for this test, as we have a dedicated test for http2. |
||
| 324 | /// @todo for completeness, we should run at least one test where we also set CURLOPT_SSL_ENABLE_ALPN = false |
||
| 325 | $this->client->setOption(\PhpXmlRpc\Client::OPT_EXTRA_CURL_OPTS, array(CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1)); |
||
| 326 | |||
| 327 | $this->$method(); |
||
| 328 | } |
||
| 329 | |||
| 330 | /** |
||
| 331 | * @dataProvider getSingleHttpTestMethods |
||
| 332 | * @param string $method |
||
| 333 | * @todo bring back tests for sslversion values 1 to 5, once we figure out the correct combination of php, ssl and |
||
| 334 | * apache which actually work with those |
||
| 335 | */ |
||
| 336 | public function testHttpsSocket($method) |
||
| 337 | { |
||
| 338 | if ($this->args['HTTPSSERVER'] == '') |
||
| 339 | { |
||
| 340 | $this->markTestSkipped('HTTPS SERVER definition missing: cannot test https'); |
||
| 341 | } |
||
| 342 | |||
| 343 | /// @todo investigate deeper: can we make this test work with php < 7.2? |
||
| 344 | /// See changes in STREAM_CRYPTO_METHOD_TLS constants in 7.2 at https://wiki.php.net/rfc/improved-tls-constants |
||
| 345 | /// and in 5.6 at https://www.php.net/manual/en/migration56.openssl.php#migration56.openssl.crypto-method |
||
| 346 | /// Take into account also that the issue might in fact relate to the server-side (Apache) ssl config |
||
| 347 | if (version_compare(PHP_VERSION, '7.2', '<')) |
||
| 348 | { |
||
| 349 | if (is_readable('/etc/os-release')) { |
||
| 350 | $output = file_get_contents('/etc/os-release'); |
||
| 351 | preg_match('/VERSION="?([0-9]+)/', $output, $matches); |
||
| 352 | $ubuntuVersion = @$matches[1]; |
||
| 353 | } else { |
||
| 354 | exec('uname -a', $output, $retval); |
||
| 355 | preg_match('/ubunutu([0-9]+)/', $output[0], $matches); |
||
| 356 | $ubuntuVersion = @$matches[1]; |
||
| 357 | } |
||
| 358 | if ($ubuntuVersion >= 20 && $this->args['SSLVERSION'] != 6) { |
||
| 359 | $this->markTestSkipped('HTTPS via Socket known to fail on php less than 7.2 on Ubuntu 20 and higher'); |
||
| 360 | } |
||
| 361 | } |
||
| 362 | |||
| 363 | $this->client->server = $this->args['HTTPSSERVER']; |
||
| 364 | $this->method = 'https'; |
||
| 365 | $this->client->method = 'https'; |
||
| 366 | $this->client->path = $this->args['HTTPSURI']; |
||
| 367 | /// @todo replace with setOptions when dropping the BC layer |
||
| 368 | $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']); |
||
| 369 | $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']); |
||
| 370 | $this->client->setSSLVersion($this->args['SSLVERSION']); |
||
| 371 | $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_NEVER); |
||
| 372 | |||
| 373 | /// @todo find a value for OPT_EXTRA_SOCKET_OPTS that we can check via an assertion |
||
| 374 | /// @see https://www.php.net/manual/en/context.php |
||
| 375 | |||
| 376 | if (version_compare(PHP_VERSION, '8.0', '>=')) |
||
| 377 | { |
||
| 378 | $version = explode('.', PHP_VERSION); |
||
| 379 | /// @see https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour for levels |
||
| 380 | $this->client->setOption(\PhpXmlRpc\Client::OPT_EXTRA_SOCKET_OPTS, |
||
| 381 | array('ssl' => array( |
||
| 382 | // security level is available as of php 7.2.0 + openssl 1.1.0 according to the docs |
||
| 383 | 'security_level' => min(1 + $version[1], 5), |
||
| 384 | // capture_session_meta was deprecated in php 7.0 |
||
| 385 | //'capture_session_meta' => true, |
||
| 386 | )) |
||
| 387 | ); |
||
| 388 | } |
||
| 389 | $this->$method(); |
||
| 390 | } |
||
| 391 | |||
| 392 | // *** http2 tests *** |
||
| 393 | |||
| 394 | /** |
||
| 395 | * @dataProvider getSingleHttpTestMethods |
||
| 396 | * @param string $method |
||
| 397 | */ |
||
| 398 | public function testHttp2NoTls($method) |
||
| 399 | { |
||
| 400 | if (!function_exists('curl_init')) |
||
| 401 | { |
||
| 402 | $this->markTestSkipped('CURL missing: cannot test http/2'); |
||
| 403 | } else if (!defined('CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE')) |
||
| 404 | { |
||
| 405 | $this->markTestSkipped('CURL http/2 support missing: cannot test http/2'); |
||
| 406 | } |
||
| 407 | $r = $this->send(new \PhpXmlRpc\Request('tests.hasHTTP2')); |
||
| 408 | if ($r->scalarVal() != true) { |
||
| 409 | $this->markTestSkipped('Server-side support missing: cannot test http/2'); |
||
| 410 | } |
||
| 411 | |||
| 412 | $this->method = 'h2c'; // not an error the double assignment! |
||
| 413 | $this->client->method = 'h2c'; |
||
| 414 | //$this->client->keepalive = false; // q: is this a good idea? |
||
| 415 | |||
| 416 | $this->expectHttp2 = true; |
||
| 417 | $this->$method(); |
||
| 418 | $this->expectHttp2 = false; |
||
| 419 | } |
||
| 420 | |||
| 421 | /** |
||
| 422 | * @dataProvider getSingleHttpTestMethods |
||
| 423 | * @param string $method |
||
| 424 | */ |
||
| 425 | public function testHttp2tls($method) |
||
| 426 | { |
||
| 427 | if (!function_exists('curl_init')) |
||
| 428 | { |
||
| 429 | $this->markTestSkipped('CURL missing: cannot test http/2 tls'); |
||
| 430 | } else if ($this->args['HTTPSSERVER'] == '') |
||
| 431 | { |
||
| 432 | $this->markTestSkipped('HTTPS SERVER definition missing: cannot test http/2 tls'); |
||
| 433 | } else if (!defined('CURL_HTTP_VERSION_2_0')) |
||
| 434 | { |
||
| 435 | $this->markTestSkipped('CURL http/2 support missing: cannot test http/2 tls'); |
||
| 436 | } |
||
| 437 | $r = $this->send(new \PhpXmlRpc\Request('tests.hasHTTP2')); |
||
| 438 | if ($r->scalarVal() != true) { |
||
| 439 | $this->markTestSkipped('Server-side support missing: cannot test http/2'); |
||
| 440 | } |
||
| 441 | |||
| 442 | $this->method = 'h2'; |
||
| 443 | $this->client->method = 'h2'; |
||
| 444 | $this->client->server = $this->args['HTTPSSERVER']; |
||
| 445 | $this->client->path = $this->args['HTTPSURI']; |
||
| 446 | /// @todo replace with setOptions when dropping the BC layer |
||
| 447 | $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']); |
||
| 448 | $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']); |
||
| 449 | $this->client->setSSLVersion($this->args['SSLVERSION']); |
||
| 450 | |||
| 451 | $this->expectHttp2 = true; |
||
| 452 | $this->$method(); |
||
| 453 | $this->expectHttp2 = false; |
||
| 454 | } |
||
| 455 | |||
| 456 | // *** proxy tests *** |
||
| 457 | |||
| 458 | /** |
||
| 459 | * @dataProvider getSingleHttpTestMethods |
||
| 460 | * @param string $method |
||
| 461 | */ |
||
| 462 | public function testProxy($method) |
||
| 463 | { |
||
| 464 | if ($this->args['PROXYSERVER'] == '') |
||
| 465 | { |
||
| 466 | $this->markTestSkipped('PROXYSERVER definition missing: cannot test proxy'); |
||
| 467 | } |
||
| 468 | |||
| 469 | $this->client->setProxy($this->args['PROXYSERVER'], $this->args['PROXYPORT']); |
||
| 470 | |||
| 471 | $this->$method(); |
||
| 472 | } |
||
| 473 | |||
| 474 | /** |
||
| 475 | * @dataProvider getSingleHttpTestMethods |
||
| 476 | * @param string $method |
||
| 477 | */ |
||
| 478 | public function testHttp11Proxy($method) |
||
| 479 | { |
||
| 480 | if (!function_exists('curl_init')) |
||
| 481 | { |
||
| 482 | $this->markTestSkipped('CURL missing: cannot test http 1.1 w. proxy'); |
||
| 483 | } |
||
| 484 | else if ($this->args['PROXYSERVER'] == '') |
||
| 485 | { |
||
| 486 | $this->markTestSkipped('PROXYSERVER definition missing: cannot test proxy w. http 1.1'); |
||
| 487 | } |
||
| 488 | |||
| 489 | $this->method = 'http11'; // not an error the double assignment! |
||
| 490 | $this->client->method = 'http11'; |
||
| 491 | $this->client->setProxy($this->args['PROXYSERVER'], $this->args['PROXYPORT']); |
||
| 492 | $this->client->keepalive = false; |
||
| 493 | |||
| 494 | $this->$method(); |
||
| 495 | } |
||
| 496 | |||
| 497 | /** |
||
| 498 | * @todo this method is known to fail on bionic/php5.5. Investigate if we can fix that. |
||
| 499 | * Error message: "CURL error: gnutls_handshake() failed: The TLS connection was non-properly terminated" |
||
| 500 | * @dataProvider getSingleHttpTestMethods |
||
| 501 | * @param string $method |
||
| 502 | */ |
||
| 503 | public function testHttpsProxyCurl($method) |
||
| 504 | { |
||
| 505 | if (!function_exists('curl_init')) |
||
| 506 | { |
||
| 507 | $this->markTestSkipped('CURL missing: cannot test https w. proxy'); |
||
| 508 | } |
||
| 509 | else if ($this->args['PROXYSERVER'] == '') |
||
| 510 | { |
||
| 511 | $this->markTestSkipped('PROXYSERVER definition missing: cannot test proxy w. https'); |
||
| 512 | } |
||
| 513 | else if ($this->args['HTTPSSERVER'] == '') |
||
| 514 | { |
||
| 515 | $this->markTestSkipped('HTTPS SERVER definition missing: cannot test https w. proxy'); |
||
| 516 | } |
||
| 517 | |||
| 518 | $this->method = 'https'; |
||
| 519 | $this->client->method = 'https'; |
||
| 520 | $this->client->server = $this->args['HTTPSSERVER']; |
||
| 521 | $this->client->path = $this->args['HTTPSURI']; |
||
| 522 | /// @todo replace with setOptions when dropping the BC layer |
||
| 523 | $this->client->setProxy($this->args['PROXYSERVER'], $this->args['PROXYPORT']); |
||
| 524 | $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']); |
||
| 525 | $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']); |
||
| 526 | $this->client->setSSLVersion($this->args['SSLVERSION']); |
||
| 527 | /// @todo push this override to the test matrix config? |
||
| 528 | if (version_compare(PHP_VERSION, '8.0', '>=') && $this->args['SSLVERSION'] == 0) |
||
| 529 | { |
||
| 530 | $version = explode('.', PHP_VERSION); |
||
| 531 | $this->client->setSSLVersion(min(4 + $version[1], 7)); |
||
| 532 | } |
||
| 533 | |||
| 534 | $this->$method(); |
||
| 535 | } |
||
| 536 | |||
| 537 | /* NB: this is not yet supported by the Client class |
||
| 538 | /** |
||
| 539 | * @dataProvider getSingleHttpTestMethods |
||
| 540 | * @param string $method |
||
| 541 | * / |
||
| 542 | public function testHttpsProxySocket($method) |
||
| 543 | { |
||
| 544 | if ($this->args['PROXYSERVER'] == '') |
||
| 545 | { |
||
| 546 | $this->markTestSkipped('PROXYSERVER definition missing: cannot test proxy w. https'); |
||
| 547 | } |
||
| 548 | else if ($this->args['HTTPSSERVER'] == '') |
||
| 549 | { |
||
| 550 | $this->markTestSkipped('HTTPS SERVER definition missing: cannot test https w. proxy'); |
||
| 551 | } |
||
| 552 | |||
| 553 | if (version_compare(PHP_VERSION, '7.2', '<')) |
||
| 554 | { |
||
| 555 | if (is_readable('/etc/os-release')) { |
||
| 556 | $output = file_get_contents('/etc/os-release'); |
||
| 557 | preg_match('/VERSION="?([0-9]+)/', $output, $matches); |
||
| 558 | $ubuntuVersion = @$matches[1]; |
||
| 559 | } else { |
||
| 560 | exec('uname -a', $output, $retval); |
||
| 561 | preg_match('/ubunutu([0-9]+)/', $output[0], $matches); |
||
| 562 | $ubuntuVersion = @$matches[1]; |
||
| 563 | } |
||
| 564 | if ($ubuntuVersion >= 20 && $this->args['SSLVERSION'] != 6) { |
||
| 565 | $this->markTestSkipped('HTTPS via Socket known to fail on php less than 7.2 on Ubuntu 20 and higher'); |
||
| 566 | } |
||
| 567 | } |
||
| 568 | |||
| 569 | $this->method = 'https'; |
||
| 570 | $this->client->method = 'https'; |
||
| 571 | $this->client->server = $this->args['HTTPSSERVER']; |
||
| 572 | $this->client->path = $this->args['HTTPSURI']; |
||
| 573 | /// @todo replace with setOptions when dropping the BC layer |
||
| 574 | $this->client->setProxy($this->args['PROXYSERVER'], $this->args['PROXYPORT']); |
||
| 575 | $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']); |
||
| 576 | $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']); |
||
| 577 | $this->client->setSSLVersion($this->args['SSLVERSION']); |
||
| 578 | $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_NEVER); |
||
| 579 | /// @todo push this override to the test matrix config? |
||
| 580 | if (version_compare(PHP_VERSION, '8.1', '>=') && $this->args['SSLVERSION'] == 0) |
||
| 581 | { |
||
| 582 | $version = explode('.', PHP_VERSION); |
||
| 583 | $this->client->setSSLVersion(min(5 + $version[1], 7)); |
||
| 584 | } |
||
| 585 | |||
| 586 | $this->$method(); |
||
| 587 | } |
||
| 588 | */ |
||
| 589 | |||
| 590 | // *** charset tests *** |
||
| 591 | |||
| 592 | public function testAcceptCharset() |
||
| 593 | { |
||
| 594 | if (version_compare(PHP_VERSION, '5.6.0', '<')) |
||
| 595 | { |
||
| 596 | $this->markTestSkipped('Cannot test accept-charset on php < 5.6'); |
||
| 597 | } |
||
| 598 | if (!function_exists('mb_list_encodings')) |
||
| 599 | { |
||
| 600 | $this->markTestSkipped('mbstring missing: cannot test accept-charset'); |
||
| 601 | } |
||
| 602 | |||
| 603 | $r = new \PhpXmlRpc\Request('examples.stringecho', array(new \PhpXmlRpc\Value('€'))); // chr(164) |
||
| 604 | |||
| 605 | \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8'; |
||
| 606 | |||
| 607 | $this->addQueryParams(array('RESPONSE_ENCODING' => 'auto')); |
||
| 608 | $this->client->accepted_charset_encodings = array( |
||
| 609 | 'utf-1234;q=0.1', |
||
| 610 | 'windows-1252;q=0.8' |
||
| 611 | ); |
||
| 612 | $v = $this->send($r, 0, true); |
||
| 613 | $h = $v->httpResponse(); |
||
| 614 | $this->assertEquals('text/xml; charset=Windows-1252', $h['headers']['content-type']); |
||
| 615 | if ($v) { |
||
| 616 | $this->assertEquals('€', $v->value()->scalarval()); |
||
| 617 | } |
||
| 618 | } |
||
| 619 | |||
| 620 | /// @todo a better organization of tests could be to move the 4 tests below and all charset-related tests from |
||
| 621 | /// class ServerTest to a dedicated class - and make sure we iterate over each of those with different |
||
| 622 | /// proxy/auth/compression/etc... settings |
||
| 623 | |||
| 624 | /** |
||
| 625 | * @dataProvider getSingleHttpTestMethods |
||
| 626 | * @param string $method |
||
| 627 | */ |
||
| 628 | public function testUTF8Responses($method) |
||
| 629 | { |
||
| 630 | $this->addQueryParams(array('RESPONSE_ENCODING' => 'UTF-8')); |
||
| 631 | |||
| 632 | $this->$method(); |
||
| 633 | } |
||
| 634 | |||
| 635 | /** |
||
| 636 | * @dataProvider getSingleHttpTestMethods |
||
| 637 | * @param string $method |
||
| 638 | */ |
||
| 639 | public function testUTF8Requests($method) |
||
| 644 | } |
||
| 645 | |||
| 646 | /** |
||
| 647 | * @dataProvider getSingleHttpTestMethods |
||
| 648 | * @param string $method |
||
| 649 | */ |
||
| 650 | public function testISOResponses($method) |
||
| 651 | { |
||
| 652 | $this->addQueryParams(array('RESPONSE_ENCODING' => 'ISO-8859-1')); |
||
| 653 | |||
| 654 | $this->$method(); |
||
| 655 | } |
||
| 656 | |||
| 657 | /** |
||
| 658 | * @dataProvider getSingleHttpTestMethods |
||
| 659 | * @param string $method |
||
| 660 | */ |
||
| 661 | public function testISORequests($method) |
||
| 666 | } |
||
| 667 | } |
||
| 668 |