diff --git a/source/core/FtpFileSystem.cpp b/source/core/FtpFileSystem.cpp index 466a457ed..b923be022 100644 --- a/source/core/FtpFileSystem.cpp +++ b/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; } diff --git a/source/filezilla/FtpControlSocket.cpp b/source/filezilla/FtpControlSocket.cpp index 5bd34c9c9..ce3bdffa2 100644 --- a/source/filezilla/FtpControlSocket.cpp +++ b/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); { diff --git a/source/filezilla/FtpControlSocket.h b/source/filezilla/FtpControlSocket.h index 97dbb29a4..103e20a98 100644 --- a/source/filezilla/FtpControlSocket.h +++ b/source/filezilla/FtpControlSocket.h @@ -120,6 +120,7 @@ class CFtpControlSocket : public CAsyncSocketEx, public CApiLog void ResetTransferSocket(int Error); int OpenTransferFile(CFileTransferData * pData); int ActivateTransferSocket(CFileTransferData * pData); + void CancelTransferResume(CFileTransferData * pData); void DoClose(int nError = 0); int TryGetReplyCode();