MediaWiki
REL1_22
|
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 }