Merge "auth: Follow up on e907d4328dc3e"
[lhc/web/wiklou.git] / tests / phpunit / includes / http / HttpTest.php
1 <?php
2
3 use GuzzleHttp\Handler\MockHandler;
4 use GuzzleHttp\HandlerStack;
5 use GuzzleHttp\Psr7\Response;
6
7 /**
8 * @group Http
9 * @group small
10 */
11 class HttpTest extends MediaWikiTestCase {
12 /**
13 * @dataProvider cookieDomains
14 * @covers Cookie::validateCookieDomain
15 */
16 public function testValidateCookieDomain( $expected, $domain, $origin = null ) {
17 if ( $origin ) {
18 $ok = Cookie::validateCookieDomain( $domain, $origin );
19 $msg = "$domain against origin $origin";
20 } else {
21 $ok = Cookie::validateCookieDomain( $domain );
22 $msg = "$domain";
23 }
24 $this->assertEquals( $expected, $ok, $msg );
25 }
26
27 public static function cookieDomains() {
28 return [
29 [ false, "org" ],
30 [ false, ".org" ],
31 [ true, "wikipedia.org" ],
32 [ true, ".wikipedia.org" ],
33 [ false, "co.uk" ],
34 [ false, ".co.uk" ],
35 [ false, "gov.uk" ],
36 [ false, ".gov.uk" ],
37 [ true, "supermarket.uk" ],
38 [ false, "uk" ],
39 [ false, ".uk" ],
40 [ false, "127.0.0." ],
41 [ false, "127." ],
42 [ false, "127.0.0.1." ],
43 [ true, "127.0.0.1" ],
44 [ false, "333.0.0.1" ],
45 [ true, "example.com" ],
46 [ false, "example.com." ],
47 [ true, ".example.com" ],
48
49 [ true, ".example.com", "www.example.com" ],
50 [ false, "example.com", "www.example.com" ],
51 [ true, "127.0.0.1", "127.0.0.1" ],
52 [ false, "127.0.0.1", "localhost" ],
53 ];
54 }
55
56 /**
57 * Test Http::isValidURI()
58 * T29854 : Http::isValidURI is too lax
59 * @dataProvider provideURI
60 * @covers Http::isValidURI
61 */
62 public function testIsValidUri( $expect, $URI, $message = '' ) {
63 $this->assertEquals(
64 $expect,
65 (bool)Http::isValidURI( $URI ),
66 $message
67 );
68 }
69
70 /**
71 * @covers Http::getProxy
72 */
73 public function testGetProxy() {
74 $this->setMwGlobals( 'wgHTTPProxy', false );
75 $this->assertEquals(
76 '',
77 Http::getProxy(),
78 'default setting'
79 );
80
81 $this->setMwGlobals( 'wgHTTPProxy', 'proxy.domain.tld' );
82 $this->assertEquals(
83 'proxy.domain.tld',
84 Http::getProxy()
85 );
86 }
87
88 /**
89 * Feeds URI to test a long regular expression in Http::isValidURI
90 */
91 public static function provideURI() {
92 /** Format: 'boolean expectation', 'URI to test', 'Optional message' */
93 return [
94 [ false, '¿non sens before!! http://a', 'Allow anything before URI' ],
95
96 # (http|https) - only two schemes allowed
97 [ true, 'http://www.example.org/' ],
98 [ true, 'https://www.example.org/' ],
99 [ true, 'http://www.example.org', 'URI without directory' ],
100 [ true, 'http://a', 'Short name' ],
101 [ true, 'http://étoile', 'Allow UTF-8 in hostname' ], # 'étoile' is french for 'star'
102 [ false, '\\host\directory', 'CIFS share' ],
103 [ false, 'gopher://host/dir', 'Reject gopher scheme' ],
104 [ false, 'telnet://host', 'Reject telnet scheme' ],
105
106 # :\/\/ - double slashes
107 [ false, 'http//example.org', 'Reject missing colon in protocol' ],
108 [ false, 'http:/example.org', 'Reject missing slash in protocol' ],
109 [ false, 'http:example.org', 'Must have two slashes' ],
110 # Following fail since hostname can be made of anything
111 [ false, 'http:///example.org', 'Must have exactly two slashes, not three' ],
112
113 # (\w+:{0,1}\w*@)? - optional user:pass
114 [ true, 'http://user@host', 'Username provided' ],
115 [ true, 'http://user:@host', 'Username provided, no password' ],
116 [ true, 'http://user:pass@host', 'Username and password provided' ],
117
118 # (\S+) - host part is made of anything not whitespaces
119 // commented these out in order to remove @group Broken
120 // @todo are these valid tests? if so, fix Http::isValidURI so it can handle them
121 // [ false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ],
122 // [ false, 'http://exam:ple.org/', 'hostname can not use colons!' ],
123
124 # (:[0-9]+)? - port number
125 [ true, 'http://example.org:80/' ],
126 [ true, 'https://example.org:80/' ],
127 [ true, 'http://example.org:443/' ],
128 [ true, 'https://example.org:443/' ],
129
130 # Part after the hostname is / or / with something else
131 [ true, 'http://example/#' ],
132 [ true, 'http://example/!' ],
133 [ true, 'http://example/:' ],
134 [ true, 'http://example/.' ],
135 [ true, 'http://example/?' ],
136 [ true, 'http://example/+' ],
137 [ true, 'http://example/=' ],
138 [ true, 'http://example/&' ],
139 [ true, 'http://example/%' ],
140 [ true, 'http://example/@' ],
141 [ true, 'http://example/-' ],
142 [ true, 'http://example//' ],
143 [ true, 'http://example/&' ],
144
145 # Fragment
146 [ true, 'http://exam#ple.org', ], # This one is valid, really!
147 [ true, 'http://example.org:80#anchor' ],
148 [ true, 'http://example.org/?id#anchor' ],
149 [ true, 'http://example.org/?#anchor' ],
150
151 [ false, 'http://a ¿non !!sens after', 'Allow anything after URI' ],
152 ];
153 }
154
155 public static function provideRelativeRedirects() {
156 return [
157 [
158 'location' => [ 'http://newsite/file.ext', '/newfile.ext' ],
159 'final' => 'http://newsite/newfile.ext',
160 'Relative file path Location: interpreted as full URL'
161 ],
162 [
163 'location' => [ 'https://oldsite/file.ext' ],
164 'final' => 'https://oldsite/file.ext',
165 'Location to the HTTPS version of the site'
166 ],
167 [
168 'location' => [
169 '/anotherfile.ext',
170 'http://anotherfile/hoster.ext',
171 'https://anotherfile/hoster.ext'
172 ],
173 'final' => 'https://anotherfile/hoster.ext',
174 'Relative file path Location: should keep the latest host and scheme!'
175 ],
176 [
177 'location' => [ '/anotherfile.ext' ],
178 'final' => 'http://oldsite/anotherfile.ext',
179 'Relative Location without domain '
180 ],
181 [
182 'location' => null,
183 'final' => 'http://oldsite/file.ext',
184 'No Location (no redirect) '
185 ],
186 ];
187 }
188
189 /**
190 * Warning:
191 *
192 * These tests are for code that makes use of an artifact of how CURL
193 * handles header reporting on redirect pages, and will need to be
194 * rewritten when T31232 is taken care of (high-level handling of HTTP redirects).
195 *
196 * @dataProvider provideRelativeRedirects
197 * @covers MWHttpRequest::getFinalUrl
198 */
199 public function testRelativeRedirections( $location, $final, $message = null ) {
200 $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext', [], __METHOD__ );
201 // Forge a Location header
202 $h->setRespHeaders( 'location', $location );
203 // Verify it correctly fixes the Location
204 $this->assertEquals( $final, $h->getFinalUrl(), $message );
205 }
206
207 /**
208 * Constant values are from PHP 5.3.28 using cURL 7.24.0
209 * @see https://secure.php.net/manual/en/curl.constants.php
210 *
211 * All constant values are present so that developers don’t need to remember
212 * to add them if added at a later date. The commented out constants were
213 * not found anywhere in the MediaWiki core code.
214 *
215 * Commented out constants that were not available in:
216 * HipHop VM 3.3.0 (rel)
217 * Compiler: heads/master-0-g08810d920dfff59e0774cf2d651f92f13a637175
218 * Repo schema: 3214fc2c684a4520485f715ee45f33f2182324b1
219 * Extension API: 20140829
220 *
221 * Commented out constants that were removed in PHP 5.6.0
222 */
223 public function provideCurlConstants() {
224 return [
225 [ 'CURLAUTH_ANY' ],
226 [ 'CURLAUTH_ANYSAFE' ],
227 [ 'CURLAUTH_BASIC' ],
228 [ 'CURLAUTH_DIGEST' ],
229 [ 'CURLAUTH_GSSNEGOTIATE' ],
230 [ 'CURLAUTH_NTLM' ],
231 // [ 'CURLCLOSEPOLICY_CALLBACK' ], // removed in PHP 5.6.0
232 // [ 'CURLCLOSEPOLICY_LEAST_RECENTLY_USED' ], // removed in PHP 5.6.0
233 // [ 'CURLCLOSEPOLICY_LEAST_TRAFFIC' ], // removed in PHP 5.6.0
234 // [ 'CURLCLOSEPOLICY_OLDEST' ], // removed in PHP 5.6.0
235 // [ 'CURLCLOSEPOLICY_SLOWEST' ], // removed in PHP 5.6.0
236 [ 'CURLE_ABORTED_BY_CALLBACK' ],
237 [ 'CURLE_BAD_CALLING_ORDER' ],
238 [ 'CURLE_BAD_CONTENT_ENCODING' ],
239 [ 'CURLE_BAD_FUNCTION_ARGUMENT' ],
240 [ 'CURLE_BAD_PASSWORD_ENTERED' ],
241 [ 'CURLE_COULDNT_CONNECT' ],
242 [ 'CURLE_COULDNT_RESOLVE_HOST' ],
243 [ 'CURLE_COULDNT_RESOLVE_PROXY' ],
244 [ 'CURLE_FAILED_INIT' ],
245 [ 'CURLE_FILESIZE_EXCEEDED' ],
246 [ 'CURLE_FILE_COULDNT_READ_FILE' ],
247 [ 'CURLE_FTP_ACCESS_DENIED' ],
248 [ 'CURLE_FTP_BAD_DOWNLOAD_RESUME' ],
249 [ 'CURLE_FTP_CANT_GET_HOST' ],
250 [ 'CURLE_FTP_CANT_RECONNECT' ],
251 [ 'CURLE_FTP_COULDNT_GET_SIZE' ],
252 [ 'CURLE_FTP_COULDNT_RETR_FILE' ],
253 [ 'CURLE_FTP_COULDNT_SET_ASCII' ],
254 [ 'CURLE_FTP_COULDNT_SET_BINARY' ],
255 [ 'CURLE_FTP_COULDNT_STOR_FILE' ],
256 [ 'CURLE_FTP_COULDNT_USE_REST' ],
257 [ 'CURLE_FTP_PORT_FAILED' ],
258 [ 'CURLE_FTP_QUOTE_ERROR' ],
259 [ 'CURLE_FTP_SSL_FAILED' ],
260 [ 'CURLE_FTP_USER_PASSWORD_INCORRECT' ],
261 [ 'CURLE_FTP_WEIRD_227_FORMAT' ],
262 [ 'CURLE_FTP_WEIRD_PASS_REPLY' ],
263 [ 'CURLE_FTP_WEIRD_PASV_REPLY' ],
264 [ 'CURLE_FTP_WEIRD_SERVER_REPLY' ],
265 [ 'CURLE_FTP_WEIRD_USER_REPLY' ],
266 [ 'CURLE_FTP_WRITE_ERROR' ],
267 [ 'CURLE_FUNCTION_NOT_FOUND' ],
268 [ 'CURLE_GOT_NOTHING' ],
269 [ 'CURLE_HTTP_NOT_FOUND' ],
270 [ 'CURLE_HTTP_PORT_FAILED' ],
271 [ 'CURLE_HTTP_POST_ERROR' ],
272 [ 'CURLE_HTTP_RANGE_ERROR' ],
273 [ 'CURLE_LDAP_CANNOT_BIND' ],
274 [ 'CURLE_LDAP_INVALID_URL' ],
275 [ 'CURLE_LDAP_SEARCH_FAILED' ],
276 [ 'CURLE_LIBRARY_NOT_FOUND' ],
277 [ 'CURLE_MALFORMAT_USER' ],
278 [ 'CURLE_OBSOLETE' ],
279 [ 'CURLE_OK' ],
280 [ 'CURLE_OPERATION_TIMEOUTED' ],
281 [ 'CURLE_OUT_OF_MEMORY' ],
282 [ 'CURLE_PARTIAL_FILE' ],
283 [ 'CURLE_READ_ERROR' ],
284 [ 'CURLE_RECV_ERROR' ],
285 [ 'CURLE_SEND_ERROR' ],
286 [ 'CURLE_SHARE_IN_USE' ],
287 // [ 'CURLE_SSH' ], // not present in HHVM 3.3.0-dev
288 [ 'CURLE_SSL_CACERT' ],
289 [ 'CURLE_SSL_CERTPROBLEM' ],
290 [ 'CURLE_SSL_CIPHER' ],
291 [ 'CURLE_SSL_CONNECT_ERROR' ],
292 [ 'CURLE_SSL_ENGINE_NOTFOUND' ],
293 [ 'CURLE_SSL_ENGINE_SETFAILED' ],
294 [ 'CURLE_SSL_PEER_CERTIFICATE' ],
295 [ 'CURLE_TELNET_OPTION_SYNTAX' ],
296 [ 'CURLE_TOO_MANY_REDIRECTS' ],
297 [ 'CURLE_UNKNOWN_TELNET_OPTION' ],
298 [ 'CURLE_UNSUPPORTED_PROTOCOL' ],
299 [ 'CURLE_URL_MALFORMAT' ],
300 [ 'CURLE_URL_MALFORMAT_USER' ],
301 [ 'CURLE_WRITE_ERROR' ],
302 [ 'CURLFTPAUTH_DEFAULT' ],
303 [ 'CURLFTPAUTH_SSL' ],
304 [ 'CURLFTPAUTH_TLS' ],
305 // [ 'CURLFTPMETHOD_MULTICWD' ], // not present in HHVM 3.3.0-dev
306 // [ 'CURLFTPMETHOD_NOCWD' ], // not present in HHVM 3.3.0-dev
307 // [ 'CURLFTPMETHOD_SINGLECWD' ], // not present in HHVM 3.3.0-dev
308 [ 'CURLFTPSSL_ALL' ],
309 [ 'CURLFTPSSL_CONTROL' ],
310 [ 'CURLFTPSSL_NONE' ],
311 [ 'CURLFTPSSL_TRY' ],
312 // [ 'CURLINFO_CERTINFO' ], // not present in HHVM 3.3.0-dev
313 [ 'CURLINFO_CONNECT_TIME' ],
314 [ 'CURLINFO_CONTENT_LENGTH_DOWNLOAD' ],
315 [ 'CURLINFO_CONTENT_LENGTH_UPLOAD' ],
316 [ 'CURLINFO_CONTENT_TYPE' ],
317 [ 'CURLINFO_EFFECTIVE_URL' ],
318 [ 'CURLINFO_FILETIME' ],
319 [ 'CURLINFO_HEADER_OUT' ],
320 [ 'CURLINFO_HEADER_SIZE' ],
321 [ 'CURLINFO_HTTP_CODE' ],
322 [ 'CURLINFO_NAMELOOKUP_TIME' ],
323 [ 'CURLINFO_PRETRANSFER_TIME' ],
324 [ 'CURLINFO_PRIVATE' ],
325 [ 'CURLINFO_REDIRECT_COUNT' ],
326 [ 'CURLINFO_REDIRECT_TIME' ],
327 // [ 'CURLINFO_REDIRECT_URL' ], // not present in HHVM 3.3.0-dev
328 [ 'CURLINFO_REQUEST_SIZE' ],
329 [ 'CURLINFO_SIZE_DOWNLOAD' ],
330 [ 'CURLINFO_SIZE_UPLOAD' ],
331 [ 'CURLINFO_SPEED_DOWNLOAD' ],
332 [ 'CURLINFO_SPEED_UPLOAD' ],
333 [ 'CURLINFO_SSL_VERIFYRESULT' ],
334 [ 'CURLINFO_STARTTRANSFER_TIME' ],
335 [ 'CURLINFO_TOTAL_TIME' ],
336 [ 'CURLMSG_DONE' ],
337 [ 'CURLM_BAD_EASY_HANDLE' ],
338 [ 'CURLM_BAD_HANDLE' ],
339 [ 'CURLM_CALL_MULTI_PERFORM' ],
340 [ 'CURLM_INTERNAL_ERROR' ],
341 [ 'CURLM_OK' ],
342 [ 'CURLM_OUT_OF_MEMORY' ],
343 [ 'CURLOPT_AUTOREFERER' ],
344 [ 'CURLOPT_BINARYTRANSFER' ],
345 [ 'CURLOPT_BUFFERSIZE' ],
346 [ 'CURLOPT_CAINFO' ],
347 [ 'CURLOPT_CAPATH' ],
348 // [ 'CURLOPT_CERTINFO' ], // not present in HHVM 3.3.0-dev
349 // [ 'CURLOPT_CLOSEPOLICY' ], // removed in PHP 5.6.0
350 [ 'CURLOPT_CONNECTTIMEOUT' ],
351 [ 'CURLOPT_CONNECTTIMEOUT_MS' ],
352 [ 'CURLOPT_COOKIE' ],
353 [ 'CURLOPT_COOKIEFILE' ],
354 [ 'CURLOPT_COOKIEJAR' ],
355 [ 'CURLOPT_COOKIESESSION' ],
356 [ 'CURLOPT_CRLF' ],
357 [ 'CURLOPT_CUSTOMREQUEST' ],
358 [ 'CURLOPT_DNS_CACHE_TIMEOUT' ],
359 [ 'CURLOPT_DNS_USE_GLOBAL_CACHE' ],
360 [ 'CURLOPT_EGDSOCKET' ],
361 [ 'CURLOPT_ENCODING' ],
362 [ 'CURLOPT_FAILONERROR' ],
363 [ 'CURLOPT_FILE' ],
364 [ 'CURLOPT_FILETIME' ],
365 [ 'CURLOPT_FOLLOWLOCATION' ],
366 [ 'CURLOPT_FORBID_REUSE' ],
367 [ 'CURLOPT_FRESH_CONNECT' ],
368 [ 'CURLOPT_FTPAPPEND' ],
369 [ 'CURLOPT_FTPLISTONLY' ],
370 [ 'CURLOPT_FTPPORT' ],
371 [ 'CURLOPT_FTPSSLAUTH' ],
372 [ 'CURLOPT_FTP_CREATE_MISSING_DIRS' ],
373 // [ 'CURLOPT_FTP_FILEMETHOD' ], // not present in HHVM 3.3.0-dev
374 // [ 'CURLOPT_FTP_SKIP_PASV_IP' ], // not present in HHVM 3.3.0-dev
375 [ 'CURLOPT_FTP_SSL' ],
376 [ 'CURLOPT_FTP_USE_EPRT' ],
377 [ 'CURLOPT_FTP_USE_EPSV' ],
378 [ 'CURLOPT_HEADER' ],
379 [ 'CURLOPT_HEADERFUNCTION' ],
380 [ 'CURLOPT_HTTP200ALIASES' ],
381 [ 'CURLOPT_HTTPAUTH' ],
382 [ 'CURLOPT_HTTPGET' ],
383 [ 'CURLOPT_HTTPHEADER' ],
384 [ 'CURLOPT_HTTPPROXYTUNNEL' ],
385 [ 'CURLOPT_HTTP_VERSION' ],
386 [ 'CURLOPT_INFILE' ],
387 [ 'CURLOPT_INFILESIZE' ],
388 [ 'CURLOPT_INTERFACE' ],
389 [ 'CURLOPT_IPRESOLVE' ],
390 // [ 'CURLOPT_KEYPASSWD' ], // not present in HHVM 3.3.0-dev
391 [ 'CURLOPT_KRB4LEVEL' ],
392 [ 'CURLOPT_LOW_SPEED_LIMIT' ],
393 [ 'CURLOPT_LOW_SPEED_TIME' ],
394 [ 'CURLOPT_MAXCONNECTS' ],
395 [ 'CURLOPT_MAXREDIRS' ],
396 // [ 'CURLOPT_MAX_RECV_SPEED_LARGE' ], // not present in HHVM 3.3.0-dev
397 // [ 'CURLOPT_MAX_SEND_SPEED_LARGE' ], // not present in HHVM 3.3.0-dev
398 [ 'CURLOPT_NETRC' ],
399 [ 'CURLOPT_NOBODY' ],
400 [ 'CURLOPT_NOPROGRESS' ],
401 [ 'CURLOPT_NOSIGNAL' ],
402 [ 'CURLOPT_PORT' ],
403 [ 'CURLOPT_POST' ],
404 [ 'CURLOPT_POSTFIELDS' ],
405 [ 'CURLOPT_POSTQUOTE' ],
406 [ 'CURLOPT_POSTREDIR' ],
407 [ 'CURLOPT_PRIVATE' ],
408 [ 'CURLOPT_PROGRESSFUNCTION' ],
409 // [ 'CURLOPT_PROTOCOLS' ], // not present in HHVM 3.3.0-dev
410 [ 'CURLOPT_PROXY' ],
411 [ 'CURLOPT_PROXYAUTH' ],
412 [ 'CURLOPT_PROXYPORT' ],
413 [ 'CURLOPT_PROXYTYPE' ],
414 [ 'CURLOPT_PROXYUSERPWD' ],
415 [ 'CURLOPT_PUT' ],
416 [ 'CURLOPT_QUOTE' ],
417 [ 'CURLOPT_RANDOM_FILE' ],
418 [ 'CURLOPT_RANGE' ],
419 [ 'CURLOPT_READDATA' ],
420 [ 'CURLOPT_READFUNCTION' ],
421 // [ 'CURLOPT_REDIR_PROTOCOLS' ], // not present in HHVM 3.3.0-dev
422 [ 'CURLOPT_REFERER' ],
423 [ 'CURLOPT_RESUME_FROM' ],
424 [ 'CURLOPT_RETURNTRANSFER' ],
425 // [ 'CURLOPT_SSH_AUTH_TYPES' ], // not present in HHVM 3.3.0-dev
426 // [ 'CURLOPT_SSH_HOST_PUBLIC_KEY_MD5' ], // not present in HHVM 3.3.0-dev
427 // [ 'CURLOPT_SSH_PRIVATE_KEYFILE' ], // not present in HHVM 3.3.0-dev
428 // [ 'CURLOPT_SSH_PUBLIC_KEYFILE' ], // not present in HHVM 3.3.0-dev
429 [ 'CURLOPT_SSLCERT' ],
430 [ 'CURLOPT_SSLCERTPASSWD' ],
431 [ 'CURLOPT_SSLCERTTYPE' ],
432 [ 'CURLOPT_SSLENGINE' ],
433 [ 'CURLOPT_SSLENGINE_DEFAULT' ],
434 [ 'CURLOPT_SSLKEY' ],
435 [ 'CURLOPT_SSLKEYPASSWD' ],
436 [ 'CURLOPT_SSLKEYTYPE' ],
437 [ 'CURLOPT_SSLVERSION' ],
438 [ 'CURLOPT_SSL_CIPHER_LIST' ],
439 [ 'CURLOPT_SSL_VERIFYHOST' ],
440 [ 'CURLOPT_SSL_VERIFYPEER' ],
441 [ 'CURLOPT_STDERR' ],
442 [ 'CURLOPT_TCP_NODELAY' ],
443 [ 'CURLOPT_TIMECONDITION' ],
444 [ 'CURLOPT_TIMEOUT' ],
445 [ 'CURLOPT_TIMEOUT_MS' ],
446 [ 'CURLOPT_TIMEVALUE' ],
447 [ 'CURLOPT_TRANSFERTEXT' ],
448 [ 'CURLOPT_UNRESTRICTED_AUTH' ],
449 [ 'CURLOPT_UPLOAD' ],
450 [ 'CURLOPT_URL' ],
451 [ 'CURLOPT_USERAGENT' ],
452 [ 'CURLOPT_USERPWD' ],
453 [ 'CURLOPT_VERBOSE' ],
454 [ 'CURLOPT_WRITEFUNCTION' ],
455 [ 'CURLOPT_WRITEHEADER' ],
456 // [ 'CURLPROTO_ALL' ], // not present in HHVM 3.3.0-dev
457 // [ 'CURLPROTO_DICT' ], // not present in HHVM 3.3.0-dev
458 // [ 'CURLPROTO_FILE' ], // not present in HHVM 3.3.0-dev
459 // [ 'CURLPROTO_FTP' ], // not present in HHVM 3.3.0-dev
460 // [ 'CURLPROTO_FTPS' ], // not present in HHVM 3.3.0-dev
461 // [ 'CURLPROTO_HTTP' ], // not present in HHVM 3.3.0-dev
462 // [ 'CURLPROTO_HTTPS' ], // not present in HHVM 3.3.0-dev
463 // [ 'CURLPROTO_LDAP' ], // not present in HHVM 3.3.0-dev
464 // [ 'CURLPROTO_LDAPS' ], // not present in HHVM 3.3.0-dev
465 // [ 'CURLPROTO_SCP' ], // not present in HHVM 3.3.0-dev
466 // [ 'CURLPROTO_SFTP' ], // not present in HHVM 3.3.0-dev
467 // [ 'CURLPROTO_TELNET' ], // not present in HHVM 3.3.0-dev
468 // [ 'CURLPROTO_TFTP' ], // not present in HHVM 3.3.0-dev
469 [ 'CURLPROXY_HTTP' ],
470 // [ 'CURLPROXY_SOCKS4' ], // not present in HHVM 3.3.0-dev
471 [ 'CURLPROXY_SOCKS5' ],
472 // [ 'CURLSSH_AUTH_DEFAULT' ], // not present in HHVM 3.3.0-dev
473 // [ 'CURLSSH_AUTH_HOST' ], // not present in HHVM 3.3.0-dev
474 // [ 'CURLSSH_AUTH_KEYBOARD' ], // not present in HHVM 3.3.0-dev
475 // [ 'CURLSSH_AUTH_NONE' ], // not present in HHVM 3.3.0-dev
476 // [ 'CURLSSH_AUTH_PASSWORD' ], // not present in HHVM 3.3.0-dev
477 // [ 'CURLSSH_AUTH_PUBLICKEY' ], // not present in HHVM 3.3.0-dev
478 [ 'CURLVERSION_NOW' ],
479 [ 'CURL_HTTP_VERSION_1_0' ],
480 [ 'CURL_HTTP_VERSION_1_1' ],
481 [ 'CURL_HTTP_VERSION_NONE' ],
482 [ 'CURL_IPRESOLVE_V4' ],
483 [ 'CURL_IPRESOLVE_V6' ],
484 [ 'CURL_IPRESOLVE_WHATEVER' ],
485 [ 'CURL_NETRC_IGNORED' ],
486 [ 'CURL_NETRC_OPTIONAL' ],
487 [ 'CURL_NETRC_REQUIRED' ],
488 [ 'CURL_TIMECOND_IFMODSINCE' ],
489 [ 'CURL_TIMECOND_IFUNMODSINCE' ],
490 [ 'CURL_TIMECOND_LASTMOD' ],
491 [ 'CURL_VERSION_IPV6' ],
492 [ 'CURL_VERSION_KERBEROS4' ],
493 [ 'CURL_VERSION_LIBZ' ],
494 [ 'CURL_VERSION_SSL' ],
495 ];
496 }
497
498 /**
499 * Added this test based on an issue experienced with HHVM 3.3.0-dev
500 * where it did not define a cURL constant. T72570
501 *
502 * @dataProvider provideCurlConstants
503 * @coversNothing
504 */
505 public function testCurlConstants( $value ) {
506 $this->checkPHPExtension( 'curl' );
507
508 $this->assertTrue( defined( $value ), $value . ' not defined' );
509 }
510
511 /**
512 * No actual request is made herein
513 */
514 public function testGuzzleHttpRequest() {
515 $handler = HandlerStack::create( new MockHandler( [ new Response( 200 ) ] ) );
516 $r = new GuzzleHttpRequest( 'http://www.example.text', [ 'handler' => $handler ] );
517 $r->execute();
518 $this->assertEquals( 200, $r->getStatus() );
519
520 // @TODO: add failure tests (404s and failure to connect)
521 }
522 }
523
524 /**
525 * Class to let us overwrite MWHttpRequest respHeaders variable
526 */
527 class MWHttpRequestTester extends MWHttpRequest {
528 // function derived from the MWHttpRequest factory function but
529 // returns appropriate tester class here
530 public static function factory( $url, array $options = null, $caller = __METHOD__ ) {
531 if ( !Http::$httpEngine ) {
532 Http::$httpEngine = 'guzzle';
533 } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
534 throw new DomainException( __METHOD__ . ': curl (https://secure.php.net/curl) is not ' .
535 'installed, but Http::$httpEngine is set to "curl"' );
536 }
537
538 switch ( Http::$httpEngine ) {
539 case 'guzzle':
540 return new GuzzleHttpRequestTester( $url, $options, $caller );
541 case 'curl':
542 return new CurlHttpRequestTester( $url, $options, $caller );
543 case 'php':
544 if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
545 throw new DomainException( __METHOD__ .
546 ': allow_url_fopen needs to be enabled for pure PHP HTTP requests to work. '
547 . 'If possible, curl should be used instead. See https://secure.php.net/curl.' );
548 }
549
550 return new PhpHttpRequestTester( $url, $options, $caller );
551 default:
552 }
553 }
554 }
555
556 class GuzzleHttpRequestTester extends GuzzleHttpRequest {
557 function setRespHeaders( $name, $value ) {
558 $this->respHeaders[$name] = $value;
559 }
560 }
561
562 class CurlHttpRequestTester extends CurlHttpRequest {
563 function setRespHeaders( $name, $value ) {
564 $this->respHeaders[$name] = $value;
565 }
566 }
567
568 class PhpHttpRequestTester extends PhpHttpRequest {
569 function setRespHeaders( $name, $value ) {
570 $this->respHeaders[$name] = $value;
571 }
572 }