MediaWiki  REL1_22
HttpTest.php
Go to the documentation of this file.
00001 <?php
00005 class HttpTest extends MediaWikiTestCase {
00010     public function testValidateCookieDomain( $expected, $domain, $origin = null ) {
00011         if ( $origin ) {
00012             $ok = Cookie::validateCookieDomain( $domain, $origin );
00013             $msg = "$domain against origin $origin";
00014         } else {
00015             $ok = Cookie::validateCookieDomain( $domain );
00016             $msg = "$domain";
00017         }
00018         $this->assertEquals( $expected, $ok, $msg );
00019     }
00020 
00021     public static function cookieDomains() {
00022         return array(
00023             array( false, "org" ),
00024             array( false, ".org" ),
00025             array( true, "wikipedia.org" ),
00026             array( true, ".wikipedia.org" ),
00027             array( false, "co.uk" ),
00028             array( false, ".co.uk" ),
00029             array( false, "gov.uk" ),
00030             array( false, ".gov.uk" ),
00031             array( true, "supermarket.uk" ),
00032             array( false, "uk" ),
00033             array( false, ".uk" ),
00034             array( false, "127.0.0." ),
00035             array( false, "127." ),
00036             array( false, "127.0.0.1." ),
00037             array( true, "127.0.0.1" ),
00038             array( false, "333.0.0.1" ),
00039             array( true, "example.com" ),
00040             array( false, "example.com." ),
00041             array( true, ".example.com" ),
00042 
00043             array( true, ".example.com", "www.example.com" ),
00044             array( false, "example.com", "www.example.com" ),
00045             array( true, "127.0.0.1", "127.0.0.1" ),
00046             array( false, "127.0.0.1", "localhost" ),
00047         );
00048     }
00049 
00056     public function testIsValidUri( $expect, $URI, $message = '' ) {
00057         $this->assertEquals(
00058             $expect,
00059             (bool)Http::isValidURI( $URI ),
00060             $message
00061         );
00062     }
00063 
00067     public static function provideURI() {
00069         return array(
00070             array( false, '¿non sens before!! http://a', 'Allow anything before URI' ),
00071 
00072             # (http|https) - only two schemes allowed
00073             array( true, 'http://www.example.org/' ),
00074             array( true, 'https://www.example.org/' ),
00075             array( true, 'http://www.example.org', 'URI without directory' ),
00076             array( true, 'http://a', 'Short name' ),
00077             array( true, 'http://étoile', 'Allow UTF-8 in hostname' ), # 'étoile' is french for 'star'
00078             array( false, '\\host\directory', 'CIFS share' ),
00079             array( false, 'gopher://host/dir', 'Reject gopher scheme' ),
00080             array( false, 'telnet://host', 'Reject telnet scheme' ),
00081 
00082             # :\/\/ - double slashes
00083             array( false, 'http//example.org', 'Reject missing colon in protocol' ),
00084             array( false, 'http:/example.org', 'Reject missing slash in protocol' ),
00085             array( false, 'http:example.org', 'Must have two slashes' ),
00086             # Following fail since hostname can be made of anything
00087             array( false, 'http:///example.org', 'Must have exactly two slashes, not three' ),
00088 
00089             # (\w+:{0,1}\w*@)? - optional user:pass
00090             array( true, 'http://user@host', 'Username provided' ),
00091             array( true, 'http://user:@host', 'Username provided, no password' ),
00092             array( true, 'http://user:pass@host', 'Username and password provided' ),
00093 
00094             # (\S+) - host part is made of anything not whitespaces
00095             array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ),
00096             array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ),
00097 
00098             # (:[0-9]+)? - port number
00099             array( true, 'http://example.org:80/' ),
00100             array( true, 'https://example.org:80/' ),
00101             array( true, 'http://example.org:443/' ),
00102             array( true, 'https://example.org:443/' ),
00103 
00104             # Part after the hostname is / or / with something else
00105             array( true, 'http://example/#' ),
00106             array( true, 'http://example/!' ),
00107             array( true, 'http://example/:' ),
00108             array( true, 'http://example/.' ),
00109             array( true, 'http://example/?' ),
00110             array( true, 'http://example/+' ),
00111             array( true, 'http://example/=' ),
00112             array( true, 'http://example/&' ),
00113             array( true, 'http://example/%' ),
00114             array( true, 'http://example/@' ),
00115             array( true, 'http://example/-' ),
00116             array( true, 'http://example//' ),
00117             array( true, 'http://example/&' ),
00118 
00119             # Fragment
00120             array( true, 'http://exam#ple.org', ), # This one is valid, really!
00121             array( true, 'http://example.org:80#anchor' ),
00122             array( true, 'http://example.org/?id#anchor' ),
00123             array( true, 'http://example.org/?#anchor' ),
00124 
00125             array( false, 'http://a ¿non !!sens after', 'Allow anything after URI' ),
00126         );
00127     }
00128 
00137     public function testRelativeRedirections() {
00138         $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext' );
00139 
00140         # Forge a Location header
00141         $h->setRespHeaders( 'location', array(
00142                 'http://newsite/file.ext',
00143                 '/newfile.ext',
00144             )
00145         );
00146         # Verify we correctly fix the Location
00147         $this->assertEquals(
00148             'http://newsite/newfile.ext',
00149             $h->getFinalUrl(),
00150             "Relative file path Location: interpreted as full URL"
00151         );
00152 
00153         $h->setRespHeaders( 'location', array(
00154                 'https://oldsite/file.ext'
00155             )
00156         );
00157         $this->assertEquals(
00158             'https://oldsite/file.ext',
00159             $h->getFinalUrl(),
00160             "Location to the HTTPS version of the site"
00161         );
00162 
00163         $h->setRespHeaders( 'location', array(
00164                 '/anotherfile.ext',
00165                 'http://anotherfile/hoster.ext',
00166                 'https://anotherfile/hoster.ext'
00167             )
00168         );
00169         $this->assertEquals(
00170             'https://anotherfile/hoster.ext',
00171             $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" )
00172         );
00173     }
00174 }
00175 
00179 class MWHttpRequestTester extends MWHttpRequest {
00180 
00181     // function derived from the MWHttpRequest factory function but
00182     // returns appropriate tester class here
00183     public static function factory( $url, $options = null ) {
00184         if ( !Http::$httpEngine ) {
00185             Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
00186         } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
00187             throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
00188                 'Http::$httpEngine is set to "curl"' );
00189         }
00190 
00191         switch ( Http::$httpEngine ) {
00192             case 'curl':
00193                 return new CurlHttpRequestTester( $url, $options );
00194             case 'php':
00195                 if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
00196                     throw new MWException( __METHOD__ . ': allow_url_fopen needs to be enabled for pure PHP' .
00197                         ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' );
00198                 }
00199 
00200                 return new PhpHttpRequestTester( $url, $options );
00201             default:
00202         }
00203     }
00204 }
00205 
00206 class CurlHttpRequestTester extends CurlHttpRequest {
00207     function setRespHeaders( $name, $value ) {
00208         $this->respHeaders[$name] = $value;
00209     }
00210 }
00211 
00212 class PhpHttpRequestTester extends PhpHttpRequest {
00213     function setRespHeaders( $name, $value ) {
00214         $this->respHeaders[$name] = $value;
00215     }
00216 }