經歷一陣子的追蹤,發現 osTicket v1.18.1 的信件處理流程更新的不錯,但在一個關鍵的格式拼裝上出了錯誤,目前就發個 PR 讓團隊評估是否能修正了
這陣子研究 osTicket v1.18.1 時,信件處理分成兩個部分,一個是信件下載,另一個是信件解析。之前設法先把他信件架在過程中,埋了一個機制把信件存起來,接著去研究它的 MIMEDecode 流程,並猜測這邊要補強,實際上是他下載信件後,要組成 MIME 格式有問題,才使得信件解析有問題
public function getRawEmail(int $i) {- return $this->getRawHeader($i) . $this->getRawContent($i);+ return trim($this->getRawHeader($i)) . "\r\n\r\n" . $this->getRawContent($i);}
透過這次也研究了 osTicket v1.18 採用了 laminas-mail 來處理信件下載流程,整體上跑 api/cron.php 可以看到:
# php8.1 cron.php@class.mail.php - Imap class: __construct@Storage/Imap.php: __construct@Storage/Imap.php: selectFolder(INBOX)@Storage/Imap.php: countMessages()@Storage/Imap.php: getRawHeader(1, , 0)@Storage/Imap.php: getRawContent(1, )@class.mail.php, Imap class: markAsSeen(1)@Storage/Imap.php: setFlags(1, Array)@class.mail.php, Imap class: expunge()@Storage/Imap.php:close()
而在 class.mail.php 在 v1.16 是看不到的,可在 osTicket/osTicket/blob/1.16.x/include/class.mailfetch.php 觀看直接用 PHP imap_* 系列的函式做事,而在 v1.17 起多了 class.mail.php 檔案,在其檔案內可以看到 getRawEmail() 的實作分成 getRawHeader() + getRawContent()
再往下追就會發現架構也變得漂亮。趁這次多了解了 osTicket ,而為了這次任務,解題思維:
- 設法用 Docker 建立 osTicket 測試環境
- 設法在 osTicket 處理信件流程中,取出一個 eml 檔案實驗
- 設法在 osTicket 架構下,建立匯入 eml 檔案作為重現 MIMEDecode 的測試
- 設法直接用 MIMEDecode 測試流程
- 追蹤 osTicket IMAP 信件下載流程
沒想到最後一步才發現問題的根源,若一開始先懷疑信件下載流程,應當可以秒解任務。後續再看送出的 PR 有沒緣被收了