Java Mail 附件名太長導致接收端附件名解析出錯

0x00(測試條件)

附件名:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt


0x01(現象)

新浪郵箱解析出錯:

QQ郵箱解析出錯:


0x02(分析問題)

本地沒問題,到 Linux 環境纔出錯。所以抓了本地的包和 Linux 下的包比較。

本地的包(之前用比較長的中文名測試抓的包):

------=_Part_18_1324418920.1488440125843

Content-Type: application/octet-stream;

name="=?UTF-8?Q?=E4=B8=AD=E6=96=87=E5=AD=97=E7=AC=A6201711=2Edocx?="

Content-Transfer-Encoding: base64

Content-Disposition: attachment;

filename="=?UTF-8?Q?=E4=B8=AD=E6=96=87=E5=AD=97=E7=AC=A6201711=2Edocx?="

Linux 的包:

------=_Part_0_528597028.1488450122516

Content-Type: text/plain; charset=us-ascii;

name*0=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

name*1=a.txt

Content-Transfer-Encoding: 7bit

Content-Disposition: attachment;

filename*0=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

filename*1=a.txt

可以看到問題是文件名太長被拆分了


0x03(查找根源)

看 Java 代碼

String encodeName = MimeUtility.encodeWord(name);
UrlResource inputStreamSource = new UrlResource(attach.getUrl());
helper.addAttachment(encodeName, inputStreamSource); // 自己的業務代碼
addAttachment(attachmentFilename, inputStreamSource, contentType);	// 跟進去
addAttachment(attachmentFilename, dataSource);	// 跟進去

mimeBodyPart.setFileName(MimeUtility.encodeText(attachmentFilename)); // 跟進去
setFileName(this, filename);	// 跟進去
part.setHeader("Content-Disposition", cd.toString()); // 跟進去
sb.append(list.toString(sb.length() + 21));	// 跟進去

if (value.length() > 60 &&
      splitLongParameters && encodeParameters) {
    int seg = 0;
    name += "*"; // 省略...

已經看出是怎麼回事了

 

0x04(解決)

Main方法下加

System.setProperty("mail.mime.splitlongparameters", "false"); // linux 會默認爲 true,會截斷附件名

0x05PS

這是 RFC2231 的規定,估計國內的還不支持(個人猜想)

 

0x06(走過的彎路)

之前沒頭緒。以爲是 Linux 的限制;也懷疑過“MimeUtility.encodeWord(name)”的問題。

跟蹤源碼的時候看錯了 jar 包,應該是 com.sun.mail:javax.mail:1.5.6,還不是 javax.mail:mail:1.4.5

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章