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