FTPConnection.downloadStream can never return
Brought to you by:
arnold_mad,
kurt_tas
If you try to download a file and the server refuses, and exception is raised in FTPConnection.downloadStream.DownStreamingThread.run(), and because the PipedInputStream is never initialised, the client hangs until a timeout.
The following patch catches the exception:
DownStreamingThread thread = new
DownStreamingThread(this, fromFile, pis);
thread.start();
// ensure that in/out pipes are connected already
try {
for(int i=0;
thread.isAlive() && i<60 && pis.available() <= 0;
i++)
Thread.sleep(1000);
}catch(Exception e) {}
Hi
I have made to following changes to 0.7.1 for handling FtpWorkflow and FtpIO expections in the downloadStream functionality:
public InputStream downloadStream(FTPFile fromFile) throws IOException, FtpWorkflowException, FtpIOException {
PipedInputStream pis = new PipedInputStream();
class DownStreamingThread extends Thread {
FTPConnection connection;
FTPFile fromFile;
PipedInputStream pis;
FtpWorkflowException fwException = null;
FtpIOException fioException = null;
IOException ioException = null;
public DownStreamingThread(FTPConnection connection, FTPFile fromFile, PipedInputStream pis) {
super();
this.connection = connection;
this.fromFile = fromFile;
this.pis = pis;
}
public void run() {
// Updated by KMD: YTC - Added exception handling for FtpWorkflow and FtpIO expections
try {
connection.streamFile(fromFile, pis);
} catch (FtpWorkflowException e) {
fwException = e;
} catch (FtpIOException e) {
fioException = e;
} catch (IOException e) {
ioException = e;
}
}
/**
* @return the fwException
*/
public FtpWorkflowException getFwException() {
return fwException;
}
/**
* @return the fioException
*/
public FtpIOException getFioException() {
return fioException;
}
/**
* @return the ioException
*/
public IOException getIoException() {
return ioException;
}
}
DownStreamingThread dst = new DownStreamingThread(this, fromFile, pis);
dst.start();
// ensure that in/out pipes are connected already
try {
for(int i=0; i<60 && pis.available() <= 0; i++) {
Thread.sleep(1000);
// Updated by KMD: YTC - Added exception handling for FtpWorkflow and FtpIO expections
if(dst.getFwException() != null) {
throw dst.getFwException();
} else if(dst.getFioException() != null) {
throw dst.getFioException();
} else if(dst.getIoException() != null) {
throw dst.getIoException();
}
}
} catch(InterruptedException e) {}
return pis;
}
It is not pretty but it serves our purpose well and I hope that someone will implement it or something better.
Regards
Torben
holmbaeck (at) gmail (dot) com