Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser::getRawHeader() may returns array #418

Merged
merged 3 commits into from
Jan 4, 2024

Conversation

anton-bel
Copy link
Contributor

@anton-bel anton-bel commented Apr 20, 2023

getRawHeader may return array, if the mail has multiple header lines, like a Received

@eXorus
Copy link
Member

eXorus commented Apr 20, 2023

Thanks, could you add a test?

@bendavies
Copy link

bendavies commented Sep 8, 2023

came looking for this as well.
getHeader('received') returns the first received header when there can often be many.
would be nice if there was a method to return an array here of all of the received headers, like https://github.com/laminas/laminas-mail/blob/2.24.x/src/Storage/Part.php#L341

@eXorus
Copy link
Member

eXorus commented Sep 20, 2023

Hello,

I tested it, but I couldn't reproduce the issue:

        $parser = new Parser();
        $parser->setText(<<<MIME
        From: expéditeur@example.com
        To: destinataire@example.com
        Subject: Exemple d'e-mail MIME avec en-tête Received
        Received: from mail.example.com (mail.example.com [192.168.1.1])
            by mx.example.net (Postfix) with ESMTPS id ABC12345
            for <destinataire@example.com>; Mon, 20 Sep 2023 10:00:00 -0400 (EDT)
            (envelope-from expéditeur@example.com)
            (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
            (No client certificate requested)
            by mail.example.com (Postfix) with ESMTPSA id DEF67890
            for <destinataire@example.com>; Mon, 20 Sep 2023 09:59:59 -0400 (EDT)
            (envelope-from expéditeur@example.com)

        Content-Type: multipart/mixed; boundary="frontière123"

        --frontière123
        Content-Type: text/plain

        Bonjour,

        Ceci est un exemple d'e-mail MIME avec un en-tête "Received" comprenant plusieurs lignes.

        Cordialement,
        Expéditeur

        --frontière123
        Content-Type: application/pdf; name="document.pdf"
        Content-Disposition: attachment; filename="document.pdf"

        [Contenu du fichier PDF ici]

        --frontière123--
        MIME
        );
        $subject = $parser->getHeader('Subject');
        $this->assertEquals("Exemple d'e-mail MIME avec en-tête Received", $subject);

        $received = $parser->getHeader('Received');
        $this->assertEquals("from mail.example.com (mail.example.com [192.168.1.1])    by mx.example.net (Postfix) with ESMTPS id ABC12345    for <destinataire@example.com>; Mon, 20 Sep 2023 10:00:00 -0400 (EDT)    (envelope-from expéditeur@example.com)    (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))    (No client certificate requested)    by mail.example.com (Postfix) with ESMTPSA id DEF67890    for <destinataire@example.com>; Mon, 20 Sep 2023 09:59:59 -0400 (EDT)    (envelope-from expéditeur@example.com)", $received);
        $received_raw = $parser->getRawHeader('Received');
        $this->assertEquals("from mail.example.com (mail.example.com [192.168.1.1])    by mx.example.net (Postfix) with ESMTPS id ABC12345    for <destinataire@example.com>; Mon, 20 Sep 2023 10:00:00 -0400 (EDT)    (envelope-from expéditeur@example.com)    (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))    (No client certificate requested)    by mail.example.com (Postfix) with ESMTPSA id DEF67890    for <destinataire@example.com>; Mon, 20 Sep 2023 09:59:59 -0400 (EDT)    (envelope-from expéditeur@example.com)", $received_raw);
        $headers = $parser->getHeaders();
        $this->assertEquals([
            'from' => 'expéditeur@example.com',
            'to' => 'destinataire@example.com',
            'subject' => "Exemple d'e-mail MIME avec en-tête Received",
            'received' => 'from mail.example.com (mail.example.com [192.168.1.1])    by mx.example.net (Postfix) with ESMTPS id ABC12345    for <destinataire@example.com>; Mon, 20 Sep 2023 10:00:00 -0400 (EDT)    (envelope-from expéditeur@example.com)    (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))    (No client certificate requested)    by mail.example.com (Postfix) with ESMTPSA id DEF67890    for <destinataire@example.com>; Mon, 20 Sep 2023 09:59:59 -0400 (EDT)    (envelope-from expéditeur@example.com)',
        ], $headers);

This test passed, which means that getHeader('received') or getHeaders()['received'] doesn't return an array but rather a string with X lines separated by spaces.

@eXorus
Copy link
Member

eXorus commented Sep 20, 2023

I was able to reproduce it with 2 headers, but it's an edge case that I'm not quite sure how to handle because in 99% of the cases, we just want to have a string and not an array.

        $parser = new Parser();
        $parser->setText(<<<MIME
        From: expéditeur@example.com
        To: destinataire@example.com
        Subject: Exemple d'e-mail MIME avec en-tête Received
        Received: from first line
        Received: from second line

        Content-Type: text/plain

        hello world!
        MIME
        );
        $subject = $parser->getHeader('Subject');
        $this->assertEquals("Exemple d'e-mail MIME avec en-tête Received", $subject);

        $received = $parser->getHeader('Received');
        $this->assertEquals("from first line", $received);
        $received_raw = $parser->getRawHeader('Received');
        $this->assertEquals(["from first line", "from second line"], $received_raw);
        $headers = $parser->getHeaders();
        $this->assertEquals([
            'from' => 'expéditeur@example.com',
            'to' => 'destinataire@example.com',
            'subject' => "Exemple d'e-mail MIME avec en-tête Received",
            'received' => ["from first line", "from second line"],
        ], $headers);

I agree that it's not ideal because getHeader and getHeaders should return the same type, but introducing a breaking change is inevitable.

@fresent
Copy link

fresent commented Dec 30, 2023

@eXorus I see the pull request is still open for this, can we please push this mainstream?
We are running into this exact thing.

A lot of ESPs using mail-channels are relay are returning multiple received headers, and mail-channels is a major relay.

@codecov-commenter
Copy link

codecov-commenter commented Jan 4, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (f8b14de) 97.00% compared to head (24cdfe8) 97.00%.

❗ Current head 24cdfe8 differs from pull request most recent head 5b5ad11. Consider uploading reports for the commit 5b5ad11 to get more accurate results

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff            @@
##               main     #418   +/-   ##
=========================================
  Coverage     97.00%   97.00%           
  Complexity      177      177           
=========================================
  Files             6        6           
  Lines           468      468           
=========================================
  Hits            454      454           
  Misses           14       14           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@eXorus eXorus merged commit e62934a into php-mime-mail-parser:main Jan 4, 2024
10 checks passed
@eXorus
Copy link
Member

eXorus commented Jan 4, 2024

I added the test and it's merged.
Thank you for the reminder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants