Browse Source

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>
tags/v0.8.1
Shawn O. Pearce 14 years ago
parent
commit
3cba5377df

+ 12
- 6
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java View File

ChannelExec exec(final String exe) throws TransportException { ChannelExec exec(final String exe) throws TransportException {
initSession(); initSession();


final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0;
try { try {
final ChannelExec channel = (ChannelExec) sock.openChannel("exec"); final ChannelExec channel = (ChannelExec) sock.openChannel("exec");
channel.setCommand(commandFor(exe)); channel.setCommand(commandFor(exe));
channel.connect(tms);
return channel; return channel;
} catch (JSchException je) { } catch (JSchException je) {
throw new TransportException(uri, je.getMessage(), 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) void checkExecFailure(int status, String exe, String why)
throws TransportException { throws TransportException {
if (status == 127) { if (status == 127) {
setMessageWriter(msg); setMessageWriter(msg);


channel = exec(getOptionUploadPack()); channel = exec(getOptionUploadPack());
if (!channel.isConnected())
throw new TransportException(uri, "connection failed");


final InputStream upErr = channel.getErrStream(); final InputStream upErr = channel.getErrStream();
errorThread = new StreamCopyThread(upErr, msg.getRawStream()); errorThread = new StreamCopyThread(upErr, msg.getRawStream());
errorThread.start(); errorThread.start();


init(channel.getInputStream(), outputStream(channel)); init(channel.getInputStream(), outputStream(channel));
connect(channel);


} catch (TransportException err) { } catch (TransportException err) {
close(); close();
setMessageWriter(msg); setMessageWriter(msg);


channel = exec(getOptionReceivePack()); channel = exec(getOptionReceivePack());
if (!channel.isConnected())
throw new TransportException(uri, "connection failed");


final InputStream rpErr = channel.getErrStream(); final InputStream rpErr = channel.getErrStream();
errorThread = new StreamCopyThread(rpErr, msg.getRawStream()); errorThread = new StreamCopyThread(rpErr, msg.getRawStream());
errorThread.start(); errorThread.start();


init(channel.getInputStream(), outputStream(channel)); init(channel.getInputStream(), outputStream(channel));
connect(channel);


} catch (TransportException err) { } catch (TransportException err) {
close(); close();

Loading…
Cancel
Save