From 4846d9393d5dcd6993bbff9ec3f85ed813911e21 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 15 Jan 2019 17:32:14 +0000 Subject: [PATCH] ftp: wait for 60 seconds for connection Close then declare it dead This helps with indefinite hangs when transferring very large files on some ftp server. Fixes #2912 --- backend/ftp/ftp.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/ftp/ftp.go b/backend/ftp/ftp.go index fafe6b702..fafe7bc53 100644 --- a/backend/ftp/ftp.go +++ b/backend/ftp/ftp.go @@ -646,7 +646,21 @@ func (f *ftpReadCloser) Read(p []byte) (n int, err error) { // Close the FTP reader and return the connection to the pool func (f *ftpReadCloser) Close() error { - err := f.rc.Close() + var err error + errchan := make(chan error, 1) + go func() { + errchan <- f.rc.Close() + }() + // Wait for Close for up to 60 seconds + timer := time.NewTimer(60 * time.Second) + select { + case err = <-errchan: + timer.Stop() + case <-timer.C: + // if timer fired assume no error but connection dead + fs.Errorf(f.f, "Timeout when waiting for connection Close") + return nil + } // if errors while reading or closing, dump the connection if err != nil || f.err != nil { _ = f.c.Quit()