QFtp - implement fast abort for downloads
authorShane Kearns <ext-shane.2.kearns@nokia.com>
Wed, 25 Apr 2012 14:53:23 +0000 (15:53 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 3 May 2012 04:10:02 +0000 (06:10 +0200)
Most FTP servers do not support the ABOR command (they don't process
control channel traffic until the data channel is finished). Or they
require the telnet IP & sync procedure on the control channel (this
requires sending TCP urgent data, which we do not support).
Following behaviour of most browsers and GUI FTP clients, abort
downloads by resetting the data channel.
Abort of uploads needs no change, because the client closes the data
channel rather than the server.

Task-number: QTBUG-25494
Change-Id: I69e7b7c04d709d26def9a4a7081074e1cbf69701
Reviewed-by: Martin Petersson <Martin.Petersson@nokia.com>
src/network/access/qftp.cpp

index c7ad810..a504157 100644 (file)
@@ -665,7 +665,7 @@ void QFtpDTP::socketReadyRead()
         return;
     }
 
-    if (pi->abortState == QFtpPI::AbortStarted) {
+    if (pi->abortState != QFtpPI::None) {
         // discard data
         socket->readAll();
         return;
@@ -865,14 +865,25 @@ void QFtpPI::abort()
         // ABOR already sent
         return;
 
-    abortState = AbortStarted;
+    if (currentCmd.isEmpty())
+        return; //no command in progress
+
+    if (currentCmd.startsWith(QLatin1String("STOR "))) {
+        abortState = AbortStarted;
 #if defined(QFTPPI_DEBUG)
-    qDebug("QFtpPI send: ABOR");
+        qDebug("QFtpPI send: ABOR");
 #endif
-    commandSocket.write("ABOR\r\n", 6);
+        commandSocket.write("ABOR\r\n", 6);
 
-    if (currentCmd.startsWith(QLatin1String("STOR ")))
         dtp.abortConnection();
+    } else {
+        //Deviation from RFC 959:
+        //Most FTP servers do not support ABOR, or require the telnet
+        //IP & synch sequence (TCP urgent data) which is not supported by QTcpSocket.
+        //Following what most FTP clients do, just reset the data connection and wait for 426
+        abortState = WaitForAbortToFinish;
+        dtp.abortConnection();
+    }
 }
 
 void QFtpPI::hostFound()