ddeboer / imap

Object-oriented, fully tested PHP IMAP library
MIT License
889 stars 253 forks source link

Can't retrieve headers from RFC822-HEADERS subpart #561

Open rudiedirkx opened 1 year ago

rudiedirkx commented 1 year ago
Q A
ddeboer/imap version 1.17.0
PHP version 8.1.17
IMAP provider smtp.mailprotect.be

I am reading bounces from a sender mailbox to mark some users as undeliverable. To do that I need the bounce DELIVERY-STATUS subpart. That's pretty easy:

class BouncesReader {
  protected function getSubtypePart(Message $message, string $subtype) : ?PartInterface {
    $iterator = new RecursiveIteratorIterator($message, RecursiveIteratorIterator::SELF_FIRST);
    foreach ($iterator as $part) {
      if (strtoupper($part->getSubtype()) === strtoupper($subtype)) {
        return $part;
      }
    }

    return null;
  }

  protected function getDeliveryStatus(Message $message) : ?string {
    if ($part = $this->getSubtypePart($message, 'DELIVERY-STATUS')) {
      return $part->getContent();
    }

    return null;
  }
}

getSubtypePart() will find the subpart anywhere, and getDeliveryStatus() will return its content.

But I also want some info from the original mail that was bounced. Some mail servers embed the entire original mail in the bounce, so I can find that attachment part (Attachment) and its message (BasicMessageInterface) with all the original headers:

    if ($original = $this->getSubtypePart($message, 'RFC822')) {
      return $original->getEmbeddedMessage();
    }

But some mail servers don't include the entire original message (RFC822), just the headers (RFC822-HEADERS):

    $originalHeaders = $this->getSubtypePart($message, 'RFC822-HEADERS');

That part is not an Attachment part, but a SimplePart, and that doesn't support an 'embedded message'. Which is true, it's not a full message, but it does contain very useful headers in a standard format. But I can't get at those, because a SimplePart doesn't think it has headers. I can see them in the raw content (see below), but I can't access them (without parsing the entire raw email, so no).


This is a full bounce without RFC822 but with RFC822-HEADERS:

Return-Path: <>
Delivered-To: bounces@mine.com
Received: from com-bemdirector002.mailprotect.be ([83.217.77.146])
        by com-bemback010.mailprotect.be (Dovecot) with LMTP id 88kPHehnPmQ0IwAAYfQt7g
        for <bounces@mine.com>; Tue, 18 Apr 2023 11:50:32 +0200
Received: from com-bemdirector001.mailprotect.be ([83.217.77.146])
        by com-bemdirector002.mailprotect.be (Dovecot) with LMTP id pcFTCehnPmSq2gAAQ2+l/g
        ; Tue, 18 Apr 2023 11:50:32 +0200
Received: from com-basicem-smtp006.srv.combell-ops.net ([178.208.39.158] helo=smtp06.mailprotect.be)
        by com-bemdirector001.mailprotect.be with esmtp (Exim 4.89)
        id 1pohyq-0008iT-9f
        for bounces@mine.com; Tue, 18 Apr 2023 11:50:32 +0200
Received: from gateway.mailprotect.be (gateway.mailprotect.be [178.208.39.177])
        by smtp06.mailprotect.be (Postfix) with ESMTP id 355FE141625
        for <bounces@mine.com>; Tue, 18 Apr 2023 11:50:32 +0200 (CEST)
Received: from localhost (localhost [127.0.0.1])
        by gateway.mailprotect.be (Postfix) with ESMTP id 2CDA634423
        for <bounces@mine.com>; Tue, 18 Apr 2023 11:50:32 +0200 (CEST)
Received: from gateway.mailprotect.be ([127.0.0.1])
        by localhost (gateway.mailprotect.be [127.0.0.1]) (amavisd-new, port 10025)
        with ESMTP id q3bTjBYIqaN5 for <bounces@mine.com>;
        Tue, 18 Apr 2023 11:50:31 +0200 (CEST)
Received: from mx.mailprotect.be (mx.mailprotect.be [178.208.39.142])
        by gateway.mailprotect.be (Postfix) with ESMTP id DB15A3430A
        for <bounces@mine.com>; Tue, 18 Apr 2023 11:50:31 +0200 (CEST)
Received: from filter1-ams.surfmailfilter.nl (filter1-ams.surfmailfilter.nl [192.87.106.162])
        (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
         key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256)
        (No client certificate requested)
        by mx.mailprotect.be (Postfix) with ESMTPS id 216BBC01F6
        for <bounces@mine.com>; Tue, 18 Apr 2023 11:50:31 +0200 (CEST)
From: SURFmailfilter Postmaster <postmaster@mail.surfmailfilter.nl>
To: bounces@mine.com
Date: Tue, 18 Apr 2023 11:50:31 +0200
Message-ID: <75005cf3-ddce-11ed-8ef5-005056a3ec54@filter1-ams.surfmailfilter.nl>
Subject: Undeliverable: Mine registratie
References: <348117b3979d1d08b00d16279477c873@mine.com>
In-Reply-To: <348117b3979d1d08b00d16279477c873@mine.com>
Auto-Submitted: auto-replied
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
        boundary="75005cf3-ddce-11ed-8ef5-005056a3ec54"
X-Mail-From:

This is a multipart message in MIME format.

--75005cf3-ddce-11ed-8ef5-005056a3ec54
Content-Description: Delivery Status Notification
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit

This is the mail system at host filter1-ams.surfmailfilter.nl.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

<them@theirs.com> failed: host 132.229.101.213 said: 550 5.1.10
 RESOLVER.ADR.RecipientNotFound; Recipient not found by SMTP address lookup (in
 reply to EOD command)

--75005cf3-ddce-11ed-8ef5-005056a3ec54
Content-Description: Delivery Status Report
Content-Type: message/delivery-status

Reporting-MTA: dns; filter1-ams.surfmailfilter.nl
Received-from-MTA: dns; prod.mine.com (83.217.77.197)
Arrival-Date: Tue, 18 Apr 2023 11:50:30 +0200
X-Original-ID: 74411e8c-ddce-11ed-8ef5-005056a3ec54

Final-Recipient: rfc822; them@theirs.com
Action: failed
Status: 5.1.10
Remote-MTA: dns; 132.229.101.213
Diagnostic-Code: smtp; 550 5.1.10 RESOLVER.ADR.RecipientNotFound; Recipient not
 found by SMTP address lookup (in reply to EOD command)

--75005cf3-ddce-11ed-8ef5-005056a3ec54
Content-Description: Undelivered Message Headers
Content-Type: text/rfc822-headers

Received: from prod.mine.com (prod.mine.com [83.217.77.197])
        by filter1-ams.surfmailfilter.nl (Halon) with ESMTPS
        id 74411e8c-ddce-11ed-8ef5-005056a3ec54;
        Tue, 18 Apr 2023 11:50:30 +0200 (CEST)
Received: from mine.com (localhost [127.0.0.1])
        by prod.mine.com (Postfix) with ESMTP id 0933E6167C
        for <them@theirs.com>; Tue, 18 Apr 2023 11:50:30 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mine.com; s=prod;
        t=1681811430; bh=wVgLtYfUZFyq/Y6JV9B6/c2mJ+ZWOu+PozUNEr5Npks=;
        h=Date:Subject:From:To:From;
        b=OqlWJxYZbdB3POaNNSNV2ob5qUwD8P68fsHcQr4vpOF6GdHpaDn9NdTHFkABUlXgi
         3Xa3JYfk07YUg2SkGv41sJCSVAinZRP0WXQG5mTBpUNhCLMOmIKAvgiUuWXKSRDa9m
         rOPx8JOhtTiwEQZC5BSNvW5oTvAcQ4HMk9aQcMOS15B4q3BLFC7SozC3Xt/Lxh6wDu
         UnFzip65ema+lZyo/4VA+kfcQy1rYEZfv/vbwtO58nZ/4AC83LI9S5Fn/jSsWDNMam
         3fbhxkiDFv4LQoEl2x8uFfwCQ/IFOr504szOw81b3xBR0kjhkkGUWpZGgw/H2d8OD+
         v7yTt/GDrGlQA==
Sender: bounces@mine.com
Message-ID: <348117b3979d1d08b00d16279477c873@mine.com>
Date: Tue, 18 Apr 2023 11:50:29 +0200
Subject: Mine registratie
From: Mine <info@mine.com>
To: them@theirs.com
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

--75005cf3-ddce-11ed-8ef5-005056a3ec54--
Slamdunk commented 1 year ago

Interesting, never heard about RFC822-HEADERS before.

Would you like to propose a PR with a fix? It will be very much appreciated :heart:

rudiedirkx commented 1 year ago

I was afraid you'd say that =) I'll give it a shot, but there's a lot of package interfaces that have to remain BC, so it's not easy. The RFC822-HEADERS part is a kind of message interface, but without content, but with all the headers, so what interfaces is it..?