Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x

This commit is contained in:
gregw 2020-07-15 23:38:04 +02:00
commit 7c44d0a01a
5 changed files with 105 additions and 2 deletions

View File

@ -74,6 +74,7 @@
<Set name="httpCompliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="from"><Arg><Property name="jetty.httpConfig.compliance" deprecated="jetty.http.compliance" default="RFC7230"/></Arg></Call></Set>
<Set name="requestCookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.requestCookieCompliance" 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="relativeRedirectAllowed"><Property name="jetty.httpConfig.relativeRedirectAllowed" default="false"/></Set>
</New>
<!-- =========================================================== -->

View File

@ -68,6 +68,9 @@ etc/jetty.xml
## Cookie compliance mode for generating response Set-Cookie: RFC2965, RFC6265
# jetty.httpConfig.responseCookieCompliance=RFC6265
## 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

View File

@ -75,6 +75,7 @@ public class HttpConfiguration implements Dumpable
private CookieCompliance _requestCookieCompliance = CookieCompliance.RFC6265;
private CookieCompliance _responseCookieCompliance = CookieCompliance.RFC6265;
private boolean _notifyRemoteAsyncErrors = true;
private boolean _relativeRedirectAllowed;
/**
* <p>An interface that allows a request object to be customized
@ -143,6 +144,7 @@ public class HttpConfiguration implements Dumpable
_requestCookieCompliance = config._requestCookieCompliance;
_responseCookieCompliance = config._responseCookieCompliance;
_notifyRemoteAsyncErrors = config._notifyRemoteAsyncErrors;
_relativeRedirectAllowed = config._relativeRedirectAllowed;
}
/**
@ -621,6 +623,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()
{
@ -651,7 +670,8 @@ public class HttpConfiguration implements Dumpable
"minResponseDataRate=" + _minResponseDataRate,
"requestCookieCompliance=" + _requestCookieCompliance,
"responseCookieCompliance=" + _responseCookieCompliance,
"notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors
"notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors,
"relativeRedirectAllowed=" + _relativeRedirectAllowed
);
}

View File

@ -504,7 +504,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

View File

@ -1003,6 +1003,83 @@ 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);
HttpURI.Mutable uri = HttpURI.build(request.getHttpURI());
uri.scheme("http");
if (host != null)
uri.authority(host, port);
uri.pathQuery("/path/info;param;jsessionid=12345?query=0&more=1#target");
request.setHttpURI(uri);
request.setContext(null, "/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()
{