400734 - NPE for redirects with relative location.
Now resolving locations against original URL if it is relative.
This commit is contained in:
parent
12d9d77cd7
commit
dd96cc50b2
|
@ -66,37 +66,48 @@ public class RedirectProtocolHandler extends Response.Listener.Empty implements
|
|||
{
|
||||
Request request = result.getRequest();
|
||||
Response response = result.getResponse();
|
||||
URI location = URI.create(response.getHeaders().get("location"));
|
||||
int status = response.getStatus();
|
||||
switch (status)
|
||||
String location = response.getHeaders().get("location");
|
||||
if (location != null)
|
||||
{
|
||||
case 301:
|
||||
URI newURI = URI.create(location);
|
||||
if (!newURI.isAbsolute())
|
||||
newURI = request.getURI().resolve(newURI);
|
||||
|
||||
int status = response.getStatus();
|
||||
switch (status)
|
||||
{
|
||||
if (request.getMethod() == HttpMethod.GET || request.getMethod() == HttpMethod.HEAD)
|
||||
redirect(result, request.getMethod(), location);
|
||||
else
|
||||
fail(result, new HttpResponseException("HTTP protocol violation: received 301 for non GET or HEAD request", response));
|
||||
break;
|
||||
}
|
||||
case 302:
|
||||
case 303:
|
||||
{
|
||||
// Redirect must be done using GET
|
||||
redirect(result, HttpMethod.GET, location);
|
||||
break;
|
||||
}
|
||||
case 307:
|
||||
{
|
||||
// Keep same method
|
||||
redirect(result, request.getMethod(), location);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fail(result, new HttpResponseException("Unhandled HTTP status code " + status, response));
|
||||
break;
|
||||
case 301:
|
||||
{
|
||||
if (request.getMethod() == HttpMethod.GET || request.getMethod() == HttpMethod.HEAD)
|
||||
redirect(result, request.getMethod(), newURI);
|
||||
else
|
||||
fail(result, new HttpResponseException("HTTP protocol violation: received 301 for non GET or HEAD request", response));
|
||||
break;
|
||||
}
|
||||
case 302:
|
||||
case 303:
|
||||
{
|
||||
// Redirect must be done using GET
|
||||
redirect(result, HttpMethod.GET, newURI);
|
||||
break;
|
||||
}
|
||||
case 307:
|
||||
{
|
||||
// Keep same method
|
||||
redirect(result, request.getMethod(), newURI);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fail(result, new HttpResponseException("Unhandled HTTP status code " + status, response));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fail(result, new HttpResponseException("Missing Location header " + location, response));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -18,13 +18,10 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -42,6 +39,8 @@ import org.junit.Assert;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
||||
{
|
||||
public HttpClientRedirectTest(SslContextFactory sslContextFactory)
|
||||
|
@ -199,6 +198,19 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
Assert.assertTrue(response.getHeaders().containsKey(HttpHeader.LOCATION.asString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelativeLocation() throws Exception
|
||||
{
|
||||
Response response = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.path("/303/localhost/done?relative=true")
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(200, response.getStatus());
|
||||
Assert.assertFalse(response.getHeaders().containsKey(HttpHeader.LOCATION.asString()));
|
||||
}
|
||||
|
||||
private class RedirectHandler extends AbstractHandler
|
||||
{
|
||||
@Override
|
||||
|
@ -212,10 +224,13 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
response.setStatus(status);
|
||||
|
||||
String host = paths[2];
|
||||
response.setHeader("Location", request.getScheme() + "://" + host + ":" + request.getServerPort() + "/" + paths[3]);
|
||||
String path = paths[3];
|
||||
boolean relative = Boolean.parseBoolean(request.getParameter("relative"));
|
||||
String location = relative ? "" : request.getScheme() + "://" + host + ":" + request.getServerPort();
|
||||
location += "/" + path;
|
||||
response.setHeader("Location", location);
|
||||
|
||||
String close = request.getParameter("close");
|
||||
if (Boolean.parseBoolean(close))
|
||||
if (Boolean.parseBoolean(request.getParameter("close")))
|
||||
response.setHeader("Connection", "close");
|
||||
}
|
||||
catch (NumberFormatException x)
|
||||
|
|
Loading…
Reference in New Issue