@NotNull private Map<String, Ref> getRemoteRefs(@NotNull Repository db, @NotNull GitVcsRoot gitRoot) throws Exception { long retryInterval = myConfig.getConnectionRetryIntervalMillis(); int attemptsLeft = myConfig.getConnectionRetryAttempts(); while (true) { final long start = System.currentTimeMillis(); Transport transport = null; FetchConnection connection = null; try { transport = myTransportFactory.createTransport( db, gitRoot.getRepositoryFetchURL(), gitRoot.getAuthSettings()); connection = transport.openFetch(); return connection.getRefsMap(); } catch (NotSupportedException nse) { throw friendlyNotSupportedException(gitRoot, nse); } catch (TransportException te) { attemptsLeft--; if (isRecoverable(te) && attemptsLeft > 0) { LOG.warn( "List remote refs failed: " + te.getMessage() + ", " + attemptsLeft + " attempt(s) left"); } else { throw friendlyTransportException(te, gitRoot); } } catch (WrongPassphraseException e) { throw new VcsException(e.getMessage(), e); } finally { if (connection != null) connection.close(); if (transport != null) transport.close(); final long finish = System.currentTimeMillis(); PERFORMANCE_LOG.debug( "[getRemoteRefs] repository: " + LogUtil.describe(gitRoot) + ", took " + (finish - start) + "ms"); } Thread.sleep(retryInterval); retryInterval *= 2; } }
private boolean isRecoverable(@NotNull TransportException e) { String message = e.getMessage(); if (message == null) return false; if (message.contains("Connection timed out") || message.contains("Connection time out")) { return true; } Throwable cause = e.getCause(); if (cause instanceof JSchException) { return message.contains("Session.connect: java.net.SocketException: Connection reset") || message.contains( "Session.connect: java.net.SocketException: Software caused connection abort") || message.contains("connection is closed by foreign host") || message.contains("java.net.UnknownHostException:") || // TW-31027 message.contains("com.jcraft.jsch.JSchException: verify: false"); // TW-31175 } return false; }
@Test public void testListRemote_Smart_UploadPackNeedsAuth() throws Exception { Repository dst = createBareRepository(); Transport t = Transport.open(dst, smartAuthBasicURI); try { try { t.openFetch(); fail("connection opened even though service disabled"); } catch (TransportException err) { String exp = smartAuthBasicURI + ": " + JGitText.get().notAuthorized; assertEquals(exp, err.getMessage()); } } finally { t.close(); } }
@Test public void testListRemote_Dumb_NeedsAuth() throws Exception { Repository dst = createBareRepository(); Transport t = Transport.open(dst, dumbAuthBasicURI); try { try { t.openFetch(); fail("connection opened even info/refs needs auth basic"); } catch (TransportException err) { String exp = dumbAuthBasicURI + ": " + JGitText.get().notAuthorized; assertEquals(exp, err.getMessage()); } } finally { t.close(); } }
@Test public void testListRemote_Smart_UploadPackDisabled() throws Exception { FileRepository src = remoteRepository.getRepository(); final FileBasedConfig cfg = src.getConfig(); cfg.setBoolean("http", null, "uploadpack", false); cfg.save(); Repository dst = createBareRepository(); Transport t = Transport.open(dst, smartAuthNoneURI); try { try { t.openFetch(); fail("connection opened even though service disabled"); } catch (TransportException err) { String exp = smartAuthNoneURI + ": git-upload-pack not permitted"; assertEquals(exp, err.getMessage()); } } finally { t.close(); } }
@Test public void testListRemote_Dumb_Auth() throws Exception { Repository dst = createBareRepository(); Transport t = Transport.open(dst, dumbAuthBasicURI); t.setCredentialsProvider( new UsernamePasswordCredentialsProvider(AppServer.username, AppServer.password)); try { t.openFetch(); } finally { t.close(); } t = Transport.open(dst, dumbAuthBasicURI); t.setCredentialsProvider(new UsernamePasswordCredentialsProvider(AppServer.username, "")); try { t.openFetch(); fail("connection opened even info/refs needs auth basic and we provide wrong password"); } catch (TransportException err) { String exp = dumbAuthBasicURI + ": " + JGitText.get().notAuthorized; assertEquals(exp, err.getMessage()); } finally { t.close(); } }