* Issue #5029 Relative Redirection Provide option to allow relative redirection * Issue #5029 Relative Redirection Fixed checkstyle * rename from review
This commit is contained in:
parent
6b57654b03
commit
5c1dda3f7c
|
@ -74,6 +74,7 @@
|
|||
<Set name="requestCookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.requestCookieCompliance" deprecated="jetty.httpConfig.cookieCompliance" default="RFC6265"/></Arg></Call></Set>
|
||||
<Set name="responseCookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.responseCookieCompliance" default="RFC6265"/></Arg></Call></Set>
|
||||
<Set name="multiPartFormDataCompliance"><Call class="org.eclipse.jetty.server.MultiPartFormDataCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.multiPartFormDataCompliance" default="RFC7578"/></Arg></Call></Set>
|
||||
<Set name="relativeRedirectAllowed"><Property name="jetty.httpConfig.relativeRedirectAllowed" default="false"/></Set>
|
||||
</New>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
|
|
|
@ -72,6 +72,9 @@ patch-module: servlet.api=lib/jetty-schemas-3.1.jar
|
|||
## multipart/form-data compliance mode of: LEGACY(slow), RFC7578(fast)
|
||||
# jetty.httpConfig.multiPartFormDataCompliance=LEGACY
|
||||
|
||||
## Relative Redirect Locations allowed
|
||||
# jetty.httpConfig.relativeRedirectAllowed=false
|
||||
|
||||
### Server configuration
|
||||
## Whether ctrl+c on the console gracefully stops the Jetty server
|
||||
# jetty.server.stopAtShutdown=true
|
||||
|
|
|
@ -76,6 +76,7 @@ public class HttpConfiguration implements Dumpable
|
|||
private CookieCompliance _responseCookieCompliance = CookieCompliance.RFC6265;
|
||||
private MultiPartFormDataCompliance _multiPartCompliance = MultiPartFormDataCompliance.LEGACY; // TODO change default in jetty-10
|
||||
private boolean _notifyRemoteAsyncErrors = true;
|
||||
private boolean _relativeRedirectAllowed;
|
||||
|
||||
/**
|
||||
* <p>An interface that allows a request object to be customized
|
||||
|
@ -142,6 +143,7 @@ public class HttpConfiguration implements Dumpable
|
|||
_responseCookieCompliance = config._responseCookieCompliance;
|
||||
_multiPartCompliance = config._multiPartCompliance;
|
||||
_notifyRemoteAsyncErrors = config._notifyRemoteAsyncErrors;
|
||||
_relativeRedirectAllowed = config._relativeRedirectAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -642,6 +644,23 @@ public class HttpConfiguration implements Dumpable
|
|||
return _notifyRemoteAsyncErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowed True if relative redirection locations are allowed
|
||||
*/
|
||||
public void setRelativeRedirectAllowed(boolean allowed)
|
||||
{
|
||||
_relativeRedirectAllowed = allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if relative redirection locations are allowed
|
||||
*/
|
||||
@ManagedAttribute("Whether relative redirection locations are allowed")
|
||||
public boolean isRelativeRedirectAllowed()
|
||||
{
|
||||
return _relativeRedirectAllowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dump()
|
||||
{
|
||||
|
@ -673,7 +692,8 @@ public class HttpConfiguration implements Dumpable
|
|||
"minResponseDataRate=" + _minResponseDataRate,
|
||||
"cookieCompliance=" + _requestCookieCompliance,
|
||||
"setRequestCookieCompliance=" + _responseCookieCompliance,
|
||||
"notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors
|
||||
"notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors,
|
||||
"relativeRedirectAllowed=" + _relativeRedirectAllowed
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -506,7 +506,9 @@ public class Response implements HttpServletResponse
|
|||
|
||||
if (!URIUtil.hasScheme(location))
|
||||
{
|
||||
StringBuilder buf = _channel.getRequest().getRootURL();
|
||||
StringBuilder buf = _channel.getHttpConfiguration().isRelativeRedirectAllowed()
|
||||
? new StringBuilder()
|
||||
: _channel.getRequest().getRootURL();
|
||||
if (location.startsWith("/"))
|
||||
{
|
||||
// absolute in context
|
||||
|
|
|
@ -858,6 +858,81 @@ public class ResponseTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendRedirectRelative()
|
||||
throws Exception
|
||||
{
|
||||
String[][] tests = {
|
||||
// No cookie
|
||||
{
|
||||
"http://myhost:8888/other/location;jsessionid=12345?name=value",
|
||||
"http://myhost:8888/other/location;jsessionid=12345?name=value"
|
||||
},
|
||||
{"/other/location;jsessionid=12345?name=value", "/other/location;jsessionid=12345?name=value"},
|
||||
{"./location;jsessionid=12345?name=value", "/path/location;jsessionid=12345?name=value"},
|
||||
|
||||
// From cookie
|
||||
{"/other/location", "/other/location"},
|
||||
{"/other/l%20cation", "/other/l%20cation"},
|
||||
{"location", "/path/location"},
|
||||
{"./location", "/path/location"},
|
||||
{"../location", "/location"},
|
||||
{"/other/l%20cation", "/other/l%20cation"},
|
||||
{"l%20cation", "/path/l%20cation"},
|
||||
{"./l%20cation", "/path/l%20cation"},
|
||||
{"../l%20cation", "/l%20cation"},
|
||||
{"../locati%C3%abn", "/locati%C3%abn"},
|
||||
{"../other%2fplace", "/other%2fplace"},
|
||||
{"http://somehost.com/other/location", "http://somehost.com/other/location"},
|
||||
};
|
||||
|
||||
int[] ports = new int[]{8080, 80};
|
||||
String[] hosts = new String[]{null, "myhost", "192.168.0.1", "0::1"};
|
||||
for (int port : ports)
|
||||
{
|
||||
for (String host : hosts)
|
||||
{
|
||||
for (int i = 0; i < tests.length; i++)
|
||||
{
|
||||
// System.err.printf("%s %d %s%n",host,port,tests[i][0]);
|
||||
|
||||
Response response = getResponse();
|
||||
Request request = response.getHttpChannel().getRequest();
|
||||
request.getHttpChannel().getHttpConfiguration().setRelativeRedirectAllowed(true);
|
||||
|
||||
request.setScheme("http");
|
||||
if (host != null)
|
||||
request.setAuthority(host, port);
|
||||
request.setURIPathQuery("/path/info;param;jsessionid=12345?query=0&more=1#target");
|
||||
request.setContextPath("/path");
|
||||
request.setRequestedSessionId("12345");
|
||||
request.setRequestedSessionIdFromCookie(i > 2);
|
||||
SessionHandler handler = new SessionHandler();
|
||||
|
||||
NullSessionDataStore ds = new NullSessionDataStore();
|
||||
DefaultSessionCache ss = new DefaultSessionCache(handler);
|
||||
handler.setSessionCache(ss);
|
||||
ss.setSessionDataStore(ds);
|
||||
DefaultSessionIdManager idMgr = new DefaultSessionIdManager(_server);
|
||||
idMgr.setWorkerName(null);
|
||||
handler.setSessionIdManager(idMgr);
|
||||
request.setSessionHandler(handler);
|
||||
request.setSession(new TestSession(handler, "12345"));
|
||||
handler.setCheckingRemoteSessionIdEncoding(false);
|
||||
|
||||
response.sendRedirect(tests[i][0]);
|
||||
|
||||
String location = response.getHeader("Location");
|
||||
|
||||
String expected = tests[i][1]
|
||||
.replace("@HOST@", host == null ? request.getLocalAddr() : (host.contains(":") ? ("[" + host + "]") : host))
|
||||
.replace("@PORT@", host == null ? ":8888" : (port == 80 ? "" : (":" + port)));
|
||||
assertEquals(expected, location, "test-" + i + " " + host + ":" + port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidSendRedirect() throws Exception
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue