Ticket #1519: filezilla3_rc1_keepalive3.patch

File filezilla3_rc1_keepalive3.patch, 9.8 KB (added by tommywu, 13 years ago)

keepalive version 3

  • 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);
    151    
     158
    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        }
     
    344353
    345354    if (m_repliesToSkip)
    346355    {
     356        SetWait(false);
    347357        LogMessage(Debug_Info, _T("Skipping reply after cancelled operation."));
    348358        if (m_Response[0] != '1')
    349359            m_repliesToSkip--;
     
    798808        LogMessage(::Error, _T("Failed to convert command to 8 bit charset"));
    799809        return false;
    800810    }
     811    m_keepAliveStopWatch.Start();
    801812    unsigned int len = (unsigned int)strlen(buffer);
    802813    bool res = CRealControlSocket::Send(buffer, len);
    803814    if (res)
     
    30063017    }
    30073018
    30083019    return FZ_REPLY_WOULDBLOCK;
     3020}
     3021
     3022int CFtpControlSocket::KeepAlive(const CKeepAliveCommand& command)
     3023{
     3024    LogMessage(Debug_Verbose, _T("CFtpControlSocket::KeepAlive"));
     3025
     3026    if (command.IsKeepAlive())
     3027    {
     3028        if (!m_bEnableKeepAlive)
     3029        {
     3030            m_bEnableKeepAlive = true;
     3031            // FIXME:
     3032            // read keepalive option here
     3033            int min_wait = 30;
     3034            int max_wait = 60;
     3035            int waitsecond = min_wait + (int)(rand()*(max_wait - min_wait)/(RAND_MAX+1));
     3036            m_keepAliveTimer.Start(waitsecond * 1000);
     3037        }
     3038    }
     3039    else
     3040    {
     3041        if (m_bEnableKeepAlive)
     3042        {
     3043            m_bEnableKeepAlive = false;
     3044            m_keepAliveTimer.Stop();
     3045        }
     3046    }
     3047
     3048    m_bEnableKeepAlive = true;
     3049    return FZ_REPLY_OK;
     3050}
     3051
     3052void CFtpControlSocket::DoKeepAlive()
     3053{
     3054    LogMessage(Debug_Verbose, _T("CFtpControlSocket::DoKeepAlive"));
     3055
     3056    // ignore keepalive for last I/O for socket less than 15 seconds
     3057    if (m_keepAliveStopWatch.Time() < 15000)
     3058        return;
     3059    // choose any command
     3060    wxString commands[4] = {_T("PWD"),_T("REST 0"), _T("NOOP"), _T("STAT") };
     3061    int choice=(rand()*4)/(RAND_MAX+1);
     3062
     3063    m_repliesToSkip++;
     3064    Send(commands[choice]);
     3065    return;
     3066}
     3067
     3068void CFtpControlSocket::OnTimer(wxTimerEvent& event)
     3069{
     3070    if (event.GetId() == KEEPALIVE_TIMER_ID)
     3071    {
     3072        if (m_keepAliveTimer.IsRunning())
     3073        {
     3074            m_keepAliveTimer.Stop();
     3075            if (m_bEnableKeepAlive) {
     3076                // FIXME:
     3077                // need to read the values from options...
     3078                int min_wait = 30;
     3079                int max_wait = 60;
     3080
     3081                int waitsecond = min_wait + (int)(rand()*(max_wait - min_wait)/(RAND_MAX+1));
     3082                m_keepAliveTimer.Start(waitsecond * 1000);
     3083                DoKeepAlive();
     3084            }
     3085        }
     3086    }
     3087    else
     3088        CControlSocket::OnTimer(event);
    30093089}
    30103090
    30113091bool 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    void DoKeepAlive();
     32
    2733    virtual int ResetOperation(int nErrorCode);
    2834
    2935    virtual int Connect(const CServer &server);
     
    128134
    129135    DECLARE_EVENT_TABLE();
    130136    void OnExternalIPAddress(fzExternalIPResolveEvent& event);
     137    void OnTimer(wxTimerEvent& event);
    131138};
    132139
    133140class 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;