2014年8月22日 星期五

JAVA POP3 Server 信件內文中斷符號問題修正


接續著上一篇 JAVA POP3 Server 實作 後,
這一篇主要是修正一個很奇怪的問題。


在使用Thunderbird測試一段時間後發現一個很奇怪的問題
只要跑一段時間就會出現 "RETR 命令不成功,取回郵件時發生錯誤"

在Outlook下測試卻不會,但會有很奇怪的空白信件,
空白信件的大小甚至可以到200M,這太不尋常了

反復測試 bug track後,
發現應該是信件內有 RETR cammond 的中斷符號造成。

至於兩個 Client 對於此問題的出現不一樣的結果,
我只能說,各家對於問題處裡的方式不同。

Thunderbird遇到問題就停止收信。
Outlook則是繼續收,但有問題的信跟後續的幾封信,都會變成空白信件。

之後有試著自己處理output時遇到中斷點問題,
但後來參考了 Apache James 的 POP3Handler Source Code ,
覺得寫的比較好,就拿來用了

看程式吧~
=============================================================
為了使用 FilterOutputStream 所以要加上 BufferedOutputStream

修改前
out = new PrintWriter(mySocket.getOutputStream(), AUTOFLUSH);

修改後
outs = new BufferedOutputStream(mySocket.getOutputStream(), 1024);
out = new PrintWriter(outs, AUTOFLUSH);

=============================================================
printMail 修改,使用 Apache James 的 ExtraDotOutputStream 來處理內文斷點

修改前
private void printMail(Integer index) {
String str = "";
GridFSDBFile gfsdbf = glist.get(index - 1);
InputStream inputS = null;
BufferedReader reader = null;
try {
inputS = gfsdbf.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputS));

while ((str = reader.readLine()) != null) {
out.println(str);
}

} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
} finally {
try {
if (inputS != null)
inputS.close();
if (reader != null)
reader.close();
} catch (Throwable ignore) {
}
}
}

修改後
private void printMail(Integer index) {
GridFSDBFile gfsdbf = glist.get(index - 1);
InputStream inputS = null;
try {
inputS = gfsdbf.getInputStream();

ExtraDotOutputStream edouts =
                    new ExtraDotOutputStream(outs);

int numRead;
byte[] buf = new byte[8192];
while ((numRead = inputS.read(buf)) >= 0) {
edouts.write(buf, 0, numRead);
}

edouts.checkCRLFTerminator();
            edouts.flush();
           
} catch (Exception e) {
out.println("-ERR");
log.error(ExceptionUtils.getStackTrace(e));
} finally {
try {
if (inputS != null)
inputS.close();
} catch (Throwable ignore) {
}
}
}


至於 ExtraDotOutputStream 這隻程式我就不附上了,
有興趣的可以去下載 Source Code 來看

沒有留言:

張貼留言