3 class MockCookie
extends Cookie
{
4 public function canServeDomain( $arg ) { return parent
::canServeDomain( $arg ); }
5 public function canServePath( $arg ) { return parent
::canServePath( $arg ); }
6 public function isUnExpired() { return parent
::isUnExpired(); }
12 class HttpTest
extends PHPUnit_Framework_TestCase
{
17 static $has_proxy = false;
18 static $proxy = "http://hulk:8080/";
19 var $test_geturl = array(
20 "http://www.example.com/",
21 "http://pecl.php.net/feeds/pkg_apc.rss",
22 "http://toolserver.org/~jan/poll/dev/main.php?page=wiki_output&id=3",
23 "http://meta.wikimedia.org/w/index.php?title=Interwiki_map&action=raw",
24 "http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:MediaWiki_hooks&format=php",
26 var $test_requesturl = array( "http://en.wikipedia.org/wiki/Special:Export/User:MarkAHershberger" );
28 var $test_posturl = array( "http://www.comp.leeds.ac.uk/cgi-bin/Perl/environment-example" => "review=test" );
31 putenv( "http_proxy" ); /* Remove any proxy env var, so curl doesn't get confused */
32 if ( is_array( self
::$content ) ) {
35 self
::$has_curl = function_exists( 'curl_init' );
36 self
::$has_fopen = wfIniGetBool( 'allow_url_fopen' );
38 if ( !file_exists( "/usr/bin/curl" ) ) {
39 $this->markTestIncomplete( "This test requires the curl binary at /usr/bin/curl. If you have curl, please file a bug on this test, or, better yet, provide a patch." );
42 $content = tempnam( wfTempDir(), "" );
43 $headers = tempnam( wfTempDir(), "" );
44 if ( !$content && !$headers ) {
45 die( "Couldn't create temp file!" );
48 // This probably isn't the best test for a proxy, but it works on my system!
49 system( "curl -0 -o $content -s " . self
::$proxy );
50 $out = file_get_contents( $content );
52 self
::$has_proxy = true;
55 /* Maybe use wget instead of curl here ... just to use a different codebase? */
56 foreach ( $this->test_geturl
as $u ) {
57 system( "curl -0 -s -D $headers '$u' -o $content" );
58 self
::$content["GET $u"] = file_get_contents( $content );
59 self
::$headers["GET $u"] = file_get_contents( $headers );
61 foreach ( $this->test_requesturl
as $u ) {
62 system( "curl -0 -s -X POST -H 'Content-Length: 0' -D $headers '$u' -o $content" );
63 self
::$content["POST $u"] = file_get_contents( $content );
64 self
::$headers["POST $u"] = file_get_contents( $headers );
66 foreach ( $this->test_posturl
as $u => $postData ) {
67 system( "curl -0 -s -X POST -d '$postData' -D $headers '$u' -o $content" );
68 self
::$content["POST $u => $postData"] = file_get_contents( $content );
69 self
::$headers["POST $u => $postData"] = file_get_contents( $headers );
76 function testInstantiation() {
77 Http
::$httpEngine = false;
79 $r = MWHttpRequest
::factory( "http://www.example.com/" );
80 if ( self
::$has_curl ) {
81 $this->assertThat( $r, $this->isInstanceOf( 'CurlHttpRequest' ) );
83 $this->assertThat( $r, $this->isInstanceOf( 'PhpHttpRequest' ) );
87 if ( !self
::$has_fopen ) {
88 $this->setExpectedException( 'MWException' );
90 Http
::$httpEngine = 'php';
91 $r = MWHttpRequest
::factory( "http://www.example.com/" );
92 $this->assertThat( $r, $this->isInstanceOf( 'PhpHttpRequest' ) );
95 if ( !self
::$has_curl ) {
96 $this->setExpectedException( 'MWException' );
98 Http
::$httpEngine = 'curl';
99 $r = MWHttpRequest
::factory( "http://www.example.com/" );
100 if ( self
::$has_curl ) {
101 $this->assertThat( $r, $this->isInstanceOf( 'CurlHttpRequest' ) );
105 function runHTTPFailureChecks() {
106 // Each of the following requests should result in a failure.
109 $start_time = time();
110 $r = Http
::get( "http://www.example.com:1/", $timeout );
112 $this->assertLessThan( $timeout +
2, $end_time - $start_time,
113 "Request took less than {$timeout}s via " . Http
::$httpEngine );
114 $this->assertEquals( $r, false, "false -- what we get on error from Http::get()" );
116 $r = Http
::get( "http://www.example.com/this-file-does-not-exist", $timeout );
117 $this->assertFalse( $r, "False on 404s" );
120 $r = MWHttpRequest
::factory( "http://www.example.com/this-file-does-not-exist" );
122 if ( $r instanceof PhpHttpRequest
&& version_compare( '5.2.10', phpversion(), '>' ) ) {
123 $this->assertRegexp( "/HTTP request failed/", $er->getWikiText() );
125 $this->assertRegexp( "/404 Not Found/", $er->getWikiText() );
129 function testFailureDefault() {
130 Http
::$httpEngine = false;
131 $this->runHTTPFailureChecks();
134 function testFailurePhp() {
135 if ( !self
::$has_fopen ) {
136 $this->markTestIncomplete( "This test requires allow_url_fopen=true." );
139 Http
::$httpEngine = "php";
140 $this->runHTTPFailureChecks();
143 function testFailureCurl() {
144 if ( !self
::$has_curl ) {
145 $this->markTestIncomplete( "This test requires curl." );
148 Http
::$httpEngine = "curl";
149 $this->runHTTPFailureChecks();
152 /* ./phase3/includes/Import.php:1108: $data = Http::request( $method, $url ); */
153 /* ./includes/Import.php:1124: $link = Title::newFromText( "$interwiki:Special:Export/$page" ); */
154 /* ./includes/Import.php:1134: return ImportStreamSource::newFromURL( $url, "POST" ); */
155 function runHTTPRequests( $proxy = null ) {
159 $opt['proxy'] = $proxy;
160 } elseif ( $proxy === false ) {
161 $opt['noProxy'] = true;
164 /* no postData here because the only request I could find in code so far didn't have any */
165 foreach ( $this->test_requesturl
as $u ) {
166 $r = Http
::request( "POST", $u, $opt );
167 $this->assertEquals( self
::$content["POST $u"], "$r", "POST $u with " . Http
::$httpEngine );
171 function testRequestDefault() {
172 Http
::$httpEngine = false;
173 $this->runHTTPRequests();
176 function testRequestPhp() {
177 if ( !self
::$has_fopen ) {
178 $this->markTestIncomplete( "This test requires allow_url_fopen=true." );
181 Http
::$httpEngine = "php";
182 $this->runHTTPRequests();
185 function testRequestCurl() {
186 if ( !self
::$has_curl ) {
187 $this->markTestIncomplete( "This test requires curl." );
190 Http
::$httpEngine = "curl";
191 $this->runHTTPRequests();
194 function runHTTPGets( $proxy = null ) {
198 $opt['proxy'] = $proxy;
199 } elseif ( $proxy === false ) {
200 $opt['noProxy'] = true;
203 foreach ( $this->test_geturl
as $u ) {
204 $r = Http
::get( $u, 30, $opt ); /* timeout of 30s */
205 $this->assertEquals( self
::$content["GET $u"], "$r", "Get $u with " . Http
::$httpEngine );
209 function testGetDefault() {
210 Http
::$httpEngine = false;
211 $this->runHTTPGets();
214 function testGetPhp() {
215 if ( !self
::$has_fopen ) {
216 $this->markTestIncomplete( "This test requires allow_url_fopen=true." );
219 Http
::$httpEngine = "php";
220 $this->runHTTPGets();
223 function testGetCurl() {
224 if ( !self
::$has_curl ) {
225 $this->markTestIncomplete( "This test requires curl." );
228 Http
::$httpEngine = "curl";
229 $this->runHTTPGets();
232 /* ./phase3/maintenance/parserTests.inc:1618: return Http::post( $url, array( 'postData' => wfArrayToCGI( $data ) ) ); */
233 function runHTTPPosts( $proxy = null ) {
237 $opt['proxy'] = $proxy;
238 } elseif ( $proxy === false ) {
239 $opt['noProxy'] = true;
242 foreach ( $this->test_posturl
as $u => $postData ) {
243 $opt['postData'] = $postData;
244 $r = Http
::post( $u, $opt );
245 $this->assertEquals( self
::$content["POST $u => $postData"], "$r",
246 "POST $u (postData=$postData) with " . Http
::$httpEngine );
250 function testPostDefault() {
251 Http
::$httpEngine = false;
252 $this->runHTTPPosts();
255 function testPostPhp() {
256 if ( !self
::$has_fopen ) {
257 $this->markTestIncomplete( "This test requires allow_url_fopen=true." );
260 Http
::$httpEngine = "php";
261 $this->runHTTPPosts();
264 function testPostCurl() {
265 if ( !self
::$has_curl ) {
266 $this->markTestIncomplete( "This test requires curl." );
269 Http
::$httpEngine = "curl";
270 $this->runHTTPPosts();
273 function runProxyRequests() {
274 if ( !self
::$has_proxy ) {
275 $this->markTestIncomplete( "This test requires a proxy." );
277 $this->runHTTPGets( self
::$proxy );
278 $this->runHTTPPosts( self
::$proxy );
279 $this->runHTTPRequests( self
::$proxy );
281 // Set false here to do noProxy
282 $this->runHTTPGets( false );
283 $this->runHTTPPosts( false );
284 $this->runHTTPRequests( false );
287 function testProxyDefault() {
288 Http
::$httpEngine = false;
289 $this->runProxyRequests();
292 function testProxyPhp() {
293 if ( !self
::$has_fopen ) {
294 $this->markTestIncomplete( "This test requires allow_url_fopen=true." );
297 Http
::$httpEngine = 'php';
298 $this->runProxyRequests();
301 function testProxyCurl() {
302 if ( !self
::$has_curl ) {
303 $this->markTestIncomplete( "This test requires curl." );
306 Http
::$httpEngine = 'curl';
307 $this->runProxyRequests();
310 function testIsLocalUrl() {
313 /* ./extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php:559: $user_agent = Http::userAgent(); */
314 function testUserAgent() {
317 function testIsValidUrl() {
320 function testValidateCookieDomain() {
321 $this->assertFalse( Cookie
::validateCookieDomain( "co.uk" ) );
322 $this->assertFalse( Cookie
::validateCookieDomain( ".co.uk" ) );
323 $this->assertFalse( Cookie
::validateCookieDomain( "gov.uk" ) );
324 $this->assertFalse( Cookie
::validateCookieDomain( ".gov.uk" ) );
325 $this->assertTrue( Cookie
::validateCookieDomain( "supermarket.uk" ) );
326 $this->assertFalse( Cookie
::validateCookieDomain( "uk" ) );
327 $this->assertFalse( Cookie
::validateCookieDomain( ".uk" ) );
328 $this->assertFalse( Cookie
::validateCookieDomain( "127.0.0." ) );
329 $this->assertFalse( Cookie
::validateCookieDomain( "127." ) );
330 $this->assertFalse( Cookie
::validateCookieDomain( "127.0.0.1." ) );
331 $this->assertTrue( Cookie
::validateCookieDomain( "127.0.0.1" ) );
332 $this->assertFalse( Cookie
::validateCookieDomain( "333.0.0.1" ) );
333 $this->assertTrue( Cookie
::validateCookieDomain( "example.com" ) );
334 $this->assertFalse( Cookie
::validateCookieDomain( "example.com." ) );
335 $this->assertTrue( Cookie
::validateCookieDomain( ".example.com" ) );
337 $this->assertTrue( Cookie
::validateCookieDomain( ".example.com", "www.example.com" ) );
338 $this->assertFalse( Cookie
::validateCookieDomain( "example.com", "www.example.com" ) );
339 $this->assertTrue( Cookie
::validateCookieDomain( "127.0.0.1", "127.0.0.1" ) );
340 $this->assertFalse( Cookie
::validateCookieDomain( "127.0.0.1", "localhost" ) );
345 function testSetCooke() {
346 $c = new MockCookie( "name", "value",
351 $this->assertFalse( $c->canServeDomain( "ac.th" ) );
353 $c = new MockCookie( "name", "value",
355 "domain" => "example.com",
359 $this->assertTrue( $c->canServeDomain( "example.com" ) );
360 $this->assertFalse( $c->canServeDomain( "www.example.com" ) );
362 $c = new MockCookie( "name", "value",
364 "domain" => ".example.com",
368 $this->assertFalse( $c->canServeDomain( "www.example.net" ) );
369 $this->assertFalse( $c->canServeDomain( "example.com" ) );
370 $this->assertTrue( $c->canServeDomain( "www.example.com" ) );
372 $this->assertFalse( $c->canServePath( "/" ) );
373 $this->assertFalse( $c->canServePath( "/bogus/path/" ) );
374 $this->assertFalse( $c->canServePath( "/path" ) );
375 $this->assertTrue( $c->canServePath( "/path/" ) );
377 $this->assertTrue( $c->isUnExpired() );
379 $this->assertEquals( "", $c->serializeToHttpRequest( "/path/", "www.example.net" ) );
380 $this->assertEquals( "", $c->serializeToHttpRequest( "/", "www.example.com" ) );
381 $this->assertEquals( "name=value", $c->serializeToHttpRequest( "/path/", "www.example.com" ) );
383 $c = new MockCookie( "name", "value",
385 "domain" => "www.example.com",
388 $this->assertFalse( $c->canServeDomain( "example.com" ) );
389 $this->assertFalse( $c->canServeDomain( "www.example.net" ) );
390 $this->assertTrue( $c->canServeDomain( "www.example.com" ) );
392 $c = new MockCookie( "name", "value",
394 "domain" => ".example.com",
396 "expires" => "-1 day",
398 $this->assertFalse( $c->isUnExpired() );
399 $this->assertEquals( "", $c->serializeToHttpRequest( "/path/", "www.example.com" ) );
401 $c = new MockCookie( "name", "value",
403 "domain" => ".example.com",
405 "expires" => "+1 day",
407 $this->assertTrue( $c->isUnExpired() );
408 $this->assertEquals( "name=value", $c->serializeToHttpRequest( "/path/", "www.example.com" ) );
411 function testCookieJarSetCookie() {
413 $cj->setCookie( "name", "value",
415 "domain" => ".example.com",
418 $cj->setCookie( "name2", "value",
420 "domain" => ".example.com",
421 "path" => "/path/sub",
423 $cj->setCookie( "name3", "value",
425 "domain" => ".example.com",
428 $cj->setCookie( "name4", "value",
430 "domain" => ".example.net",
433 $cj->setCookie( "name5", "value",
435 "domain" => ".example.net",
437 "expires" => "-1 day",
440 $this->assertEquals( "name4=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) );
441 $this->assertEquals( "name3=value", $cj->serializeToHttpRequest( "/", "www.example.com" ) );
442 $this->assertEquals( "name=value; name3=value", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) );
444 $cj->setCookie( "name5", "value",
446 "domain" => ".example.net",
448 "expires" => "+1 day",
450 $this->assertEquals( "name4=value; name5=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) );
452 $cj->setCookie( "name4", "value",
454 "domain" => ".example.net",
456 "expires" => "-1 day",
458 $this->assertEquals( "name5=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) );
461 function testParseResponseHeader() {
464 $h[] = "Set-Cookie: name4=value; domain=.example.com; path=/; expires=Mon, 09-Dec-2029 13:46:00 GMT";
465 $cj->parseCookieResponseHeader( $h[0], "www.example.com" );
466 $this->assertEquals( "name4=value", $cj->serializeToHttpRequest( "/", "www.example.com" ) );
468 $h[] = "name4=value2; domain=.example.com; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT";
469 $cj->parseCookieResponseHeader( $h[1], "www.example.com" );
470 $this->assertEquals( "", $cj->serializeToHttpRequest( "/", "www.example.com" ) );
471 $this->assertEquals( "name4=value2", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) );
473 $h[] = "name5=value3; domain=.example.com; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT";
474 $cj->parseCookieResponseHeader( $h[2], "www.example.com" );
475 $this->assertEquals( "name4=value2; name5=value3", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) );
477 $h[] = "name6=value3; domain=.example.net; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT";
478 $cj->parseCookieResponseHeader( $h[3], "www.example.com" );
479 $this->assertEquals( "", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) );
481 $h[] = "name6=value0; domain=.example.net; path=/path/; expires=Mon, 09-Dec-1999 13:46:00 GMT";
482 $cj->parseCookieResponseHeader( $h[4], "www.example.net" );
483 $this->assertEquals( "", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) );
485 $h[] = "name6=value4; domain=.example.net; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT";
486 $cj->parseCookieResponseHeader( $h[5], "www.example.net" );
487 $this->assertEquals( "name6=value4", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) );
490 function runCookieRequests() {
491 $r = MWHttpRequest
::factory( "http://www.php.net/manual", array( 'followRedirects' => true ) );
494 $jar = $r->getCookieJar();
495 $this->assertThat( $jar, $this->isInstanceOf( 'CookieJar' ) );
497 if ( $r instanceof PhpHttpRequest
&& version_compare( '5.1.7', phpversion(), '>' ) ) {
498 $this->markTestSkipped( 'Redirection fails or crashes PHP on 5.1.6 and prior' );
500 $serialized = $jar->serializeToHttpRequest( "/search?q=test", "www.php.net" );
501 $this->assertRegExp( '/\bCOUNTRY=[^=;]+/', $serialized );
502 $this->assertRegExp( '/\bLAST_LANG=[^=;]+/', $serialized );
503 $this->assertEquals( '', $jar->serializeToHttpRequest( "/search?q=test", "www.php.com" ) );
506 function testCookieRequestDefault() {
507 Http
::$httpEngine = false;
508 $this->runCookieRequests();
510 function testCookieRequestPhp() {
511 if ( !self
::$has_fopen ) {
512 $this->markTestIncomplete( "This test requires allow_url_fopen=true." );
515 Http
::$httpEngine = 'php';
516 $this->runCookieRequests();
518 function testCookieRequestCurl() {
519 if ( !self
::$has_curl ) {
520 $this->markTestIncomplete( "This test requires curl." );
523 Http
::$httpEngine = 'curl';
524 $this->runCookieRequests();