echo Impossible|sed 's/Im/To be /'

June 07, 2008

proftpd iconv

概要:由 proftpd 提供動態檔名編碼轉換。Proftpd UTF8 <-> [ BIG5 | shift-jis | UTF8 ] Ftp Client

前情:開發 web ap,須上傳多個超大 video 檔案,利用 WinXP IE browser ftp 功能, 而衍生出 [BIG5|shift-jis|UTF8] <-> UTF8 的問題。中文 WinXP 內建的 ftp 上傳檔案 中文檔名會是 Big5 編碼。 遠端系統編碼是 UTF8,所以想簡單的透過 ftp server 更改檔名編碼,於是我找上了 ProFTPD - iconv() charset conversion patch 利用這個 patch 作 Big5 與 UTF8 轉換。如果故事就這樣結束了,那這篇也沒有存在的價值了。

問題:圖說如下

[1] WinXP ftp[Big5] <--> Linux Proftpd[Big5] <--> Linux lftp[Big5]
[2] WinXP ftp[Big5] <--> Linux Proftpd-iconv[UTF8] <--> Linux lftp[Big5]
[3] WinXP cutftp[UTF8] <--> Linux Proftpd[UTF8] <--> Linux lftp[UTF8]
[1] 三地檔名將會是 Big5, Big5 許功蓋會是個問題。
[2] 雖然 Linux Proftpd 端是 UTF8, 但 Linux lftp 卻又會是 Big5, 一樣有 Big5 的問題。
[3] 用可以選編碼的 ftp client 是最佳解,但不被接受,須額外安裝程式。

解法:
事實上這問題的解法相當多樣,簡單推算了一下,至少有六種。

  1. WinXP 透過 cutftp 上傳 UTF8 編碼的檔案。此解法最為簡單,但遭到否決,因為對使用者造成麻煩。
  2. 寫 WinXP ftp IE plugin。但卻遭到否決,因為對使用者造成麻煩,要安裝。
  3. WinXP 上傳 Big5 檔名, 在 Linux Proftpd-iconv patch 轉為 UTF8, 以千為數的 Linux lftp download video 會因 Proftpd-iconv path 再度將檔名轉為 Big5,須再度透過 iconv 在轉成 UTF8。
  4. 同上,但直接透過 lftp set file:charset , 或 set ftp:charset 轉碼。 現行案例有兩種以上可能的編碼 Shift-jis, GBK, Big5,這須額外指定, Client 數量太多了,放棄。
  5. Linux 啟動兩個 Proftpd ,一個轉碼 for WinXP,一個不轉碼 for Linux lftp,聽不同 port。可行,但好醜。
  6. Linux Proftpd 知道 ftp client 的種類後決定轉碼或不轉碼。

我想採用最佳解 6.,不成功還有 5. 可以用,簡單的測試過 5. 的方法驗證確定可行後,轉攻 6.

過程:
Proftpd Server 有幾個沒有實作的指令 CLNT ACCT LANG,實作 LANG 做語系編碼轉換較佳, 但案子受限不允許於 clinet 額外送出 LANG command。 只好退而求 CLNT 跟 ACCT。 CLNT 本意在送出程式名通知 Server 做區隔。 ACCT 本意對特殊帳號讓 Server 做出特別權限或行為。這兩個都可以拿來利用。 但 ACCT 在 proftpd ldap modules 上有實作,且 ACCT 對往後 code 再利用上我認為較差。 CLNT 命令讓 Server 收到後針對 Clinet 不同而做出不同反應,較符合原意, 但遺憾的是並非所有的 ftp client 都會送出 CLNT 命令, windows 上有幾款 ftp client 會送,測試了但忘了記下來, linux 會送的有 lftp, ncftp。 最後採用修正 proftpd 針對 linux lftp 跟 WinXP ftp 辨別後做轉碼或不轉碼的區分。 於是圖例解法如下。WinXP ftp 端強迫轉碼,linux lftp 則不做轉碼動作。

[4] WinXP ftp[Big5] <--> Linux Proftpd-iconv-CLNT[UTF8] <--> Linux lftp[UTF8]

新增一 proftpd modules ,及 ftp server 指令。在 ftp client 以 FEAT 與詢問 Server Site 要求回傳 211-Features: 211-CLNT 用以觸發 client 送出 CLNT command,以及其他相關特殊命令。

感謝 『使徒提姆』 幫我查 lftp 的 source code, 找出了 FEAT 要求後回傳 211-CLNT,觸發 lftp 送出 CLNT String command。

  • proftpd - iconv 1.3.0-20 deb file -- 將 proftpd iconv 1.2.10 patch port 到 debian etch
  • proftpd - iconv - CLNT 1.3.0-21 deb file -- 針對 CLNT 命令的有無,辨別轉碼或不轉碼的特殊修正
  • Source and patch files