讓FileZilla相容FtpAnywhere的網格FTP[修改原始碼]

來源:互聯網
上載者:User

讓FileZilla相容FtpAnywhere

FileZilla
FTP是一個著名的開源標準FTP用戶端軟體,但是它的目前版本與FtpAnywhere提供的網格FTP有相容問題,而且,目前無法通過它提供的那些設定模組來實現相容,因此,我特地下載了它的原始碼快照
[2009.4.16] ,看看是否有可能通過修改原始碼來讓它相容.

解壓縮它的原始碼,轉到子目錄/src/engine下,開啟ftpcontrolsocket.cpp檔案,這個檔案就是FileZilla用來支援標準FTP指令的核心,需要改造的是它的列表模式以及對PASV反饋的分析代碼
[包括IPV6下的EPSV指令,但是暫時因為沒有IPV6,所以沒必要動它],改造它的PASV解析代碼

讓FileZilla相容FtpAnywhere

bool
CFtpControlSocket::ParsePasvResponse(CRawTransferOpData* pData)

{

// Validate ip address


wxString digit = _T("0*[0-9]{1,3}");

const wxChar* dot =
_T(",");

wxString exp = _T("( |//()(") + digit + dot + digit + dot + digit + dot + digit + dot + digit + dot +
digit + _T(")( |//)|$)");

wxRegEx regex;

regex.Compile(exp);

if
(!regex.Matches(m_Response))

return false;

pData->host = regex.GetMatch(m_Response, 2);

int i =
pData->host.Find(',',
true);

long number;

if (i == -1 ||
!pData->host.Mid(i + 1).ToLong(&number))

return false;

pData->port = number; //get ls byte of
server socket


pData->host = pData->host.Left(i);

i = pData->host.Find(',', true);

if (i == -1 ||
!pData->host.Mid(i + 1).ToLong(&number))

return false;

pData->port += 256 * number; //add ms
byte of server socket


pData->host = pData-> host.Left(i);

pData->host.Replace(_T(","), _T("."));

if (m_pProxyBackend)

{

// We do not have any information about the
proxy's inner workings


return true;

}

const wxString peerIP =
m_pSocket->GetPeerIP();

if
(!IsRoutableAddress(pData->host, m_pSocket->GetAddressFamily()) &&
IsRoutableAddress(peerIP, m_pSocket->GetAddressFamily()))

{

if
(!m_pEngine->GetOptions()->GetOptionVal(OPTION_PASVREPLYFALLBACKMODE) ||
pData->bTriedActive)

{

LogMessage(Status, _("Server sent passive
reply with unroutable address. Using server address instead."));

LogMessage(Debug_Info, _T(" Reply: %s,
peer: %s"), pData->host.c_str(), peerIP.c_str());

pData->host = peerIP;

}

else


{

LogMessage(Status, _("Server sent passive
reply with unroutable address. Passive mode failed."));

LogMessage(Debug_Info, _T(" Reply: %s,
peer: %s"), pData->host.c_str(),
peerIP.c_str());

return false;

}

}

return true;

}

這裡是它原先的代碼,導致PASV模式下無法下載的問題就出在它不知道有P2P傳輸這麼個東西,因此加了個安全判斷功能,只要把它登出就可以適合FtpAnywhere了,一般來說,只要FTP伺服器是正規的伺服器,那麼這些代碼完全是白費蠟,登出後的代碼

 

讓FileZilla相容FtpAnywhere

bool
CFtpControlSocket::ParsePasvResponse(CRawTransferOpData* pData)

{

// Validate ip address


wxString digit = _T("0*[0-9]{1,3}");

const wxChar* dot =
_T(",");

wxString exp = _T("( |//()(") + digit + dot + digit + dot + digit + dot + digit + dot + digit + dot +
digit + _T(")( |//)|$)");

wxRegEx regex;

regex.Compile(exp);

if
(!regex.Matches(m_Response))

return false;

pData->host = regex.GetMatch(m_Response, 2);

int i =
pData->host.Find(',',
true);

long number;

if (i == -1 ||
!pData->host.Mid(i + 1).ToLong(&number))

return false;

pData->port = number; //get ls byte of
server socket


pData->host = pData->host.Left(i);

i = pData->host.Find(',', true);

if (i == -1 ||
!pData->host.Mid(i + 1).ToLong(&number))

return false;

pData->port += 256 * number; //add ms
byte of server socket


pData->host = pData-> host.Left(i);

pData->host.Replace(_T(","), _T("."));

if (m_pProxyBackend)

{

// We do not have any information about the
proxy's inner workings


return true;

}

 

//注意,把下面的代碼登出,就可以支援P2P
PASV模式下的串連傳輸了

//const wxString peerIP =
m_pSocket->GetPeerIP();

//if
(!IsRoutableAddress(pData->host, m_pSocket->GetAddressFamily()) &&
IsRoutableAddress(peerIP, m_pSocket->GetAddressFamily()))

//{

//if
(!m_pEngine->GetOptions()->GetOptionVal(OPTION_PASVREPLYFALLBACKMODE) ||
pData->bTriedActive)

//{

//LogMessage(Status, _("Server sent passive reply with unroutable address. Using server address
instead."));

//LogMessage(Debug_Info, _T(" Reply: %s, peer: %s"), pData->host.c_str(), peerIP.c_str());

//pData->host = peerIP;

//}

//else


//{

//LogMessage(Status, _("Server sent passive reply with unroutable address. Passive mode
failed."));

//LogMessage(Debug_Info, _T(" Reply: %s, peer: %s"), pData->host.c_str(),
peerIP.c_str());

//return false;

//}

//}

return true;

}

那麼現在的代碼,只要在網站屬性的串連模式裡,指定PORT為優先,在PORT模式串連失敗後,設定自動切換到PASV模式,已經可以有條件相容,只是第一次下載會失敗而已,下面我們改造它的列表模式,讓它具備更好的相容性.
當然,你可以在FtpAnywhere伺服器裡,設定禁止根目錄下PASV列表,來讓FileZilla自動判斷串連模式,但是從它的代碼看,它的判斷還是存在一點相容問題.因此,將LIST改造成主動模式優先,是最好的選擇.

問題在這裡

CRawTransferOpData::CRawTransferOpData()

: COpData(cmd_rawtransfer)

{

bTriedPasv = bTriedActive = false;

bPasv = true;

}

它的初始化是被動模式優先,這樣,列表的時候將發生問題,但是下載可以成功,但是我閱讀代碼,發現除非額外指定一個列表時優先使用的模式變數,否則很難修改代碼,因為它的代碼中列表和檔案傳輸的優先模式是一致的,還要適應其他標準FTP網站,畢竟我不可以能讓它為我的FtpAnywhere進行最佳化,方法是,在FtpControlSocket.h裡定義的類

class CRawTransferOpData : public COpData

{

public:

CRawTransferOpData();

wxString cmd;

CFtpTransferOpData* pOldData;

bool bPasv;

bool bTriedPasv;

bool bTriedActive;

wxString host;

int port;

};

給它加個額外的變數,例如 bool bFtpAnywhere;然後,在List指令前,確定首先採用PASV或者PORT前,判斷
bFtpAnywhere是否為真,如果為真,那麼列表應該優先採用PORT模式,否則繼續執行預設的動作;而bFtpAnywhere的初始化應該從給伺服器發送
VDSI指令是否返回2XX來判斷,是否是一個FtpAnywhere伺服器,因為這裡涉及的修改太多,除非FileZilla代碼維護人員同意,否則沒有意義,因此,最簡單最快的方法還是直接登出我上面給出的代碼,雖然無法獲得100%相容,但是基本可以相容,而且通過設定項目,可以做到手動相容.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.