接續著上一篇 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 來看