Index: src/docbkx/httpagent.xml =================================================================== --- src/docbkx/httpagent.xml (revision 792829) +++ src/docbkx/httpagent.xml (working copy) @@ -172,9 +172,10 @@
Automcatic redirect handling HttpClient handles all types of redirects automatically, except those explicitly - prohibited by the HTTP specification as requiring user intervention. Redirects on - POST and PUT requests are converted to - GET requests as required by the HTTP specification. + prohibited by the HTTP specification as requiring user intervention. See + Other (status code 303) redirects on POST and + PUT requests are converted to GET requests as + required by the HTTP specification.
HTTP client and execution context Index: httpclient/src/test/java/org/apache/http/client/protocol/TestRedirects.java =================================================================== --- httpclient/src/test/java/org/apache/http/client/protocol/TestRedirects.java (revision 792829) +++ httpclient/src/test/java/org/apache/http/client/protocol/TestRedirects.java (working copy) @@ -455,7 +455,7 @@ } } - public void testPostRedirect() throws Exception { + public void testPostNoRedirect() throws Exception { int port = this.localServer.getServicePort(); String host = "localhost"; this.localServer.register("*", new BasicRedirectService(host, port)); @@ -475,6 +475,32 @@ HttpRequest reqWrapper = (HttpRequest) context.getAttribute( ExecutionContext.HTTP_REQUEST); + assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getStatusLine().getStatusCode()); + assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri()); + assertEquals("POST", reqWrapper.getRequestLine().getMethod()); + } + + public void testPostRedirectSeeOther() throws Exception { + int port = this.localServer.getServicePort(); + String host = "localhost"; + this.localServer.register("*", new BasicRedirectService(host, port, + HttpStatus.SC_SEE_OTHER)); + + DefaultHttpClient client = new DefaultHttpClient(); + HttpContext context = new BasicHttpContext(); + + HttpPost httppost = new HttpPost("/oldlocation/"); + httppost.setEntity(new StringEntity("stuff")); + + HttpResponse response = client.execute(getServerHttp(), httppost, context); + HttpEntity e = response.getEntity(); + if (e != null) { + e.consumeContent(); + } + + HttpRequest reqWrapper = (HttpRequest) context.getAttribute( + ExecutionContext.HTTP_REQUEST); + assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); assertEquals("GET", reqWrapper.getRequestLine().getMethod()); Index: httpclient/src/main/java/org/apache/http/impl/client/HttpRedirect.java =================================================================== --- httpclient/src/main/java/org/apache/http/impl/client/HttpRedirect.java (revision 0) +++ httpclient/src/main/java/org/apache/http/impl/client/HttpRedirect.java (revision 0) @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.URI; + +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpRequestBase; + +import net.jcip.annotations.NotThreadSafe; + +/** + * Redirect request (can be either GET or HEAD). + * + * @since 4.0 + */ +@NotThreadSafe +class HttpRedirect extends HttpRequestBase { + + private String method; + + public HttpRedirect(final String method, final URI uri) { + super(); + if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) { + this.method = HttpHead.METHOD_NAME; + } else { + this.method = HttpGet.METHOD_NAME; + } + setURI(uri); + } + + @Override + public String getMethod() { + return this.method; + } + +} Index: httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectHandler.java =================================================================== --- httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectHandler.java (revision 792829) +++ httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectHandler.java (working copy) @@ -46,6 +46,8 @@ import org.apache.http.ProtocolException; import org.apache.http.client.CircularRedirectException; import org.apache.http.client.RedirectHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.utils.URIUtils; import org.apache.http.params.HttpParams; @@ -74,12 +76,18 @@ if (response == null) { throw new IllegalArgumentException("HTTP response may not be null"); } + int statusCode = response.getStatusLine().getStatusCode(); switch (statusCode) { case HttpStatus.SC_MOVED_TEMPORARILY: case HttpStatus.SC_MOVED_PERMANENTLY: + case HttpStatus.SC_TEMPORARY_REDIRECT: + HttpRequest request = (HttpRequest) context.getAttribute( + ExecutionContext.HTTP_REQUEST); + String method = request.getRequestLine().getMethod(); + return method.equalsIgnoreCase(HttpGet.METHOD_NAME) + || method.equalsIgnoreCase(HttpHead.METHOD_NAME); case HttpStatus.SC_SEE_OTHER: - case HttpStatus.SC_TEMPORARY_REDIRECT: return true; default: return false; Index: httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java =================================================================== --- httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java (revision 792829) +++ httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java (working copy) @@ -68,7 +68,6 @@ import org.apache.http.client.RedirectHandler; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.methods.AbortableHttpRequest; -import org.apache.http.client.methods.HttpGet; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.HttpClientParams; import org.apache.http.client.protocol.ClientContext; @@ -954,9 +953,8 @@ proxyAuthState.invalidate(); } } - - HttpGet redirect = new HttpGet(uri); - + + HttpRedirect redirect = new HttpRedirect(request.getMethod(), uri); HttpRequest orig = request.getOriginal(); redirect.setHeaders(orig.getAllHeaders());