Forráskód Böngészése

Bug 2194: Support for ProFTPD command OPTS REST STOR to query if upload restart is possible

https://winscp.net/tracker/2194

Source commit: 6b8e7e9e8d046a5a45f6ae586cb8ad9d5b61f09a
Martin Prikryl 2 éve
szülő
commit
1577b39b76

+ 5 - 1
source/core/FtpFileSystem.cpp

@@ -1455,7 +1455,11 @@ void __fastcall TFTPFileSystem::DoFileTransferProgress(__int64 TransferSize,
 
   if (FFileTransferResumed > 0)
   {
-    OperationProgress->AddResumed(FFileTransferResumed);
+    // Bytes will be 0, if resume was not possible
+    if (Bytes >= FFileTransferResumed)
+    {
+      OperationProgress->AddResumed(FFileTransferResumed);
+    }
     FFileTransferResumed = 0;
   }
 

+ 26 - 4
source/filezilla/FtpControlSocket.cpp

@@ -2684,6 +2684,12 @@ int CFtpControlSocket::ActivateTransferSocket(CFileTransferData * pData)
   return nReplyError;
 }
 
+void CFtpControlSocket::CancelTransferResume(CFileTransferData * pData)
+{
+  pData->transferdata.transferleft = pData->transferdata.transfersize;
+  pData->transferdata.bResume = FALSE;
+}
+
 void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFinish/*=FALSE*/,int nError/*=0*/)
 {
   USES_CONVERSION;
@@ -2713,6 +2719,10 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
   #define FILETRANSFER_WAIT      20
 
   #define FILETRANSFER_MFMT      21
+  #define FILETRANSFER_OPTS_REST 22
+
+  #define FILETRANSFER_OPTION_COMMAND_2 (NeedOptsCommand() ? FILETRANSFER_OPTS : FILETRANSFER_PORTPASV)
+  #define FILETRANSFER_OPTION_COMMAND_1 (NeedModeCommand() ? FILETRANSFER_MODE : FILETRANSFER_OPTION_COMMAND_2)
 
   //Partial flowchart of FileTransfer
   //
@@ -3444,7 +3454,7 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
     case FILETRANSFER_TYPE:
       if (code!=2 && code!=3)
         nReplyError = FZ_REPLY_ERROR;
-      m_Operation.nOpState = NeedModeCommand() ? FILETRANSFER_MODE : (NeedOptsCommand() ? FILETRANSFER_OPTS : FILETRANSFER_PORTPASV);
+      m_Operation.nOpState = !pData->transferfile.get && pData->transferdata.bResume ? FILETRANSFER_OPTS_REST : FILETRANSFER_OPTION_COMMAND_1;
       break;
     case FILETRANSFER_WAIT:
       if (!pData->nWaitNextOpState)
@@ -3459,7 +3469,7 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
 #else
       if (code == 2 || code == 3)
         m_useZlib = !m_useZlib;
-      m_Operation.nOpState = NeedOptsCommand() ? FILETRANSFER_OPTS : FILETRANSFER_PORTPASV;
+      m_Operation.nOpState = FILETRANSFER_OPTION_COMMAND_2;
 #endif
       break;
     case FILETRANSFER_OPTS:
@@ -3680,6 +3690,15 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
         else
           nReplyError = FZ_REPLY_ERROR;
       break;
+    case FILETRANSFER_OPTS_REST:
+      // anything else means the resume is allowed (2xx) or the server does not understand OPTS REST STOR (5xx)
+      if (code == 4)
+      {
+        ShowStatus(L"Resume not allowed by the server, restarting upload from the scratch.", FZ_LOG_PROGRESS);
+        CancelTransferResume(pData);
+      }
+      m_Operation.nOpState = FILETRANSFER_OPTION_COMMAND_1;
+      break;
     case FILETRANSFER_REST:
       { //Resume
         if (code==3 || code==2)
@@ -3719,8 +3738,7 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
               }
 
               ShowStatus(IDS_ERRORMSG_CANTRESUME, FZ_LOG_ERROR);
-              pData->transferdata.transferleft=pData->transferdata.transfersize;
-              pData->transferdata.bResume=FALSE;
+              CancelTransferResume(pData);
               m_Operation.nOpState=FILETRANSFER_RETRSTOR;
             }
             else
@@ -4325,6 +4343,10 @@ void CFtpControlSocket::FileTransfer(t_transferfile *transferfile/*=0*/,BOOL bFi
       }
     }
     break;
+  case FILETRANSFER_OPTS_REST:
+    if (!Send(L"OPTS REST STOR"))
+      bError = TRUE;
+    break;
   case FILETRANSFER_REST:
     DebugAssert(m_pDataFile);
     {

+ 1 - 0
source/filezilla/FtpControlSocket.h

@@ -120,6 +120,7 @@ protected:
   void ResetTransferSocket(int Error);
   int OpenTransferFile(CFileTransferData * pData);
   int ActivateTransferSocket(CFileTransferData * pData);
+  void CancelTransferResume(CFileTransferData * pData);
 
   void DoClose(int nError = 0);
   int TryGetReplyCode();