* 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="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="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="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>
|
</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)
|
## multipart/form-data compliance mode of: LEGACY(slow), RFC7578(fast)
|
||||||
# jetty.httpConfig.multiPartFormDataCompliance=LEGACY
|
# jetty.httpConfig.multiPartFormDataCompliance=LEGACY
|
||||||
|
|
||||||
|
## Relative Redirect Locations allowed
|
||||||
|
# jetty.httpConfig.relativeRedirectAllowed=false
|
||||||
|
|
||||||
### Server configuration
|
### Server configuration
|
||||||
## Whether ctrl+c on the console gracefully stops the Jetty server
|
## Whether ctrl+c on the console gracefully stops the Jetty server
|
||||||
# jetty.server.stopAtShutdown=true
|
# jetty.server.stopAtShutdown=true
|
||||||
|
|
|
@ -76,6 +76,7 @@ public class HttpConfiguration implements Dumpable
|
||||||
private CookieCompliance _responseCookieCompliance = CookieCompliance.RFC6265;
|
private CookieCompliance _responseCookieCompliance = CookieCompliance.RFC6265;
|
||||||
private MultiPartFormDataCompliance _multiPartCompliance = MultiPartFormDataCompliance.LEGACY; // TODO change default in jetty-10
|
private MultiPartFormDataCompliance _multiPartCompliance = MultiPartFormDataCompliance.LEGACY; // TODO change default in jetty-10
|
||||||
private boolean _notifyRemoteAsyncErrors = true;
|
private boolean _notifyRemoteAsyncErrors = true;
|
||||||
|
private boolean _relativeRedirectAllowed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>An interface that allows a request object to be customized
|
* <p>An interface that allows a request object to be customized
|
||||||
|
@ -142,6 +143,7 @@ public class HttpConfiguration implements Dumpable
|
||||||
_responseCookieCompliance = config._responseCookieCompliance;
|
_responseCookieCompliance = config._responseCookieCompliance;
|
||||||
_multiPartCompliance = config._multiPartCompliance;
|
_multiPartCompliance = config._multiPartCompliance;
|
||||||
_notifyRemoteAsyncErrors = config._notifyRemoteAsyncErrors;
|
_notifyRemoteAsyncErrors = config._notifyRemoteAsyncErrors;
|
||||||
|
_relativeRedirectAllowed = config._relativeRedirectAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -642,6 +644,23 @@ public class HttpConfiguration implements Dumpable
|
||||||
return _notifyRemoteAsyncErrors;
|
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
|
@Override
|
||||||
public String dump()
|
public String dump()
|
||||||
{
|
{
|
||||||
|
@ -673,7 +692,8 @@ public class HttpConfiguration implements Dumpable
|
||||||
"minResponseDataRate=" + _minResponseDataRate,
|
"minResponseDataRate=" + _minResponseDataRate,
|
||||||
"cookieCompliance=" + _requestCookieCompliance,
|
"cookieCompliance=" + _requestCookieCompliance,
|
||||||
"setRequestCookieCompliance=" + _responseCookieCompliance,
|
"setRequestCookieCompliance=" + _responseCookieCompliance,
|
||||||
"notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors
|
"notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors,
|
||||||
|
"relativeRedirectAllowed=" + _relativeRedirectAllowed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -506,7 +506,9 @@ public class Response implements HttpServletResponse
|
||||||
|
|
||||||
if (!URIUtil.hasScheme(location))
|
if (!URIUtil.hasScheme(location))
|
||||||
{
|
{
|
||||||
StringBuilder buf = _channel.getRequest().getRootURL();
|
StringBuilder buf = _channel.getHttpConfiguration().isRelativeRedirectAllowed()
|
||||||
|
? new StringBuilder()
|
||||||
|
: _channel.getRequest().getRootURL();
|
||||||
if (location.startsWith("/"))
|
if (location.startsWith("/"))
|
||||||
{
|
{
|
||||||
// absolute in context
|
// 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
|
@Test
|
||||||
public void testInvalidSendRedirect() throws Exception
|
public void testInvalidSendRedirect() throws Exception
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue