From 3cba5377dfdad8c36d1f3b0642f56549821b8676 Mon Sep 17 00:00:00 2001
From: "Shawn O. Pearce" <spearce@spearce.org>
Date: Thu, 13 May 2010 10:23:33 -0700
Subject: [PATCH] Fix hang when fetching over SSH

JSch may hang or abort with the timeout if JGit connects before
its obtained the streams.  Instead defer the connect() call until
after the streams have been configured.

Bug: 312383
Change-Id: I7c3a687ba4cb69a41a85e2b60d381d42b9090e3f
Reported-by: Dmitry Neverov <dmitry.neverov@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../jgit/transport/TransportGitSsh.java        | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
index fb2038b86..d73e2055a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
@@ -147,17 +147,25 @@ private String commandFor(final String exe) {
 	ChannelExec exec(final String exe) throws TransportException {
 		initSession();
 
-		final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0;
 		try {
 			final ChannelExec channel = (ChannelExec) sock.openChannel("exec");
 			channel.setCommand(commandFor(exe));
-			channel.connect(tms);
 			return channel;
 		} catch (JSchException je) {
 			throw new TransportException(uri, je.getMessage(), je);
 		}
 	}
 
+	private void connect(ChannelExec channel) throws TransportException {
+		try {
+			channel.connect(getTimeout() > 0 ? getTimeout() * 1000 : 0);
+			if (!channel.isConnected())
+				throw new TransportException(uri, "connection failed");
+		} catch (JSchException e) {
+			throw new TransportException(uri, e.getMessage(), e);
+		}
+	}
+
 	void checkExecFailure(int status, String exe, String why)
 			throws TransportException {
 		if (status == 127) {
@@ -235,14 +243,13 @@ class SshFetchConnection extends BasePackFetchConnection {
 				setMessageWriter(msg);
 
 				channel = exec(getOptionUploadPack());
-				if (!channel.isConnected())
-					throw new TransportException(uri, "connection failed");
 
 				final InputStream upErr = channel.getErrStream();
 				errorThread = new StreamCopyThread(upErr, msg.getRawStream());
 				errorThread.start();
 
 				init(channel.getInputStream(), outputStream(channel));
+				connect(channel);
 
 			} catch (TransportException err) {
 				close();
@@ -304,14 +311,13 @@ class SshPushConnection extends BasePackPushConnection {
 				setMessageWriter(msg);
 
 				channel = exec(getOptionReceivePack());
-				if (!channel.isConnected())
-					throw new TransportException(uri, "connection failed");
 
 				final InputStream rpErr = channel.getErrStream();
 				errorThread = new StreamCopyThread(rpErr, msg.getRawStream());
 				errorThread.start();
 
 				init(channel.getInputStream(), outputStream(channel));
+				connect(channel);
 
 			} catch (TransportException err) {
 				close();
-- 
GitLab