Fix canonical URL detection with URL encoded parts

getServletPath() returns a URL-decoded path while getRequestURL()
just returns the string as-is, creating an incorrect canonical URL
detection because of different URL parts lengths of encoded vs. decoded.

That problem arises when gerrit.canonicalWebUrl is empty and the
canonical URL is obtained by checking the request URL minus the Servlet
request Path.

Apply the URL decoding before trimming the request URL by the Servlet
path length, so that canonical URL can be reliable even when the request
URL contains URL-encoded fragments.

Example: the new UI login link includes the following URL-encoded
search URL (/q/status:open) which was causing an incorrect canonical
URL detection and consequently the inability to log in from PolyGerrit.

Bug: Issue 7036
Change-Id: Ibaadeb8b9a377dc1427d33d339a50a58e79012cf
This commit is contained in:
Luca Milanesio 2017-08-14 09:08:10 +01:00
parent f083894881
commit 8301cd8c98

View File

@ -14,9 +14,13 @@
package com.google.gerrit.httpd;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.gerrit.common.Nullable;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
public class CanonicalWebUrl {
@ -35,10 +39,15 @@ public class CanonicalWebUrl {
static String computeFromRequest(HttpServletRequest req) {
StringBuffer url = req.getRequestURL();
url.setLength(url.length() - req.getServletPath().length());
if (url.charAt(url.length() - 1) != '/') {
url.append('/');
try {
url = new StringBuffer(URLDecoder.decode(url.toString(), UTF_8.name()));
url.setLength(url.length() - req.getServletPath().length());
if (url.charAt(url.length() - 1) != '/') {
url.append('/');
}
return url.toString();
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Unsupported encoding for request URL " + url, e);
}
return url.toString();
}
}