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