Skip to content

Commit

Permalink
Bug 2194: Support for ProFTPD command OPTS REST STOR to query if uplo…
Browse files Browse the repository at this point in the history
…ad restart is possible

https://winscp.net/tracker/2194

Source commit: 6b8e7e9e8d046a5a45f6ae586cb8ad9d5b61f09a
  • Loading branch information
martinprikryl committed Jun 7, 2023
1 parent cb89d8c commit 1577b39
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
6 changes: 5 additions & 1 deletion source/core/FtpFileSystem.cpp
Expand Up @@ -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;
}

Expand Down
30 changes: 26 additions & 4 deletions source/filezilla/FtpControlSocket.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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
//
Expand Down Expand Up @@ -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)
Expand All @@ -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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
{
Expand Down
1 change: 1 addition & 0 deletions source/filezilla/FtpControlSocket.h
Expand Up @@ -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();
Expand Down

0 comments on commit 1577b39

Please sign in to comment.