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