Merge "Added space after switch/Removed spaces after unset"
[lhc/web/wiklou.git] / tests / phpunit / includes / HttpTest.php
1 <?php
2 /**
3 * @group Broken
4 */
5 class HttpTest extends MediaWikiTestCase {
6 /**
7 * @dataProvider cookieDomains
8 */
9 function testValidateCookieDomain( $expected, $domain, $origin = null ) {
10 if ( $origin ) {
11 $ok = Cookie::validateCookieDomain( $domain, $origin );
12 $msg = "$domain against origin $origin";
13 } else {
14 $ok = Cookie::validateCookieDomain( $domain );
15 $msg = "$domain";
16 }
17 $this->assertEquals( $expected, $ok, $msg );
18 }
19
20 public static function cookieDomains() {
21 return array(
22 array( false, "org" ),
23 array( false, ".org" ),
24 array( true, "wikipedia.org" ),
25 array( true, ".wikipedia.org" ),
26 array( false, "co.uk" ),
27 array( false, ".co.uk" ),
28 array( false, "gov.uk" ),
29 array( false, ".gov.uk" ),
30 array( true, "supermarket.uk" ),
31 array( false, "uk" ),
32 array( false, ".uk" ),
33 array( false, "127.0.0." ),
34 array( false, "127." ),
35 array( false, "127.0.0.1." ),
36 array( true, "127.0.0.1" ),
37 array( false, "333.0.0.1" ),
38 array( true, "example.com" ),
39 array( false, "example.com." ),
40 array( true, ".example.com" ),
41
42 array( true, ".example.com", "www.example.com" ),
43 array( false, "example.com", "www.example.com" ),
44 array( true, "127.0.0.1", "127.0.0.1" ),
45 array( false, "127.0.0.1", "localhost" ),
46 );
47 }
48
49 /**
50 * Test Http::isValidURI()
51 * @bug 27854 : Http::isValidURI is too lax
52 * @dataProvider provideURI
53 */
54 function testIsValidUri( $expect, $URI, $message = '' ) {
55 $this->assertEquals(
56 $expect,
57 (bool)Http::isValidURI( $URI ),
58 $message
59 );
60 }
61
62 /**
63 * Feeds URI to test a long regular expression in Http::isValidURI
64 */
65 public static function provideURI() {
66 /** Format: 'boolean expectation', 'URI to test', 'Optional message' */
67 return array(
68 array( false, '¿non sens before!! http://a', 'Allow anything before URI' ),
69
70 # (http|https) - only two schemes allowed
71 array( true, 'http://www.example.org/' ),
72 array( true, 'https://www.example.org/' ),
73 array( true, 'http://www.example.org', 'URI without directory' ),
74 array( true, 'http://a', 'Short name' ),
75 array( true, 'http://étoile', 'Allow UTF-8 in hostname' ), # 'étoile' is french for 'star'
76 array( false, '\\host\directory', 'CIFS share' ),
77 array( false, 'gopher://host/dir', 'Reject gopher scheme' ),
78 array( false, 'telnet://host', 'Reject telnet scheme' ),
79
80 # :\/\/ - double slashes
81 array( false, 'http//example.org', 'Reject missing colon in protocol' ),
82 array( false, 'http:/example.org', 'Reject missing slash in protocol' ),
83 array( false, 'http:example.org', 'Must have two slashes' ),
84 # Following fail since hostname can be made of anything
85 array( false, 'http:///example.org', 'Must have exactly two slashes, not three' ),
86
87 # (\w+:{0,1}\w*@)? - optional user:pass
88 array( true, 'http://user@host', 'Username provided' ),
89 array( true, 'http://user:@host', 'Username provided, no password' ),
90 array( true, 'http://user:pass@host', 'Username and password provided' ),
91
92 # (\S+) - host part is made of anything not whitespaces
93 array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ),
94 array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ),
95
96 # (:[0-9]+)? - port number
97 array( true, 'http://example.org:80/' ),
98 array( true, 'https://example.org:80/' ),
99 array( true, 'http://example.org:443/' ),
100 array( true, 'https://example.org:443/' ),
101
102 # Part after the hostname is / or / with something else
103 array( true, 'http://example/#' ),
104 array( true, 'http://example/!' ),
105 array( true, 'http://example/:' ),
106 array( true, 'http://example/.' ),
107 array( true, 'http://example/?' ),
108 array( true, 'http://example/+' ),
109 array( true, 'http://example/=' ),
110 array( true, 'http://example/&' ),
111 array( true, 'http://example/%' ),
112 array( true, 'http://example/@' ),
113 array( true, 'http://example/-' ),
114 array( true, 'http://example//' ),
115 array( true, 'http://example/&' ),
116
117 # Fragment
118 array( true, 'http://exam#ple.org', ), # This one is valid, really!
119 array( true, 'http://example.org:80#anchor' ),
120 array( true, 'http://example.org/?id#anchor' ),
121 array( true, 'http://example.org/?#anchor' ),
122
123 array( false, 'http://a ¿non !!sens after', 'Allow anything after URI' ),
124 );
125 }
126
127 /**
128 * Warning:
129 *
130 * These tests are for code that makes use of an artifact of how CURL
131 * handles header reporting on redirect pages, and will need to be
132 * rewritten when bug 29232 is taken care of (high-level handling of
133 * HTTP redirects).
134 */
135 function testRelativeRedirections() {
136 $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext' );
137
138 # Forge a Location header
139 $h->setRespHeaders( 'location', array(
140 'http://newsite/file.ext',
141 '/newfile.ext',
142 )
143 );
144 # Verify we correctly fix the Location
145 $this->assertEquals(
146 'http://newsite/newfile.ext',
147 $h->getFinalUrl(),
148 "Relative file path Location: interpreted as full URL"
149 );
150
151 $h->setRespHeaders( 'location', array(
152 'https://oldsite/file.ext'
153 )
154 );
155 $this->assertEquals(
156 'https://oldsite/file.ext',
157 $h->getFinalUrl(),
158 "Location to the HTTPS version of the site"
159 );
160
161 $h->setRespHeaders( 'location', array(
162 '/anotherfile.ext',
163 'http://anotherfile/hoster.ext',
164 'https://anotherfile/hoster.ext'
165 )
166 );
167 $this->assertEquals(
168 'https://anotherfile/hoster.ext',
169 $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" )
170 );
171 }
172 }
173
174 /**
175 * Class to let us overwrite MWHttpRequest respHeaders variable
176 */
177 class MWHttpRequestTester extends MWHttpRequest {
178
179 // function derived from the MWHttpRequest factory function but
180 // returns appropriate tester class here
181 public static function factory( $url, $options = null ) {
182 if ( !Http::$httpEngine ) {
183 Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
184 } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
185 throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
186 'Http::$httpEngine is set to "curl"' );
187 }
188
189 switch ( Http::$httpEngine ) {
190 case 'curl':
191 return new CurlHttpRequestTester( $url, $options );
192 case 'php':
193 if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
194 throw new MWException( __METHOD__ . ': allow_url_fopen needs to be enabled for pure PHP' .
195 ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' );
196 }
197
198 return new PhpHttpRequestTester( $url, $options );
199 default:
200 }
201 }
202 }
203
204 class CurlHttpRequestTester extends CurlHttpRequest {
205 function setRespHeaders( $name, $value ) {
206 $this->respHeaders[$name] = $value;
207 }
208 }
209
210 class PhpHttpRequestTester extends PhpHttpRequest {
211 function setRespHeaders( $name, $value ) {
212 $this->respHeaders[$name] = $value;
213 }
214 }