TransportHttp: abort on time-out or on SocketException
Avoid trying other authentication methods on SocketException or on InterruptedIOException. SocketException is rather fatal, such as nothing listening on the peer's port, connection reset, or it could be a connection time-out. Time-outs enforced by Timeout{Input,Output}Stream may result in InterruptedIOException being thrown. In both cases, it makes no sense to try other authentication methods, and doing so may wrongly report "authentication not supported" or "cannot open git-upload-pack" or some such instead of reporting a time-out. Bug: 563138 Change-Id: I0191b1e784c2471035e550205abd06ec9934fd00 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
parent
e2f82d8a7b
commit
bdb7357228
|
@ -112,6 +112,10 @@ public class SmartClientSmartServerTest extends AllFactoriesHttpTestCase {
|
||||||
|
|
||||||
private URIish authOnPostURI;
|
private URIish authOnPostURI;
|
||||||
|
|
||||||
|
private URIish slowURI;
|
||||||
|
|
||||||
|
private URIish slowAuthURI;
|
||||||
|
|
||||||
private RevBlob A_txt;
|
private RevBlob A_txt;
|
||||||
|
|
||||||
private RevCommit A, B, unreachableCommit;
|
private RevCommit A, B, unreachableCommit;
|
||||||
|
@ -152,6 +156,10 @@ public void setUp() throws Exception {
|
||||||
|
|
||||||
ServletContextHandler authOnPost = addAuthContext(gs, "pauth", "POST");
|
ServletContextHandler authOnPost = addAuthContext(gs, "pauth", "POST");
|
||||||
|
|
||||||
|
ServletContextHandler slow = addSlowContext(gs, "slow", false);
|
||||||
|
|
||||||
|
ServletContextHandler slowAuth = addSlowContext(gs, "slowAuth", true);
|
||||||
|
|
||||||
server.setUp();
|
server.setUp();
|
||||||
|
|
||||||
remoteRepository = src.getRepository();
|
remoteRepository = src.getRepository();
|
||||||
|
@ -160,6 +168,8 @@ public void setUp() throws Exception {
|
||||||
redirectURI = toURIish(redirect, srcName);
|
redirectURI = toURIish(redirect, srcName);
|
||||||
authURI = toURIish(auth, srcName);
|
authURI = toURIish(auth, srcName);
|
||||||
authOnPostURI = toURIish(authOnPost, srcName);
|
authOnPostURI = toURIish(authOnPost, srcName);
|
||||||
|
slowURI = toURIish(slow, srcName);
|
||||||
|
slowAuthURI = toURIish(slowAuth, srcName);
|
||||||
|
|
||||||
A_txt = src.blob("A");
|
A_txt = src.blob("A");
|
||||||
A = src.commit().add("A_txt", A_txt).create();
|
A = src.commit().add("A_txt", A_txt).create();
|
||||||
|
@ -372,6 +382,43 @@ public void destroy() {
|
||||||
return redirect;
|
return redirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ServletContextHandler addSlowContext(GitServlet gs, String path,
|
||||||
|
boolean auth) {
|
||||||
|
ServletContextHandler slow = server.addContext('/' + path);
|
||||||
|
slow.addFilter(new FilterHolder(new Filter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig)
|
||||||
|
throws ServletException {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simply delays the servlet for two seconds. Used for timeout
|
||||||
|
// tests, which use a one-second timeout.
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request,
|
||||||
|
ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
}), "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||||
|
slow.addServlet(new ServletHolder(gs), "/*");
|
||||||
|
if (auth) {
|
||||||
|
return server.authBasic(slow);
|
||||||
|
}
|
||||||
|
return slow;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListRemote() throws IOException {
|
public void testListRemote() throws IOException {
|
||||||
assertEquals("http", remoteURI.getScheme());
|
assertEquals("http", remoteURI.getScheme());
|
||||||
|
@ -488,6 +535,35 @@ protected Map<String, Ref> getAdvertisedRefs(Repository repository,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeoutExpired() throws Exception {
|
||||||
|
try (Repository dst = createBareRepository();
|
||||||
|
Transport t = Transport.open(dst, slowURI)) {
|
||||||
|
t.setTimeout(1);
|
||||||
|
TransportException expected = assertThrows(TransportException.class,
|
||||||
|
() -> t.fetch(NullProgressMonitor.INSTANCE,
|
||||||
|
mirror(master)));
|
||||||
|
assertTrue("Unexpected exception message: " + expected.toString(),
|
||||||
|
expected.getMessage().contains("time"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeoutExpiredWithAuth() throws Exception {
|
||||||
|
try (Repository dst = createBareRepository();
|
||||||
|
Transport t = Transport.open(dst, slowAuthURI)) {
|
||||||
|
t.setTimeout(1);
|
||||||
|
t.setCredentialsProvider(testCredentials);
|
||||||
|
TransportException expected = assertThrows(TransportException.class,
|
||||||
|
() -> t.fetch(NullProgressMonitor.INSTANCE,
|
||||||
|
mirror(master)));
|
||||||
|
assertTrue("Unexpected exception message: " + expected.toString(),
|
||||||
|
expected.getMessage().contains("time"));
|
||||||
|
assertFalse("Unexpected exception message: " + expected.toString(),
|
||||||
|
expected.getMessage().contains("auth"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInitialClone_Small() throws Exception {
|
public void testInitialClone_Small() throws Exception {
|
||||||
try (Repository dst = createBareRepository();
|
try (Repository dst = createBareRepository();
|
||||||
|
|
|
@ -39,11 +39,13 @@
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.InterruptedIOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpCookie;
|
import java.net.HttpCookie;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.ProxySelector;
|
import java.net.ProxySelector;
|
||||||
|
import java.net.SocketException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -573,6 +575,14 @@ private HttpConnection connect(String service)
|
||||||
}
|
}
|
||||||
} catch (NotSupportedException | TransportException e) {
|
} catch (NotSupportedException | TransportException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
} catch (InterruptedIOException e) {
|
||||||
|
// Timeout!? Don't try other authentication methods.
|
||||||
|
throw new TransportException(uri, MessageFormat.format(
|
||||||
|
JGitText.get().connectionTimeOut, u.getHost()), e);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
// Nothing on other end, timeout, connection reset, ...
|
||||||
|
throw new TransportException(uri,
|
||||||
|
JGitText.get().connectionFailed, e);
|
||||||
} catch (SSLHandshakeException e) {
|
} catch (SSLHandshakeException e) {
|
||||||
handleSslFailure(e);
|
handleSslFailure(e);
|
||||||
continue; // Re-try
|
continue; // Re-try
|
||||||
|
@ -1501,6 +1511,10 @@ void sendRequest() throws IOException {
|
||||||
} catch (SSLHandshakeException e) {
|
} catch (SSLHandshakeException e) {
|
||||||
handleSslFailure(e);
|
handleSslFailure(e);
|
||||||
continue; // Re-try
|
continue; // Re-try
|
||||||
|
} catch (SocketException | InterruptedIOException e) {
|
||||||
|
// Timeout!? Must propagate; don't try other authentication
|
||||||
|
// methods.
|
||||||
|
throw e;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (authenticator == null || authMethod
|
if (authenticator == null || authMethod
|
||||||
.getType() != HttpAuthMethod.Type.NONE) {
|
.getType() != HttpAuthMethod.Type.NONE) {
|
||||||
|
|
Loading…
Reference in New Issue