project:ntuwebmail

我已經不再負責維護 NTU WebMail System 了。

功能

  • 提供 ccms/msa/ms9x 的使用者,login 只需要輸入帳號跟密碼,會自動從帳號去判斷要用哪一台伺服器
  • 提供閱讀信件、寫信等基本郵件功能 (IMP)
  • 提供通訊錄 (turba)
  • 提供過濾器 (ingo)
    • 只有在 WebMail 上有效,屬於 client side 處理的 filter
  • 提供行事曆 (kronolith)
  • 提供備忘錄 (mnemo)

架構

WebMail 目前是用數台前端(wmail6,wmail9)(處理 WWW 的部分),跟一台 !MySQL (wmail6)負責存使用者的設定、通訊錄等東西。www 的東西都放在 /usr/local/www 下,webmail 相關 maintainence 用的東西都在 /home/services/webmail。裡面主要釋放備份/upgrade/sync 用的 script。其中有一個是 sync.sh,是用來讓 wmail6 跟 wmail9 sync 東西用的(包含 /usr/local/www, /home/services/webmail, /usr/local/lib/php/pear)。

升級

請先看過 notes,然後先在 www/data/horde.orig 跑 /home/services/webmail/cvs.sh,然後用 /home/services/webmail/upgarde.sh,這個會把 horde.orig → www/data/horde 然後跑 mergeconfig(改 mergemaster 的程式)。最後要 login horde as admin,去更新設定檔。另外就是用 patch.sh 去 apply 一堆有的沒的 patch(因為跟 CVS head,絕大部分會 fail,需要手動更新 patch 檔)。

問題

  • 需要有人寫完整一點的使用手冊跟功能介紹
  • 通訊錄跟收件人 MIME encoding 的問題

這個問題很複雜,簡單的說,在用通訊錄的時候,有時候會因為中文的問題,讓 RCPT TO 變成空的,因此會收到 @localhost.cc.ntu.edu.tw 之類的退信。

問題有兩個部份,第一個是 contact.inc 裡面,OPTION 的 VALUE 是用 PHP 的 rawurlencode() 處理,而 decode 則是 JavaScript 的 unescape(),很不幸的是 unescape() 是認 Unicode 的(在 escape() 的時候會弄成 %uXXXX 這種,這可以看 mozilla/fierfox source: mozilla/ja/src/jsstr.c),而 rawurlencode() 則不認得,它是一個 byte 一個 byte 去弄的,所以說解回去之後會把中文弄爛,接下來在弄RCPT TO 的時候,會呼叫很多 Horde/framework/MIME* 跟 PEAR Mail 的東西,裡面很多檢查會產生 error,於是 RCPT TO 就爛了。這個修正也很困難(至少我找不到)。

目前的解法是這樣子的,要就 encode/decode 都是 PHP(or JavaScript)來處理,但是以目前架構下不太可能,要改寫的代價太大,因此,我決定違反 W3C 的規範,在 VALUE 的地方,用 ' 把 value 弄起來,然後不呼叫 rawurlencode(),而是在 addAddress 的時候用 escape()。

另一個部份則是 \ 在 PEAR Mail::RFC822 檢查的時候,會被列成不合法的東西,因此也會把 RCPT TO 弄爛。而因為去改寫這部份會牽扯到太多 Horde 整個架構,於是就乾脆不檢查 \(Big5 會有的問題)。

另外一點是目前在用的寫信那個 compose.php 在 send 的時候如果底下有 PEAR Error 並不會傳回來,導致大家以為信是 ok 的,目前是硬 display PEAR Error,而最新的 CVS Version 中,已經改成有 error 會叫了。

    • 還有一個還沒追的是 from 的 name 中有 , 的時候似乎會被誤判,導致信塞不出去
  • 走 utf8 避免 '許成功蓋' 的問題
    • 底下有細節
  • 用 memcached 來當 session 的 backend
    • memcached 是一個相當高效率的 cache daemon(被用在 livejournal.com 上)
    • 目的是 www 可以直接走 dns round robin,而目前是用 javascript
  • 外部信件
    • 曾經有碰過設定成一 login 就去收外部信件,會造成 httpd 爆炸的,不過似乎好一陣子沒有人 complain 了,這個倒是需要再確認
  • QUOTA
    • 目前是在 login 的時候,手動走 imap 去算,好了之後放進 session
    • 除非有用到會改變信箱 size 的功能(比方說清除標記刪除的信件)以外,會直接去拿 session 中算好的大小,而不重算
    • 在算的時候,也會偷在 session 中記錄每個 mailbox 的用量,這樣子可以加速在清除標記刪除的信件等動作的時候,只需要重算有變動的 folder(大約只有 15% 的會用到這個 cache)
  • performance 相關的問題
    • php 的 accelerator 現在是跑 eaccelerator,據別的 site 的測試是 APC 比較快,但是 APC 我跑起來會有問題
    • 目前 php 沒有 –enable-inline-optimization
    • log 中有紀錄在郵件列表 (mailbox.php) 那頁花超過一定時間(目前是 5 秒)以上的分析,底下列舉一些慢的狀況
      • 第一次 login 或者清除已刪除之後,通常會花一堆 (70%~90%) 的時間在算 quota(目前 quota 是在 webmail 機器上用 imap 去掃一次 mailbox 算的,信多的話會*非常慢*)
      • 去算目前這個 mailbox 有多少信還沒讀過,偶而會花一點時間(20%),不過這是直接下 imap command 的
      • build 目前這頁要顯示些什麼信件 (buildMailboxPage) 也需要花一些 (20%~30%)

Horde/IMP & UTF8

要改的設定 / Patches

  • nls.php
  $nls['defaults']['language'] = 'zh_TW';
  $nls['charsets']['zh_TW'] = 'UTF-8';
  $nls['emails']['zh_TW'] = 'BIG5';
  • raw 8bit subject/body ??? not sure nls.php can control this
    • Horde/MIME.php: decode() X-UNKNOWN → BIG5 (subject)
    • Horde/MIME/Part.php: getCharset() x-unknown → BIG5 (body)
  • imp/lib/Message.php log
    • 不知道為什麼轉成 utf8 寫進 log 有問題,現在直接轉 big5
  • 換 libiconv 的表 (主要是日文對應錯的那段)
  • SQL 部分
    • horde/config/conf.php
  $conf['sql']['charset'] = 'utf-8';

測試

  • IMP 寫信 sending_charset 現在是 BIG5, seems ok
  • 通訊錄 → compose charset (since its default is big5.. ok)
    • [imp] address book → compose window (imp mailing)
    • imp/lib/Compose.php → MIME::encodeAddress (還沒 enocde 前就先用 RFC822 去拿 address,所以會大爆炸)
    • http://bugs.horde.org/ticket/?id=1352 (已經 close 掉,有 error 會說了)
project/ntuwebmail.txt · Last modified: 2007/10/27 07:26 by 140.112.1.98