Ticket #1519: filezilla3_rc1_keepalive2.patch

File filezilla3_rc1_keepalive2.patch, 11.4 KB (added by tommywu, 13 years ago)

keepalive version 2

  • src/engine/ControlSocket.h

    diff -Nur Filezilla3/src/engine/ControlSocket.h Filezilla3.patch/src/engine/ControlSocket.h
    old new  
    115115    virtual int Chmod(const CChmodCommand& command) { return FZ_REPLY_NOTSUPPORTED; }
    116116    virtual bool Connected() const = 0;
    117117
     118    virtual int KeepAlive(const CKeepAliveCommand& command) { return FZ_REPLY_OK; }
     119
    118120    // If m_pCurrentOpData is zero, this function returns the current command
    119121    // from the engine.
    120122    enum Command GetCurrentCommandId() const;
  • src/engine/FileZillaEngine.cpp

    diff -Nur Filezilla3/src/engine/FileZillaEngine.cpp Filezilla3.patch/src/engine/FileZillaEngine.cpp
    old new  
    7070    case cmd_chmod:
    7171        res = Chmod(reinterpret_cast<const CChmodCommand&>(command));
    7272        break;
     73    case cmd_keepalive:
     74        res = KeepAlive(reinterpret_cast<const CKeepAliveCommand &>(command));
     75        break;
    7376    default:
    7477        return FZ_REPLY_SYNTAXERROR;
    7578    }
  • src/engine/commands.cpp

    diff -Nur Filezilla3/src/engine/commands.cpp Filezilla3.patch/src/engine/commands.cpp
    old new  
    1010    return m_Server;
    1111}
    1212
     13CKeepAliveCommand::CKeepAliveCommand(bool keepAlive /*=true*/)
     14    : m_keepAlive(keepAlive)
     15{
     16}
     17
     18bool CKeepAliveCommand::IsKeepAlive() const
     19{
     20    return m_keepAlive;
     21}
     22
    1323CListCommand::CListCommand(bool refresh /*=false*/)
    1424    : m_refresh(refresh)
    1525{
  • src/engine/engineprivate.cpp

    diff -Nur Filezilla3/src/engine/engineprivate.cpp Filezilla3.patch/src/engine/engineprivate.cpp
    old new  
    525525    return m_pControlSocket->Chmod(command);
    526526}
    527527
     528int CFileZillaEnginePrivate::KeepAlive(const CKeepAliveCommand& command)
     529{
     530    m_pCurrentCommand = command.Clone();
     531    return m_pControlSocket->KeepAlive(command);
     532}
     533
    528534void CFileZillaEnginePrivate::SendDirectoryListingNotification(const CServerPath& path, bool onList, bool modified, bool failed)
    529535{
    530536    wxASSERT(m_pControlSocket);
  • src/engine/ftpcontrolsocket.cpp

    diff -Nur Filezilla3/src/engine/ftpcontrolsocket.cpp Filezilla3.patch/src/engine/ftpcontrolsocket.cpp
    old new  
    2424#define LOGON_CUSTOMCOMMANDS 10
    2525#define LOGON_DONE      11
    2626
     27#define KEEPALIVE_TIMER_ID wxID_HIGHEST + 5
     28
    2729BEGIN_EVENT_TABLE(CFtpControlSocket, CRealControlSocket)
    2830EVT_FZ_EXTERNALIPRESOLVE(wxID_ANY, CFtpControlSocket::OnExternalIPAddress)
     31EVT_TIMER(wxID_ANY, CFtpControlSocket::OnTimer)
    2932END_EVENT_TABLE();
    3033
    3134CRawTransferOpData::CRawTransferOpData()
     
    137140    m_pTlsSocket = 0;
    138141    m_protectDataChannel = false;
    139142    m_lastTypeBinary = -1;
     143    m_bEnableKeepAlive = false;
     144    m_keepAliveTimer.SetOwner(this, KEEPALIVE_TIMER_ID);
    140145}
    141146
    142147CFtpControlSocket::~CFtpControlSocket()
     
    147152{
    148153    LogMessage(Debug_Verbose, _T("CFtpControlSocket::OnReceive()"));
    149154
     155    m_keepAliveStopWatch.Start();
     156
    150157    m_pBackend->Read(m_receiveBuffer + m_bufferLen, RECVBUFFERSIZE - m_bufferLen);
    151158   
    152159    if (m_pBackend->Error())
    153160    {
    154161        if (m_pBackend->LastError() != wxSOCKET_WOULDBLOCK)
    155162        {
     163            m_bEnableKeepAlive = false;
     164            m_keepAliveTimer.Stop();
    156165            LogMessage(::Error, _("Disconnected from server"));
    157166            DoClose();
    158167        }
     
    386395    case cmd_rawtransfer:
    387396        TransferParseResponse();
    388397        break;
     398    case cmd_keepalive:
     399        KeepAliveParseResponse();
     400        break;
    389401    case cmd_none:
    390402        LogMessage(Debug_Verbose, _T("Out-of-order reply, ignoring."));
    391403        break;
     
    798810        LogMessage(::Error, _T("Failed to convert command to 8 bit charset"));
    799811        return false;
    800812    }
     813    m_keepAliveStopWatch.Start();
    801814    unsigned int len = (unsigned int)strlen(buffer);
    802815    bool res = CRealControlSocket::Send(buffer, len);
    803816    if (res)
     
    12541267        return DeleteSend(prevResult);
    12551268    case cmd_removedir:
    12561269        return RemoveDirSend(prevResult);
     1270    case cmd_keepalive:
     1271        return KeepAliveSend();
    12571272    default:
    12581273        LogMessage(__TFILE__, __LINE__, this, ::Debug_Warning, _T("Unknown opID (%d) in SendNextCommand"), m_pCurOpData->opId);
    12591274        ResetOperation(FZ_REPLY_INTERNALERROR);
     
    30063021    }
    30073022
    30083023    return FZ_REPLY_WOULDBLOCK;
     3024}
     3025
     3026class CKeepAliveOpData : public COpData
     3027{
     3028public:
     3029    CKeepAliveOpData(const wxString& command)
     3030        : COpData(cmd_keepalive)
     3031    {
     3032        m_command = command;
     3033    }
     3034
     3035    wxString m_command;
     3036};
     3037
     3038int CFtpControlSocket::KeepAlive(const CKeepAliveCommand& command)
     3039{
     3040    LogMessage(Debug_Verbose, _T("CFtpControlSocket::KeepAlive"));
     3041
     3042    if (command.IsKeepAlive())
     3043    {
     3044        if (!m_bEnableKeepAlive)
     3045        {
     3046            m_bEnableKeepAlive = true;
     3047            // FIXME:
     3048            // read keepalive option here
     3049            int min_wait = 30;
     3050            int max_wait = 60;
     3051            int waitsecond = min_wait + (int)(rand()*(max_wait - min_wait)/(RAND_MAX+1));
     3052            m_keepAliveTimer.Start(waitsecond * 1000);
     3053        }
     3054    }
     3055    else
     3056    {
     3057        if (m_bEnableKeepAlive)
     3058        {
     3059            m_bEnableKeepAlive = false;
     3060            m_keepAliveTimer.Stop();
     3061        }
     3062    }
     3063
     3064    m_bEnableKeepAlive = true;
     3065    return FZ_REPLY_OK;
     3066}
     3067
     3068int CFtpControlSocket::DoKeepAlive()
     3069{
     3070    LogMessage(Debug_Verbose, _T("CFtpControlSocket::DoKeepAlive"));
     3071
     3072    // ignore keepalive for last I/O for socket less than 15 seconds
     3073    if (m_keepAliveStopWatch.Time() < 15000)
     3074        return FZ_REPLY_OK;
     3075    // choose any command
     3076    wxString commands[6] = {_T("PWD"),_T("REST 0"), _T("NOOP"), _T("STAT"), _T("RMD"), _T("MKD") };
     3077    int choice=(rand()*6)/(RAND_MAX+1);
     3078    m_pCurOpData = new CKeepAliveOpData(commands[choice]);
     3079
     3080    return SendNextCommand();
     3081}
     3082
     3083int CFtpControlSocket::KeepAliveSend()
     3084{
     3085    LogMessage(Debug_Verbose, _T("CFtpControlSocket::KeepAliveSend"));
     3086
     3087    if (!m_pCurOpData)
     3088    {
     3089        LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("Empty m_pCurOpData"));
     3090        ResetOperation(FZ_REPLY_INTERNALERROR);
     3091        return FZ_REPLY_ERROR;
     3092    }
     3093
     3094    CDirectoryCache cache;
     3095    cache.InvalidateServer(*m_pCurrentServer);
     3096    m_CurrentPath = CServerPath();
     3097
     3098    CKeepAliveOpData *pData = static_cast<CKeepAliveOpData *>(m_pCurOpData);
     3099
     3100    if (!Send(pData->m_command))
     3101        return FZ_REPLY_ERROR;
     3102
     3103    return FZ_REPLY_WOULDBLOCK;
     3104}
     3105
     3106int CFtpControlSocket::KeepAliveParseResponse()
     3107{
     3108    LogMessage(Debug_Verbose, _T("CFtpControlSocket::KeepAliveParseResponse"));
     3109
     3110    int code = GetReplyCode();
     3111    if (code == 2 || code == 3 || code == 5)
     3112    {
     3113        ResetOperation(FZ_REPLY_OK);
     3114        return FZ_REPLY_OK;
     3115    }
     3116    else
     3117    {
     3118        ResetOperation(FZ_REPLY_ERROR);
     3119        return FZ_REPLY_ERROR;
     3120    }
     3121}
     3122
     3123void CFtpControlSocket::OnTimer(wxTimerEvent& event)
     3124{
     3125    if (event.GetId() == KEEPALIVE_TIMER_ID)
     3126    {
     3127        if (m_keepAliveTimer.IsRunning())
     3128        {
     3129            m_keepAliveTimer.Stop();
     3130            if (m_bEnableKeepAlive) {
     3131                // FIXME:
     3132                // need to read the values from options...
     3133                int min_wait = 30;
     3134                int max_wait = 60;
     3135
     3136                int waitsecond = min_wait + (int)(rand()*(max_wait - min_wait)/(RAND_MAX+1));
     3137                m_keepAliveTimer.Start(waitsecond * 1000);
     3138                DoKeepAlive();
     3139            }
     3140        }
     3141    }
     3142    else
     3143        CControlSocket::OnTimer(event);
    30093144}
    30103145
    30113146bool CFtpControlSocket::IsMisleadingListResponse() const
  • src/engine/ftpcontrolsocket.h

    diff -Nur Filezilla3/src/engine/ftpcontrolsocket.h Filezilla3.patch/src/engine/ftpcontrolsocket.h
    old new  
    2424
    2525protected:
    2626   
     27    bool m_bEnableKeepAlive;
     28    wxTimer m_keepAliveTimer;
     29    wxStopWatch m_keepAliveStopWatch;
     30    virtual int KeepAlive(const CKeepAliveCommand& command);
     31    int DoKeepAlive();
     32    int KeepAliveParseResponse();
     33    int KeepAliveSend();
     34
    2735    virtual int ResetOperation(int nErrorCode);
    2836
    2937    virtual int Connect(const CServer &server);
     
    128136
    129137    DECLARE_EVENT_TABLE();
    130138    void OnExternalIPAddress(fzExternalIPResolveEvent& event);
     139    void OnTimer(wxTimerEvent& event);
    131140};
    132141
    133142class CIOThread;
  • src/include/commands.h

    diff -Nur Filezilla3/src/include/commands.h Filezilla3.patch/src/include/commands.h
    old new  
    1919    cmd_rename,
    2020    cmd_chmod,
    2121    cmd_raw,
     22    cmd_keepalive,
    2223
    2324    // Only used internally
    2425    cmd_cwd,
     
    7475    const CServer GetServer() const;
    7576protected:
    7677    CServer m_Server;
     78};
     79
     80DECLARE_COMMAND(CKeepAliveCommand, cmd_keepalive)
     81    CKeepAliveCommand(bool keepAlive = true);
     82
     83    bool IsKeepAlive() const;
     84
     85protected:
     86    bool m_keepAlive;
    7787};
    7888
    7989DECLARE_COMMAND(CDisconnectCommand, cmd_disconnect)
  • src/include/engineprivate.h

    diff -Nur Filezilla3/src/include/engineprivate.h Filezilla3.patch/src/include/engineprivate.h
    old new  
    6969    int Mkdir(const CMkdirCommand& command);
    7070    int Rename(const CRenameCommand& command);
    7171    int Chmod(const CChmodCommand& command);
     72    int KeepAlive(const CKeepAliveCommand& command);
    7273
    7374    int ContinueConnect();
    7475
  • src/interface/Mainfrm.cpp

    diff -Nur Filezilla3/src/interface/Mainfrm.cpp Filezilla3.patch/src/interface/Mainfrm.cpp
    old new  
    825825
    826826    CServerPath path;
    827827    path.SetSafePath(COptions::Get()->GetOption(OPTION_LASTSERVERPATH));
    828     m_pState->Connect(server, false, path);
     828    // FIXME:
     829    // read keepalive from option
     830    bool keepAlive = true;
     831    m_pState->Connect(server, false, path, keepAlive);
    829832}
    830833
    831834void CMainFrame::OnRefresh(wxCommandEvent &event)
     
    13411344            return;
    13421345    }
    13431346
    1344     m_pState->Connect(pData->m_server, true, pData->m_remoteDir);
     1347    // FIXME:
     1348    // read keepalive from option
     1349    bool keepAlive = true;
     1350    m_pState->Connect(pData->m_server, true, pData->m_remoteDir, keepAlive);
    13451351
    13461352    if (pData->m_localDir != _T(""))
    13471353        m_pState->SetLocalDir(pData->m_localDir);
  • src/interface/state.cpp

    diff -Nur Filezilla3/src/interface/state.cpp Filezilla3.patch/src/interface/state.cpp
    old new  
    247247    NotifyHandlers(STATECHANGE_APPLYFILTER);
    248248}
    249249
    250 bool CState::Connect(const CServer& server, bool askBreak, const CServerPath& path /*=CServerPath()*/)
     250bool CState::Connect(const CServer& server, bool askBreak, const CServerPath& path /*=CServerPath()*/, bool keepAlive)
    251251{
    252252    if (!m_pEngine)
    253253        return false;
     
    261261
    262262    m_pCommandQueue->ProcessCommand(new CConnectCommand(server));
    263263    m_pCommandQueue->ProcessCommand(new CListCommand(path));
     264    if (keepAlive)
     265        m_pCommandQueue->ProcessCommand(new CKeepAliveCommand(true));
    264266   
    265267    COptions::Get()->SetLastServer(server);
    266268    COptions::Get()->SetOption(OPTION_LASTSERVERPATH, path.GetSafePath());
  • src/interface/state.h

    diff -Nur Filezilla3/src/interface/state.h Filezilla3.patch/src/interface/state.h
    old new  
    4040    static bool LocalDirHasParent(const wxString& dir);
    4141    static bool LocalDirIsWriteable(const wxString& dir);
    4242
    43     bool Connect(const CServer& server, bool askBreak, const CServerPath& path = CServerPath());
     43    bool Connect(const CServer& server, bool askBreak, const CServerPath& path = CServerPath(), bool keepAlive = false);
    4444
    4545    bool SetRemoteDir(const CDirectoryListing *m_pDirectoryListing, bool modified = false);
    4646    const CDirectoryListing *GetRemoteDir() const;