summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2019-08-13 23:59:50 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2019-08-16 08:31:59 +0200
commit8c7f1a699a65738220dd08a130295804cad32a32 (patch)
tree05c5e8e219eb025f6f300bbb124e76c61b02af15
parent39e83a6583d6366b65f2356cc80c7cfadb7e051b (diff)
downloadjgit-8c7f1a699a65738220dd08a130295804cad32a32.tar.gz
jgit-8c7f1a699a65738220dd08a130295804cad32a32.zip
TransportHttp: resolve redirect URIs from the "Location" header
The "Location" header in a redirect response may contain a relative URI. Resolve it against the URI the request was made. Bug: 550033 Change-Id: I29de07dfbbbc794090821b7c190cb2cf662c5a60 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java41
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java21
2 files changed, 53 insertions, 9 deletions
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
index 54c1c03b50..32fc677fb5 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
@@ -56,6 +56,7 @@ import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.PrintWriter;
+import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.Arrays;
@@ -340,6 +341,23 @@ public class SmartClientSmartServerTest extends HttpTestCase {
// empty
}
+ private String local(String url, boolean toLocal) {
+ if (!toLocal) {
+ return url;
+ }
+ try {
+ URI u = new URI(url);
+ String fragment = u.getRawFragment();
+ if (fragment != null) {
+ return u.getRawPath() + '#' + fragment;
+ } else {
+ return u.getRawPath();
+ }
+ } catch (URISyntaxException e) {
+ return url;
+ }
+ }
+
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
@@ -352,6 +370,11 @@ public class SmartClientSmartServerTest extends HttpTestCase {
.append(httpServletRequest.getQueryString());
}
String urlString = fullUrl.toString();
+ boolean localRedirect = false;
+ if (urlString.contains("/local")) {
+ urlString = urlString.replace("/local", "");
+ localRedirect = true;
+ }
if (urlString.contains("/loop/")) {
urlString = urlString.replace("/loop/", "/loop/x/");
if (urlString.contains("/loop/x/x/x/x/x/x/x/x/")) {
@@ -362,7 +385,7 @@ public class SmartClientSmartServerTest extends HttpTestCase {
httpServletResponse.setStatus(
HttpServletResponse.SC_MOVED_TEMPORARILY);
httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
- urlString);
+ local(urlString, localRedirect));
return;
}
int responseCode = HttpServletResponse.SC_MOVED_PERMANENTLY;
@@ -392,9 +415,10 @@ public class SmartClientSmartServerTest extends HttpTestCase {
targetContext = matcher.group(1);
}
urlString = urlString.replace("/redirect", targetContext);
+
}
httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
- urlString);
+ local(urlString, localRedirect));
}
@Override
@@ -561,7 +585,15 @@ public class SmartClientSmartServerTest extends HttpTestCase {
private void initialClone_Redirect(int nofRedirects, int code)
throws Exception {
+ initialClone_Redirect(nofRedirects, code, false);
+ }
+
+ private void initialClone_Redirect(int nofRedirects, int code,
+ boolean localRedirect) throws Exception {
URIish cloneFrom = redirectURI;
+ if (localRedirect) {
+ cloneFrom = extendPath(cloneFrom, "/local");
+ }
if (code != 301 || nofRedirects > 1) {
cloneFrom = extendPath(cloneFrom,
"/response/" + nofRedirects + "/" + code);
@@ -615,6 +647,11 @@ public class SmartClientSmartServerTest extends HttpTestCase {
}
@Test
+ public void testInitialClone_Redirect301Local() throws Exception {
+ initialClone_Redirect(1, 301, true);
+ }
+
+ @Test
public void testInitialClone_Redirect302Small() throws Exception {
initialClone_Redirect(1, 302);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index d5b06c1f6d..c523cbf05a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -77,6 +77,7 @@ import java.net.HttpCookie;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.ProxySelector;
+import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.InvalidPathException;
@@ -593,7 +594,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
JGitText.get().redirectsOff,
Integer.valueOf(status)));
}
- URIish newUri = redirect(conn.getHeaderField(HDR_LOCATION),
+ URIish newUri = redirect(u,
+ conn.getHeaderField(HDR_LOCATION),
Constants.INFO_REFS, redirects++);
setURI(newUri);
u = getServiceURL(service);
@@ -804,7 +806,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
}
}
- private URIish redirect(String location, String checkFor, int redirects)
+ private URIish redirect(URL currentUrl, String location, String checkFor,
+ int redirects)
throws TransportException {
if (location == null || location.isEmpty()) {
throw new TransportException(uri,
@@ -818,13 +821,16 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
location));
}
try {
- if (!isValidRedirect(baseUrl, location, checkFor)) {
+ URI redirectTo = new URI(location);
+ redirectTo = currentUrl.toURI().resolve(redirectTo);
+ String redirected = redirectTo.toASCIIString();
+ if (!isValidRedirect(baseUrl, redirected, checkFor)) {
throw new TransportException(uri,
MessageFormat.format(JGitText.get().redirectBlocked,
- baseUrl, location));
+ baseUrl, redirected));
}
- location = location.substring(0, location.indexOf(checkFor));
- URIish result = new URIish(location);
+ redirected = redirected.substring(0, redirected.indexOf(checkFor));
+ URIish result = new URIish(redirected);
if (LOG.isInfoEnabled()) {
LOG.info(MessageFormat.format(JGitText.get().redirectHttp,
uri.setPass(null),
@@ -1454,7 +1460,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
// Let openResponse() issue an error
return;
}
- currentUri = redirect(conn.getHeaderField(HDR_LOCATION),
+ currentUri = redirect(conn.getURL(),
+ conn.getHeaderField(HDR_LOCATION),
'/' + serviceName, redirects++);
try {
baseUrl = toURL(currentUri);