1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.apache.commons.httpclient;
31
32 import java.io.IOException;
33
34 import junit.framework.Test;
35 import junit.framework.TestSuite;
36
37 import org.apache.commons.httpclient.methods.GetMethod;
38 import org.apache.commons.httpclient.methods.PostMethod;
39 import org.apache.commons.httpclient.methods.StringRequestEntity;
40 import org.apache.commons.httpclient.params.HttpClientParams;
41 import org.apache.commons.httpclient.protocol.Protocol;
42 import org.apache.commons.httpclient.server.HttpService;
43 import org.apache.commons.httpclient.server.RequestLine;
44 import org.apache.commons.httpclient.server.SimpleHttpServer;
45 import org.apache.commons.httpclient.server.SimpleRequest;
46 import org.apache.commons.httpclient.server.SimpleResponse;
47
48 /***
49 * Redirection test cases.
50 *
51 * @author Oleg Kalnichevski
52 *
53 * @version $Id: TestRedirects.java 608014 2008-01-02 05:48:53Z rolandw $
54 */
55 public class TestRedirects extends HttpClientTestBase {
56
57
58 public TestRedirects(final String testName) throws IOException {
59 super(testName);
60 }
61
62
63 public static void main(String args[]) {
64 String[] testCaseName = { TestRedirects.class.getName() };
65 junit.textui.TestRunner.main(testCaseName);
66 }
67
68
69
70 public static Test suite() {
71 TestSuite suite = new TestSuite(TestRedirects.class);
72 ProxyTestDecorator.addTests(suite);
73 return suite;
74 }
75
76 private class BasicRedirectService implements HttpService {
77 private int statuscode = HttpStatus.SC_MOVED_TEMPORARILY;
78 private String host = null;
79 private int port;
80
81 public BasicRedirectService(final String host, int port, int statuscode) {
82 super();
83 this.host = host;
84 this.port = port;
85 if (statuscode > 0) {
86 this.statuscode = statuscode;
87 }
88 }
89
90 public BasicRedirectService(final String host, int port) {
91 this(host, port, -1);
92 }
93
94 public boolean process(final SimpleRequest request, final SimpleResponse response)
95 throws IOException {
96 RequestLine reqline = request.getRequestLine();
97 HttpVersion ver = reqline.getHttpVersion();
98 if (reqline.getUri().equals("/oldlocation/")) {
99 response.setStatusLine(ver, this.statuscode);
100 response.addHeader(new Header("Location",
101 "http://" + this.host + ":" + this.port + "/newlocation/"));
102 response.addHeader(new Header("Connection", "close"));
103 } else if (reqline.getUri().equals("/newlocation/")) {
104 response.setStatusLine(ver, HttpStatus.SC_OK);
105 response.setBodyString("Successful redirect");
106 } else {
107 response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
108 }
109 return true;
110 }
111 }
112
113 private class CircularRedirectService implements HttpService {
114
115 private int invocations = 0;
116
117 public CircularRedirectService() {
118 super();
119 }
120
121 public boolean process(final SimpleRequest request, final SimpleResponse response)
122 throws IOException
123 {
124 RequestLine reqline = request.getRequestLine();
125 HttpVersion ver = reqline.getHttpVersion();
126 if (reqline.getUri().startsWith("/circular-oldlocation")) {
127 response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
128 response.addHeader(new Header("Location", "/circular-location2?invk=" + (++this.invocations)));
129 } else if (reqline.getUri().startsWith("/circular-location2")) {
130 response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
131 response.addHeader(new Header("Location", "/circular-oldlocation?invk=" + (++this.invocations)));
132 } else {
133 response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
134 }
135 return true;
136 }
137 }
138
139 private class RelativeRedirectService implements HttpService {
140
141 public RelativeRedirectService() {
142 super();
143 }
144
145 public boolean process(final SimpleRequest request, final SimpleResponse response)
146 throws IOException
147 {
148 RequestLine reqline = request.getRequestLine();
149 HttpVersion ver = reqline.getHttpVersion();
150 if (reqline.getUri().equals("/oldlocation/")) {
151 response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
152 response.addHeader(new Header("Location", "/relativelocation/"));
153 } else if (reqline.getUri().equals("/relativelocation/")) {
154 response.setStatusLine(ver, HttpStatus.SC_OK);
155 response.setBodyString("Successful redirect");
156 } else {
157 response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
158 }
159 return true;
160 }
161 }
162
163 private class BogusRedirectService implements HttpService {
164 private String url;
165
166 public BogusRedirectService(String redirectUrl) {
167 super();
168 this.url = redirectUrl;
169 }
170
171 public boolean process(final SimpleRequest request, final SimpleResponse response)
172 throws IOException {
173 RequestLine reqline = request.getRequestLine();
174 HttpVersion ver = reqline.getHttpVersion();
175 if (reqline.getUri().equals("/oldlocation/")) {
176 response.setStatusLine(ver, HttpStatus.SC_MOVED_TEMPORARILY);
177 response.addHeader(new Header("Location", url));
178 } else if (reqline.getUri().equals("/relativelocation/")) {
179 response.setStatusLine(ver, HttpStatus.SC_OK);
180 response.setBodyString("Successful redirect");
181 } else {
182 response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
183 }
184 return true;
185 }
186 }
187
188 public void testBasicRedirect300() throws IOException {
189 String host = this.server.getLocalAddress();
190 int port = this.server.getLocalPort();
191 this.server.setHttpService(
192 new BasicRedirectService(host, port, HttpStatus.SC_MULTIPLE_CHOICES));
193 GetMethod httpget = new GetMethod("/oldlocation/");
194 httpget.setFollowRedirects(false);
195 try {
196 this.client.executeMethod(httpget);
197 assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, httpget.getStatusCode());
198 assertEquals("/oldlocation/", httpget.getPath());
199 assertEquals(new URI("/oldlocation/", false), httpget.getURI());
200 } finally {
201 httpget.releaseConnection();
202 }
203 }
204
205 public void testBasicRedirect301() throws IOException {
206 String host = this.server.getLocalAddress();
207 int port = this.server.getLocalPort();
208 this.server.setHttpService(
209 new BasicRedirectService(host, port, HttpStatus.SC_MOVED_PERMANENTLY));
210 GetMethod httpget = new GetMethod("/oldlocation/");
211 httpget.setFollowRedirects(true);
212 try {
213 this.client.executeMethod(httpget);
214 assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
215 assertEquals("/newlocation/", httpget.getPath());
216 assertEquals(host, httpget.getURI().getHost());
217 assertEquals(port, httpget.getURI().getPort());
218 assertEquals(new URI("http://" + host + ":" + port + "/newlocation/", false), httpget.getURI());
219 } finally {
220 httpget.releaseConnection();
221 }
222 }
223
224 public void testBasicRedirect302() throws IOException {
225 String host = this.server.getLocalAddress();
226 int port = this.server.getLocalPort();
227 this.server.setHttpService(
228 new BasicRedirectService(host, port, HttpStatus.SC_MOVED_TEMPORARILY));
229 GetMethod httpget = new GetMethod("/oldlocation/");
230 httpget.setFollowRedirects(true);
231 try {
232 this.client.executeMethod(httpget);
233 assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
234 assertEquals("/newlocation/", httpget.getPath());
235 assertEquals(host, httpget.getURI().getHost());
236 assertEquals(port, httpget.getURI().getPort());
237 assertEquals(new URI("http://" + host + ":" + port + "/newlocation/", false), httpget.getURI());
238 } finally {
239 httpget.releaseConnection();
240 }
241 }
242
243 public void testBasicRedirect303() throws IOException {
244 String host = this.server.getLocalAddress();
245 int port = this.server.getLocalPort();
246 this.server.setHttpService(
247 new BasicRedirectService(host, port, HttpStatus.SC_SEE_OTHER));
248 GetMethod httpget = new GetMethod("/oldlocation/");
249 httpget.setFollowRedirects(true);
250 try {
251 this.client.executeMethod(httpget);
252 assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
253 assertEquals("/newlocation/", httpget.getPath());
254 assertEquals(host, httpget.getURI().getHost());
255 assertEquals(port, httpget.getURI().getPort());
256 assertEquals(new URI("http://" + host + ":" + port + "/newlocation/", false), httpget.getURI());
257 } finally {
258 httpget.releaseConnection();
259 }
260 }
261
262 public void testBasicRedirect304() throws IOException {
263 String host = this.server.getLocalAddress();
264 int port = this.server.getLocalPort();
265 this.server.setHttpService(
266 new BasicRedirectService(host, port, HttpStatus.SC_NOT_MODIFIED));
267 GetMethod httpget = new GetMethod("/oldlocation/");
268 httpget.setFollowRedirects(true);
269 try {
270 this.client.executeMethod(httpget);
271 assertEquals(HttpStatus.SC_NOT_MODIFIED, httpget.getStatusCode());
272 assertEquals("/oldlocation/", httpget.getPath());
273 assertEquals(new URI("/oldlocation/", false), httpget.getURI());
274 } finally {
275 httpget.releaseConnection();
276 }
277 }
278
279 public void testBasicRedirect305() throws IOException {
280 String host = this.server.getLocalAddress();
281 int port = this.server.getLocalPort();
282 this.server.setHttpService(
283 new BasicRedirectService(host, port, HttpStatus.SC_USE_PROXY));
284 GetMethod httpget = new GetMethod("/oldlocation/");
285 httpget.setFollowRedirects(true);
286 try {
287 this.client.executeMethod(httpget);
288 assertEquals(HttpStatus.SC_USE_PROXY, httpget.getStatusCode());
289 assertEquals("/oldlocation/", httpget.getPath());
290 assertEquals(new URI("/oldlocation/", false), httpget.getURI());
291 } finally {
292 httpget.releaseConnection();
293 }
294 }
295
296 public void testBasicRedirect307() throws IOException {
297 String host = this.server.getLocalAddress();
298 int port = this.server.getLocalPort();
299 this.server.setHttpService(
300 new BasicRedirectService(host, port, HttpStatus.SC_TEMPORARY_REDIRECT));
301 GetMethod httpget = new GetMethod("/oldlocation/");
302 httpget.setFollowRedirects(true);
303 try {
304 this.client.executeMethod(httpget);
305 assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
306 assertEquals("/newlocation/", httpget.getPath());
307 assertEquals(host, httpget.getURI().getHost());
308 assertEquals(port, httpget.getURI().getPort());
309 assertEquals(new URI("http://" + host + ":" + port + "/newlocation/", false), httpget.getURI());
310 } finally {
311 httpget.releaseConnection();
312 }
313 }
314
315 public void testNoRedirect() throws IOException {
316 String host = this.server.getLocalAddress();
317 int port = this.server.getLocalPort();
318 this.server.setHttpService(new BasicRedirectService(host, port));
319 GetMethod httpget = new GetMethod("/oldlocation/");
320 httpget.setFollowRedirects(false);
321 try {
322 this.client.executeMethod(httpget);
323 assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, httpget.getStatusCode());
324 assertEquals("/oldlocation/", httpget.getPath());
325 assertEquals(new URI("/oldlocation/", false), httpget.getURI());
326 } finally {
327 httpget.releaseConnection();
328 }
329 }
330
331 public void testMaxRedirectCheck() throws IOException {
332 this.server.setHttpService(new CircularRedirectService());
333 GetMethod httpget = new GetMethod("/circular-oldlocation/");
334 try {
335 this.client.getParams().setBooleanParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, true);
336 this.client.getParams().setIntParameter(HttpClientParams.MAX_REDIRECTS, 5);
337 this.client.executeMethod(httpget);
338 fail("RedirectException exception should have been thrown");
339 }
340 catch (RedirectException e) {
341
342 } finally {
343 httpget.releaseConnection();
344 }
345 }
346
347 public void testCircularRedirect() throws IOException {
348 this.server.setHttpService(new CircularRedirectService());
349 GetMethod httpget = new GetMethod("/circular-oldlocation/");
350 try {
351 this.client.getParams().setBooleanParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, false);
352 this.client.executeMethod(httpget);
353 fail("CircularRedirectException exception should have been thrown");
354 } catch (CircularRedirectException expected) {
355 } finally {
356 httpget.releaseConnection();
357 }
358 }
359
360 public void testPostRedirect() throws IOException {
361 String host = this.server.getLocalAddress();
362 int port = this.server.getLocalPort();
363 this.server.setHttpService(new BasicRedirectService(host, port));
364 PostMethod httppost = new PostMethod("/oldlocation/");
365 httppost.setRequestEntity(new StringRequestEntity("stuff", null, null));
366 try {
367 this.client.executeMethod(httppost);
368 assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, httppost.getStatusCode());
369 assertEquals("/oldlocation/", httppost.getPath());
370 assertEquals(new URI("/oldlocation/", false), httppost.getURI());
371 } finally {
372 httppost.releaseConnection();
373 }
374 }
375
376 public void testRelativeRedirect() throws IOException {
377 String host = this.server.getLocalAddress();
378 int port = this.server.getLocalPort();
379 this.server.setHttpService(new RelativeRedirectService());
380 this.client.getParams().setBooleanParameter(
381 HttpClientParams.REJECT_RELATIVE_REDIRECT, false);
382 GetMethod httpget = new GetMethod("/oldlocation/");
383 httpget.setFollowRedirects(true);
384 try {
385 this.client.executeMethod(httpget);
386 assertEquals("/relativelocation/", httpget.getPath());
387 assertEquals(host, httpget.getURI().getHost());
388 assertEquals(port, httpget.getURI().getPort());
389 assertEquals(new URI("http://" + host + ":" + port + "/relativelocation/", false),
390 httpget.getURI());
391 } finally {
392 httpget.releaseConnection();
393 }
394 }
395
396 public void testRejectRelativeRedirect() throws IOException {
397 String host = this.server.getLocalAddress();
398 int port = this.server.getLocalPort();
399 this.server.setHttpService(new RelativeRedirectService());
400 this.client.getParams().setBooleanParameter(
401 HttpClientParams.REJECT_RELATIVE_REDIRECT, true);
402 GetMethod httpget = new GetMethod("/oldlocation/");
403 httpget.setFollowRedirects(true);
404 try {
405 this.client.executeMethod(httpget);
406 assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, httpget.getStatusCode());
407 assertEquals("/oldlocation/", httpget.getPath());
408 assertEquals(new URI("/oldlocation/", false), httpget.getURI());
409 } finally {
410 httpget.releaseConnection();
411 }
412 }
413
414 public void testRejectBogusRedirectLocation() throws IOException {
415 String host = this.server.getLocalAddress();
416 int port = this.server.getLocalPort();
417 this.server.setHttpService(new BogusRedirectService("xxx://bogus"));
418 GetMethod httpget = new GetMethod("/oldlocation/");
419 httpget.setFollowRedirects(true);
420 try {
421 this.client.executeMethod(httpget);
422 fail("BogusRedirectService should have been thrown");
423 } catch (IllegalStateException e) {
424
425 } finally {
426 httpget.releaseConnection();
427 }
428 }
429
430 public void testRejectInvalidRedirectLocation() throws IOException {
431 String host = this.server.getLocalAddress();
432 int port = this.server.getLocalPort();
433 this.server.setHttpService(new BogusRedirectService("http://"+ host +":"+ port +"/newlocation/?p=I have spaces"));
434 GetMethod httpget = new GetMethod("/oldlocation/");
435 httpget.setFollowRedirects(true);
436 try {
437 this.client.executeMethod(httpget);
438 fail("InvalidRedirectLocationException should have been thrown");
439 } catch (InvalidRedirectLocationException e) {
440
441 } finally {
442 httpget.releaseConnection();
443 }
444 }
445
446 public void testCrossSiteRedirect() throws IOException {
447 String host = this.server.getLocalAddress();
448 int port = this.server.getLocalPort();
449
450 SimpleHttpServer thatserver = new SimpleHttpServer();
451 this.server.setHttpService(new BasicRedirectService(host, port));
452 thatserver.setHttpService(new BasicRedirectService(host, port));
453 thatserver.setTestname(getName());
454
455 HostConfiguration hostconfig = new HostConfiguration();
456 hostconfig.setHost(
457 thatserver.getLocalAddress(),
458 thatserver.getLocalPort(),
459 Protocol.getProtocol("http"));
460
461 GetMethod httpget = new GetMethod("/oldlocation/");
462 httpget.setFollowRedirects(true);
463 try {
464 this.client.executeMethod(hostconfig, httpget);
465 assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
466 assertEquals("/newlocation/", httpget.getPath());
467 assertEquals(host, httpget.getURI().getHost());
468 assertEquals(port, httpget.getURI().getPort());
469 assertEquals(new URI("http://" + host + ":" + port + "/newlocation/", false),
470 httpget.getURI());
471 } finally {
472 httpget.releaseConnection();
473 }
474 thatserver.destroy();
475 }
476
477 public void testRedirectWithCookie() throws IOException {
478
479 client.getState().addCookie(new Cookie("localhost", "name", "value", "/", -1, false));
480
481 String host = this.server.getLocalAddress();
482 int port = this.server.getLocalPort();
483
484 this.server.setHttpService(new BasicRedirectService(host, port));
485 GetMethod httpget = new GetMethod("/oldlocation/");
486 httpget.setFollowRedirects(true);
487 try {
488 this.client.executeMethod(httpget);
489 assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
490 assertEquals("/newlocation/", httpget.getPath());
491
492 Header[] headers = httpget.getRequestHeaders();
493 int cookiecount = 0;
494 for (int i = 0; i < headers.length; i++) {
495 if ("cookie".equalsIgnoreCase(headers[i].getName())) {
496 ++cookiecount;
497 }
498 }
499 assertEquals("There can only be one (cookie)", 1, cookiecount);
500 } finally {
501 httpget.releaseConnection();
502 }
503 }
504 }