Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

KeepAlive patch (version 3) for FileZilla 3.0.1
post by tommy @ 24 九月, 2007 22:50

修改之前的版本, 加上 QuickConnect 的處理.

修正如下:

diff -Nur Filezilla3/src/engine/ControlSocket.h Filezilla3.patch/src/engine/ControlSocket.h
--- Filezilla3/src/engine/ControlSocket.h Mon Sep 24 22:05:20 2007
+++ Filezilla3.patch/src/engine/ControlSocket.h Mon Sep 24 22:05:49 2007
@@ -115,6 +115,8 @@
virtual int Chmod(const CChmodCommand& command) { return FZ_REPLY_NOTSUPPORTED; }
virtual bool Connected() const = 0;
 
+ virtual int KeepAlive(const CKeepAliveCommand& command) { return FZ_REPLY_OK; }
+
// If m_pCurrentOpData is zero, this function returns the current command
// from the engine.
enum Command GetCurrentCommandId() const;
diff -Nur Filezilla3/src/engine/FileZillaEngine.cpp Filezilla3.patch/src/engine/FileZillaEngine.cpp
--- Filezilla3/src/engine/FileZillaEngine.cpp Mon Sep 24 22:05:20 2007
+++ Filezilla3.patch/src/engine/FileZillaEngine.cpp Mon Sep 24 22:05:49 2007
@@ -70,6 +70,9 @@
case cmd_chmod:
res = Chmod(reinterpret_cast<const CChmodCommand&>(command));
break;
+ case cmd_keepalive:
+ res = KeepAlive(reinterpret_cast<const CKeepAliveCommand &>(command));
+ break;
default:
return FZ_REPLY_SYNTAXERROR;
}
diff -Nur Filezilla3/src/engine/commands.cpp Filezilla3.patch/src/engine/commands.cpp
--- Filezilla3/src/engine/commands.cpp Mon Sep 24 22:05:20 2007
+++ Filezilla3.patch/src/engine/commands.cpp Mon Sep 24 22:05:49 2007
@@ -10,6 +10,16 @@
return m_Server;
}
 
+CKeepAliveCommand::CKeepAliveCommand(bool keepAlive /*=true*/)
+ : m_keepAlive(keepAlive)
+{
+}
+
+bool CKeepAliveCommand::IsKeepAlive() const
+{
+ return m_keepAlive;
+}
+
CListCommand::CListCommand(bool refresh /*=false*/)
: m_refresh(refresh)
{
diff -Nur Filezilla3/src/engine/engineprivate.cpp Filezilla3.patch/src/engine/engineprivate.cpp
--- Filezilla3/src/engine/engineprivate.cpp Mon Sep 24 22:05:20 2007
+++ Filezilla3.patch/src/engine/engineprivate.cpp Mon Sep 24 22:05:49 2007
@@ -525,6 +525,12 @@
return m_pControlSocket->Chmod(command);
}
 
+int CFileZillaEnginePrivate::KeepAlive(const CKeepAliveCommand& command)
+{
+ m_pCurrentCommand = command.Clone();
+ return m_pControlSocket->KeepAlive(command);
+}
+
void CFileZillaEnginePrivate::SendDirectoryListingNotification(const CServerPath& path, bool onList, bool modified, bool failed)
{
wxASSERT(m_pControlSocket);
diff -Nur Filezilla3/src/engine/ftpcontrolsocket.cpp Filezilla3.patch/src/engine/ftpcontrolsocket.cpp
--- Filezilla3/src/engine/ftpcontrolsocket.cpp Mon Sep 24 22:05:20 2007
+++ Filezilla3.patch/src/engine/ftpcontrolsocket.cpp Mon Sep 24 22:05:49 2007
@@ -24,8 +24,11 @@
#define LOGON_CUSTOMCOMMANDS 10
#define LOGON_DONE 11
 
+#define KEEPALIVE_TIMER_ID wxID_HIGHEST + 5
+
BEGIN_EVENT_TABLE(CFtpControlSocket, CRealControlSocket)
EVT_FZ_EXTERNALIPRESOLVE(wxID_ANY, CFtpControlSocket::OnExternalIPAddress)
+EVT_TIMER(wxID_ANY, CFtpControlSocket::OnTimer)
END_EVENT_TABLE();
 
CRawTransferOpData::CRawTransferOpData()
@@ -137,6 +140,8 @@
m_pTlsSocket = 0;
m_protectDataChannel = false;
m_lastTypeBinary = -1;
+ m_bEnableKeepAlive = false;
+ m_keepAliveTimer.SetOwner(this, KEEPALIVE_TIMER_ID);
}
 
CFtpControlSocket::~CFtpControlSocket()
@@ -147,12 +152,16 @@
{
LogMessage(Debug_Verbose, _T("CFtpControlSocket::OnReceive()"));
 
+ m_keepAliveStopWatch.Start();
+
m_pBackend->Read(m_receiveBuffer + m_bufferLen, RECVBUFFERSIZE - m_bufferLen);
-
+
if (m_pBackend->Error())
{
if (m_pBackend->LastError() != wxSOCKET_WOULDBLOCK)
{
+ m_bEnableKeepAlive = false;
+ m_keepAliveTimer.Stop();
LogMessage(::Error, _("Disconnected from server"));
DoClose();
}
@@ -344,6 +353,7 @@
 
if (m_repliesToSkip)
{
+ SetWait(false);
LogMessage(Debug_Info, _T("Skipping reply after cancelled operation."));
if (m_Response[0] != '1')
m_repliesToSkip--;
@@ -798,6 +808,7 @@
LogMessage(::Error, _T("Failed to convert command to 8 bit charset"));
return false;
}
+ m_keepAliveStopWatch.Start();
unsigned int len = (unsigned int)strlen(buffer);
bool res = CRealControlSocket::Send(buffer, len);
if (res)
@@ -3006,6 +3017,75 @@
}
 
return FZ_REPLY_WOULDBLOCK;
+}
+
+int CFtpControlSocket::KeepAlive(const CKeepAliveCommand& command)
+{
+ LogMessage(Debug_Verbose, _T("CFtpControlSocket::KeepAlive"));
+
+ if (command.IsKeepAlive())
+ {
+ if (!m_bEnableKeepAlive)
+ {
+ m_bEnableKeepAlive = true;
+ // FIXME:
+ // read keepalive option here
+ int min_wait = 30;
+ int max_wait = 60;
+ int waitsecond = min_wait + (int)(rand()*(max_wait - min_wait)/(RAND_MAX+1));
+ m_keepAliveTimer.Start(waitsecond * 1000);
+ }
+ }
+ else
+ {
+ if (m_bEnableKeepAlive)
+ {
+ m_bEnableKeepAlive = false;
+ m_keepAliveTimer.Stop();
+ }
+ }
+
+ m_bEnableKeepAlive = true;
+ return FZ_REPLY_OK;
+}
+
+void CFtpControlSocket::DoKeepAlive()
+{
+ LogMessage(Debug_Verbose, _T("CFtpControlSocket::DoKeepAlive"));
+
+ // ignore keepalive for last I/O for socket less than 15 seconds
+ if (m_keepAliveStopWatch.Time() < 15000)
+ return;
+ // choose any command
+ wxString commands[4] = {_T("PWD"),_T("REST 0"), _T("NOOP"), _T("STAT") };
+ int choice=(rand()*4)/(RAND_MAX+1);
+
+ m_repliesToSkip++;
+ Send(commands[choice]);
+ return;
+}
+
+void CFtpControlSocket::OnTimer(wxTimerEvent& event)
+{
+ if (event.GetId() == KEEPALIVE_TIMER_ID)
+ {
+ if (m_keepAliveTimer.IsRunning())
+ {
+ m_keepAliveTimer.Stop();
+ if (m_bEnableKeepAlive && IsConnected()) {
+ // FIXME:
+ // need to read the values from options...
+ int min_wait = 30;
+ int max_wait = 60;
+
+ int waitsecond = min_wait + (int)(rand()*(max_wait - min_wait)/(RAND_MAX+1));
+ m_keepAliveTimer.Start(waitsecond * 1000);
+ DoKeepAlive();
+ }
+ }
+ }
+ else
+ CControlSocket::OnTimer(event);
}
 
bool CFtpControlSocket::IsMisleadingListResponse() const
diff -Nur Filezilla3/src/engine/ftpcontrolsocket.h Filezilla3.patch/src/engine/ftpcontrolsocket.h
--- Filezilla3/src/engine/ftpcontrolsocket.h Mon Sep 24 22:05:20 2007
+++ Filezilla3.patch/src/engine/ftpcontrolsocket.h Mon Sep 24 22:05:49 2007
@@ -24,6 +24,12 @@
 
protected:

+ bool m_bEnableKeepAlive;
+ wxTimer m_keepAliveTimer;
+ wxStopWatch m_keepAliveStopWatch;
+ virtual int KeepAlive(const CKeepAliveCommand& command);
+ void DoKeepAlive();
+
virtual int ResetOperation(int nErrorCode);
 
virtual int Connect(const CServer &server);
@@ -128,6 +134,7 @@
 
DECLARE_EVENT_TABLE();
void OnExternalIPAddress(fzExternalIPResolveEvent& event);
+ void OnTimer(wxTimerEvent& event);
};
 
class CIOThread;
diff -Nur Filezilla3/src/include/commands.h Filezilla3.patch/src/include/commands.h
--- Filezilla3/src/include/commands.h Mon Sep 24 22:05:12 2007
+++ Filezilla3.patch/src/include/commands.h Mon Sep 24 22:05:49 2007
@@ -19,6 +19,7 @@
cmd_rename,
cmd_chmod,
cmd_raw,
+ cmd_keepalive,
 
// Only used internally
cmd_cwd,
@@ -74,6 +75,15 @@
const CServer GetServer() const;
protected:
CServer m_Server;
+};
+
+DECLARE_COMMAND(CKeepAliveCommand, cmd_keepalive)
+ CKeepAliveCommand(bool keepAlive = true);
+
+ bool IsKeepAlive() const;
+
+protected:
+ bool m_keepAlive;
};
 
DECLARE_COMMAND(CDisconnectCommand, cmd_disconnect)
diff -Nur Filezilla3/src/include/engineprivate.h Filezilla3.patch/src/include/engineprivate.h
--- Filezilla3/src/include/engineprivate.h Mon Sep 24 22:05:12 2007
+++ Filezilla3.patch/src/include/engineprivate.h Mon Sep 24 22:05:49 2007
@@ -69,6 +69,7 @@
int Mkdir(const CMkdirCommand& command);
int Rename(const CRenameCommand& command);
int Chmod(const CChmodCommand& command);
+ int KeepAlive(const CKeepAliveCommand& command);
 
int ContinueConnect();
 
diff -Nur Filezilla3/src/interface/Mainfrm.cpp Filezilla3.patch/src/interface/Mainfrm.cpp
--- Filezilla3/src/interface/Mainfrm.cpp Mon Sep 24 22:08:54 2007
+++ Filezilla3.patch/src/interface/Mainfrm.cpp Mon Sep 24 22:09:18 2007
@@ -932,7 +932,10 @@
 
CServerPath path;
path.SetSafePath(COptions::Get()->GetOption(OPTION_LASTSERVERPATH));
- m_pState->Connect(server, false, path);
+ // FIXME:
+ // read keepalive from option
+ bool keepAlive = true;
+ m_pState->Connect(server, false, keepAlive, path);
}
 
void CMainFrame::OnRefresh(wxCommandEvent &event)
@@ -1456,7 +1459,10 @@
return;
}
 
- m_pState->Connect(pData->m_server, true, pData->m_remoteDir);
+ // FIXME:
+ // read keepalive from option
+ bool keepAlive = true;
+ m_pState->Connect(pData->m_server, true, keepAlive, pData->m_remoteDir);
 
if (pData->m_localDir != _T(""))
m_pState->SetLocalDir(pData->m_localDir);
diff -Nur Filezilla3/src/interface/quickconnectbar.cpp Filezilla3.patch/src/interface/quickconnectbar.cpp
--- Filezilla3/src/interface/quickconnectbar.cpp Mon Sep 24 22:08:54 2007
+++ Filezilla3.patch/src/interface/quickconnectbar.cpp Mon Sep 24 22:09:18 2007
@@ -108,7 +108,10 @@
return;
}
 
- if (!m_pState->Connect(server, true))
+ // FIXME:
+ // read keepalive from option
+ bool keepAlive = true;
+ if (!m_pState->Connect(server, true, keepAlive))
return;
 
CRecentServerList::SetMostRecentServer(server);
diff -Nur Filezilla3/src/interface/state.cpp Filezilla3.patch/src/interface/state.cpp
--- Filezilla3/src/interface/state.cpp Mon Sep 24 22:08:54 2007
+++ Filezilla3.patch/src/interface/state.cpp Mon Sep 24 22:09:18 2007
@@ -259,7 +259,7 @@
NotifyHandlers(STATECHANGE_APPLYFILTER);
}
 
-bool CState::Connect(const CServer& server, bool askBreak, const CServerPath& path /*=CServerPath()*/)
+bool CState::Connect(const CServer& server, bool askBreak, bool keepAlive /*=false*/, const CServerPath& path /*=CServerPath()*/)
{
if (!m_pEngine)
return false;
@@ -273,6 +273,8 @@
 
m_pCommandQueue->ProcessCommand(new CConnectCommand(server));
m_pCommandQueue->ProcessCommand(new CListCommand(path));
+ if (keepAlive)
+ m_pCommandQueue->ProcessCommand(new CKeepAliveCommand(true));

COptions::Get()->SetLastServer(server);
COptions::Get()->SetOption(OPTION_LASTSERVERPATH, path.GetSafePath());
diff -Nur Filezilla3/src/interface/state.h Filezilla3.patch/src/interface/state.h
--- Filezilla3/src/interface/state.h Mon Sep 24 22:08:54 2007
+++ Filezilla3.patch/src/interface/state.h Mon Sep 24 22:09:18 2007
@@ -40,7 +40,7 @@
static bool LocalDirHasParent(const wxString& dir);
static bool LocalDirIsWriteable(const wxString& dir);
 
- bool Connect(const CServer& server, bool askBreak, const CServerPath& path = CServerPath());
+ bool Connect(const CServer& server, bool askBreak, bool keepAlive = false, const CServerPath& path = CServerPath());
 
bool SetRemoteDir(const CDirectoryListing *m_pDirectoryListing, bool modified = false);
const CDirectoryListing *GetRemoteDir() const;

 Patch 可以由這兒抓取: http://www.teatime.com.tw/~tommy/mypatch/filezilla3_keepalive.patch
製作出來的 Windows 執行檔可以由這兒抓: http://www.teatime.com.tw/~tommy/files/filezilla/filezilla301.7z

有需要的就自己抓回去用吧.

Del.icio.us Furl HEMiDEMi Technorati MyShare
commons icon [1] Re:KeepAlive patch (version 3) for FileZilla 3.0.1 [ 回覆 ]

perfect works.

迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 136 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS