Passed
Push — master ( ea57c6...209714 )
by Gaetano
07:44
created

HTTPTest::testHttpsProxyCurl()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 18
nc 8
nop 1
dl 0
loc 32
rs 9.0444
c 2
b 0
f 0
1
<?php
2
3
include_once __DIR__ . '/08ServerTest.php';
4
5
/**
6
 * Tests which stress http features of the library.
7
 * Each of these tests iterates over (almost) all the 'Server' tests.
8
 *
9
 * @todo refactor:
10
 *       - pick a smaller subset of 'base tests' to iterate over, for every http feature
11
 *       - test more exhaustive combinations of compression/auth/ssl/charset/curl-or-socket/proxy/etc.. features
12
 *       - move SSLVERSION from being passed in as an arg to being something we exhaustively test using a dataprovider
13
 */
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;
0 ignored issues
show
Bug Best Practice introduced by
The property $keepalive is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setUseCurl() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

92
        /** @scrutinizer ignore-deprecated */ $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_ALWAYS);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
93
        $this->client->setCurlOptions(array(CURLOPT_FOLLOWLOCATION => true, CURLOPT_POSTREDIR => 3));
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setCurlOptions() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

93
        /** @scrutinizer ignore-deprecated */ $this->client->setCurlOptions(array(CURLOPT_FOLLOWLOCATION => true, CURLOPT_POSTREDIR => 3));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The property $keepalive is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The property $keepalive is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
131
        $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_ALWAYS);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setUseCurl() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

131
        /** @scrutinizer ignore-deprecated */ $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_ALWAYS);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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']));
0 ignored issues
show
Unused Code introduced by
The assignment to $r is dead and can be removed.
Loading history...
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');
0 ignored issues
show
Bug Best Practice introduced by
The property $accepted_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
235
        $this->client->request_compression = 'deflate';
0 ignored issues
show
Bug Best Practice introduced by
The property $request_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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');
0 ignored issues
show
Bug Best Practice introduced by
The property $accepted_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
252
        $this->client->request_compression = 'gzip';
0 ignored issues
show
Bug Best Practice introduced by
The property $request_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The property $keepalive is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
270
        $this->client->accepted_compression = array('gzip');
0 ignored issues
show
Bug Best Practice introduced by
The property $accepted_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
271
        $this->client->request_compression = 'gzip';
0 ignored issues
show
Bug Best Practice introduced by
The property $request_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The property $keepalive is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
289
        $this->client->accepted_compression = array('deflate');
0 ignored issues
show
Bug Best Practice introduced by
The property $accepted_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
290
        $this->client->request_compression = 'deflate';
0 ignored issues
show
Bug Best Practice introduced by
The property $request_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyPeer() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

318
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
319
        $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyHost() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

319
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
320
        $this->client->setSSLVersion($this->args['SSLVERSION']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVersion() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

320
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVersion($this->args['SSLVERSION']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyPeer() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

368
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
369
        $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyHost() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

369
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
370
        $this->client->setSSLVersion($this->args['SSLVERSION']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVersion() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

370
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVersion($this->args['SSLVERSION']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
371
        $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_NEVER);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setUseCurl() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

371
        /** @scrutinizer ignore-deprecated */ $this->client->setUseCurl(\PhpXmlRpc\Client::USE_CURL_NEVER);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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) {
0 ignored issues
show
Bug introduced by
The method scalarVal() does not exist on PhpXmlRpc\Response. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

408
        if ($r->/** @scrutinizer ignore-call */ scalarVal() != true) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
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']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyPeer() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

447
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
448
        $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyHost() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

448
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
449
        $this->client->setSSLVersion($this->args['SSLVERSION']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVersion() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

449
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVersion($this->args['SSLVERSION']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The property $keepalive is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyPeer() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

524
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
525
        $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVerifyHost() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

525
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
526
        $this->client->setSSLVersion($this->args['SSLVERSION']);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVersion() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

526
        /** @scrutinizer ignore-deprecated */ $this->client->setSSLVersion($this->args['SSLVERSION']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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));
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Client::setSSLVersion() has been deprecated: use setOption ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

531
            /** @scrutinizer ignore-deprecated */ $this->client->setSSLVersion(min(4 + $version[1], 7));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
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(
0 ignored issues
show
Bug Best Practice introduced by
The property $accepted_charset_encodings is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
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)
640
    {
641
        $this->client->request_charset_encoding = 'UTF-8';
0 ignored issues
show
Bug Best Practice introduced by
The property $request_charset_encoding is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
642
643
        $this->$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)
662
    {
663
        $this->client->request_charset_encoding = 'ISO-8859-1';
0 ignored issues
show
Bug Best Practice introduced by
The property $request_charset_encoding is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
664
665
        $this->$method();
666
    }
667
}
668