message partList and bounced recognizer
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Mail\Account\GroupAccount;
|
||||
|
||||
use Espo\Core\Mail\Message;
|
||||
use Espo\Core\Mail\Message\Part;
|
||||
|
||||
class BouncedRecognizer
|
||||
{
|
||||
public function isBounced(Message $message): bool
|
||||
{
|
||||
$from = $message->getHeader('From');
|
||||
$contentType = $message->getHeader('Content-Type');
|
||||
|
||||
if (preg_match('/MAILER-DAEMON|POSTMASTER/i', $from ?? '')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strpos($contentType ?? '', 'multipart/report') === 0) {
|
||||
// @todo Check whether ever works.
|
||||
$deliveryStatusPart = $this->getDeliveryStatusPart($message);
|
||||
|
||||
if ($deliveryStatusPart) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$content = $message->getRawContent();
|
||||
|
||||
if (
|
||||
strpos($content, 'message/delivery-status') !== false &&
|
||||
strpos($content, 'Status: ') !== false
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isHard(Message $message): bool
|
||||
{
|
||||
$content = $message->getRawContent();
|
||||
|
||||
if (preg_match('/permanent[ ]*[error|failure]/', $content)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function extractQueueItemId(Message $message): ?string
|
||||
{
|
||||
$content = $message->getRawContent();
|
||||
|
||||
if (preg_match('/X-Queue-Item-Id: [a-z0-9\-]*/', $content, $m)) {
|
||||
/** @var array{string} */
|
||||
$arr = preg_split('/X-Queue-Item-Id: /', $m[0], -1, \PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
$to = $message->getHeader('to');
|
||||
|
||||
if (preg_match('/\+bounce-qid-[a-z0-9\-]*/', $to ?? '', $m)) {
|
||||
/** @var array{string} */
|
||||
$arr = preg_split('/\+bounce-qid-/', $m[0], -1, \PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getDeliveryStatusPart(Message $message): ?Part
|
||||
{
|
||||
foreach ($message->getPartList() as $part) {
|
||||
if ($part->getContentType() === 'message/delivery-status') {
|
||||
return $part;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ use Espo\Core\Mail\Account\Hook\BeforeFetchResult;
|
||||
|
||||
use Espo\Core\Mail\Account\Account;
|
||||
use Espo\Core\Mail\Message;
|
||||
use Espo\Core\Mail\Account\GroupAccount\BouncedRecognizer;
|
||||
|
||||
use Espo\Core\Utils\Log;
|
||||
use Espo\Core\InjectableFactory;
|
||||
@@ -55,21 +56,25 @@ class BeforeFetch implements BeforeFetchInterface
|
||||
|
||||
private InjectableFactory $injectableFactory;
|
||||
|
||||
private BouncedRecognizer $bouncedRecognizer;
|
||||
|
||||
private ?CampaignService $campaignService = null;
|
||||
|
||||
public function __construct(Log $log, EntityManager $entityManager, InjectableFactory $injectableFactory)
|
||||
{
|
||||
public function __construct(
|
||||
Log $log,
|
||||
EntityManager $entityManager,
|
||||
InjectableFactory $injectableFactory,
|
||||
BouncedRecognizer $bouncedRecognizer
|
||||
) {
|
||||
$this->log = $log;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->injectableFactory = $injectableFactory;
|
||||
$this->bouncedRecognizer = $bouncedRecognizer;
|
||||
}
|
||||
|
||||
public function process(Account $account, Message $message): BeforeFetchResult
|
||||
{
|
||||
if (
|
||||
$message->hasHeader('from') &&
|
||||
preg_match('/MAILER-DAEMON|POSTMASTER/i', $message->getHeader('from') ?? '')
|
||||
) {
|
||||
if ($this->bouncedRecognizer->isBounced($message)) {
|
||||
try {
|
||||
$toSkip = $this->processBounced($message);
|
||||
}
|
||||
@@ -94,32 +99,8 @@ class BeforeFetch implements BeforeFetchInterface
|
||||
|
||||
private function processBounced(Message $message): bool
|
||||
{
|
||||
$content = $message->getRawContent();
|
||||
|
||||
$isHard = false;
|
||||
|
||||
if (preg_match('/permanent[ ]*[error|failure]/', $content)) {
|
||||
$isHard = true;
|
||||
}
|
||||
|
||||
$queueItemId = null;
|
||||
|
||||
if (preg_match('/X-Queue-Item-Id: [a-z0-9\-]*/', $content, $m)) {
|
||||
/** @var array{string} */
|
||||
$arr = preg_split('/X-Queue-Item-Id: /', $m[0], -1, \PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$queueItemId = $arr[0];
|
||||
}
|
||||
else {
|
||||
$to = $message->getHeader('to');
|
||||
|
||||
if (preg_match('/\+bounce-qid-[a-z0-9\-]*/', $to ?? '', $m)) {
|
||||
/** @var array{string} */
|
||||
$arr = preg_split('/\+bounce-qid-/', $m[0], -1, \PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$queueItemId = $arr[0];
|
||||
}
|
||||
}
|
||||
$isHard = $this->bouncedRecognizer->isHard($message);
|
||||
$queueItemId = $this->bouncedRecognizer->extractQueueItemId($message);
|
||||
|
||||
if (!$queueItemId) {
|
||||
return false;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
namespace Espo\Core\Mail;
|
||||
|
||||
use Espo\Core\Mail\Message\Part;
|
||||
|
||||
interface Message
|
||||
{
|
||||
/**
|
||||
@@ -67,4 +69,9 @@ interface Message
|
||||
* Whether contents is fetched.
|
||||
*/
|
||||
public function isFetched(): bool;
|
||||
|
||||
/**
|
||||
* @return Part[]
|
||||
*/
|
||||
public function getPartList(): array;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Mail\Message\MailMimeParser;
|
||||
|
||||
use Espo\Core\Mail\Message\Part as PartInterface;
|
||||
|
||||
use ZBateson\MailMimeParser\Message\Part\MessagePart;
|
||||
|
||||
class Part implements PartInterface
|
||||
{
|
||||
private MessagePart $part;
|
||||
|
||||
public function __construct(MessagePart $part)
|
||||
{
|
||||
$this->part = $part;
|
||||
}
|
||||
|
||||
public function getContentType(): ?string
|
||||
{
|
||||
return $this->part->getContentType();
|
||||
}
|
||||
|
||||
public function hasContent(): bool
|
||||
{
|
||||
return $this->part->hasContent();
|
||||
}
|
||||
|
||||
public function getContent(): ?string
|
||||
{
|
||||
return $this->part->getContent();
|
||||
}
|
||||
|
||||
public function getContentId(): ?string
|
||||
{
|
||||
return $this->part->getContentId();
|
||||
}
|
||||
|
||||
public function getCharset(): ?string
|
||||
{
|
||||
return $this->part->getCharset();
|
||||
}
|
||||
|
||||
public function getContentDisposition(): ?string
|
||||
{
|
||||
return $this->part->getContentDisposition();
|
||||
}
|
||||
|
||||
public function getFilename(): ?string
|
||||
{
|
||||
return $this->part->getFilename();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Mail\Message;
|
||||
|
||||
interface Part
|
||||
{
|
||||
public function getContentType(): ?string;
|
||||
|
||||
public function hasContent(): bool;
|
||||
|
||||
public function getContent(): ?string;
|
||||
|
||||
public function getContentId(): ?string;
|
||||
|
||||
public function getCharset(): ?string;
|
||||
|
||||
public function getContentDisposition(): ?string;
|
||||
|
||||
public function getFilename(): ?string;
|
||||
}
|
||||
@@ -30,6 +30,7 @@
|
||||
namespace Espo\Core\Mail;
|
||||
|
||||
use Espo\Core\Mail\Account\Storage;
|
||||
use Espo\Core\Mail\Message\Part;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
@@ -69,6 +70,17 @@ class MessageWrapper implements Message
|
||||
$this->storage = $storage;
|
||||
$this->parser = $parser;
|
||||
$this->fullRawContent = $fullRawContent;
|
||||
|
||||
if (
|
||||
!$storage &&
|
||||
$this->fullRawContent &&
|
||||
strpos($this->fullRawContent, "\r\n\r\n") !== false
|
||||
) {
|
||||
[$rawHeader, $rawBody] = explode("\r\n\r\n", $this->fullRawContent, 2);
|
||||
|
||||
$this->rawHeader = $rawHeader;
|
||||
$this->rawContent = $rawBody;
|
||||
}
|
||||
}
|
||||
|
||||
public function getRawHeader(): string
|
||||
@@ -133,4 +145,16 @@ class MessageWrapper implements Message
|
||||
{
|
||||
return (bool) $this->rawHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Part[]
|
||||
*/
|
||||
public function getPartList(): array
|
||||
{
|
||||
if (!$this->parser) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
return $this->parser->getPartList($this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Espo\Core\Mail;
|
||||
use Espo\Entities\Email;
|
||||
use Espo\Entities\Attachment;
|
||||
use Espo\Core\Mail\Message;
|
||||
use Espo\Core\Mail\Message\Part;
|
||||
|
||||
use stdClass;
|
||||
|
||||
@@ -56,4 +57,9 @@ interface Parser
|
||||
* @return Attachment[] A list of inline attachments.
|
||||
*/
|
||||
public function getInlineAttachmentList(Message $message, Email $email): array;
|
||||
|
||||
/**
|
||||
* @return Part[]
|
||||
*/
|
||||
public function getPartList(Message $message): array;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,10 @@ use Espo\Entities\Attachment;
|
||||
|
||||
use Espo\Core\Mail\Message;
|
||||
use Espo\Core\Mail\Parser;
|
||||
use Espo\Core\Mail\Message\Part;
|
||||
|
||||
use Espo\Core\Mail\Message\MailMimeParser\Part as WrapperPart;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use ZBateson\MailMimeParser\MailMimeParser as WrappeeParser;
|
||||
@@ -211,6 +215,22 @@ class MailMimeParser implements Parser
|
||||
return $addressList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Part[]
|
||||
*/
|
||||
public function getPartList(Message $message): array
|
||||
{
|
||||
$wrappeeList = $this->getMessage($message)->getChildParts();
|
||||
|
||||
$partList = [];
|
||||
|
||||
foreach ($wrappeeList as $wrappee) {
|
||||
$partList[] = new WrapperPart($wrappee);
|
||||
}
|
||||
|
||||
return $partList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Attachment[]
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail\Account;
|
||||
|
||||
use Espo\Core\Mail\Account\GroupAccount\BouncedRecognizer;
|
||||
use Espo\Core\Mail\MessageWrapper;
|
||||
use Espo\Core\Mail\Parsers\MailMimeParser;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
class BouncedRecognizerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected BouncedRecognizer $bouncedRecognizer;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->bouncedRecognizer = new BouncedRecognizer();
|
||||
}
|
||||
|
||||
private function createMessage(string $contents): MessageWrapper
|
||||
{
|
||||
$entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$parser = new MailMimeParser($entityManager);
|
||||
|
||||
return new MessageWrapper(0, null, $parser, $contents);
|
||||
}
|
||||
|
||||
public function testBounced1a(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/bounced_1.eml');
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertTrue($this->bouncedRecognizer->isBounced($message));
|
||||
$this->assertTrue($this->bouncedRecognizer->isHard($message));
|
||||
$this->assertEquals('0011aa', $this->bouncedRecognizer->extractQueueItemId($message));
|
||||
}
|
||||
|
||||
public function testBounced1b(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/bounced_1.eml');
|
||||
$contents = str_replace('MAILER-DAEMON', 'test', $contents);
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertTrue($this->bouncedRecognizer->isBounced($message));
|
||||
$this->assertTrue($this->bouncedRecognizer->isHard($message));
|
||||
}
|
||||
|
||||
public function testBounced2(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/bounced_2.eml');
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertTrue($this->bouncedRecognizer->isBounced($message));
|
||||
$this->assertFalse($this->bouncedRecognizer->isHard($message));
|
||||
}
|
||||
|
||||
public function testNotBounced1(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/test_email_1.eml');
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertFalse($this->bouncedRecognizer->isBounced($message));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
Delivered-To: me@test.com
|
||||
Received: by 10.213.9.17 with SMTP id j17csp4766ebj;
|
||||
Tue, 8 May 2012 20:34:50 -0700 (PDT)
|
||||
Received: by 10.182.207.10 with SMTP id ls10mr30733797obc.9.1336534489928;
|
||||
Tue, 08 May 2012 20:34:49 -0700 (PDT)
|
||||
Return-Path: <>
|
||||
Received: from mx3.name.com (mx3.name.com. [173.192.7.98])
|
||||
by mx.google.com with ESMTP id s3si768112obn.1.2012.05.08.20.34.49;
|
||||
Tue, 08 May 2012 20:34:49 -0700 (PDT)
|
||||
Received-SPF: pass (google.com: best guess record for domain of mx3.name.com designates 173.192.7.98 as permitted sender) client-ip=173.192.7.98;
|
||||
Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of mx3.name.com designates 173.192.7.98 as permitted sender) smtp.mail=
|
||||
Received-SPF: None (no SPF record) identity=helo; client-ip=199.255.192.13; helo=a192-13.smtp-out.amazonses.com; envelope-from=<>; receiver=info@test.com
|
||||
Received: from a192-13.smtp-out.amazonses.com (a192-13.smtp-out.amazonses.com [199.255.192.13])
|
||||
by mx3.name.com (Postfix) with ESMTP id 5972F6000074C
|
||||
for <info@test.com>; Tue, 8 May 2012 22:34:49 -0500 (CDT)
|
||||
X-Original-To: 000001372d0dbf88-76d26d51-9d96-468a-9071-318ba2c35003-000000@amazonses.com
|
||||
Delivered-To: 000001372d0dbf88-76d26d51-9d96-468a-9071-318ba2c35003-000000@amazonses.com
|
||||
Message-Id: <000001372fa9d596-ec772006-9987-11e1-8d9b-433290f94ba3-000000@email.amazonses.com>
|
||||
Date: Wed, 9 May 2012 03:34:48 +0000
|
||||
To: info+bounce-qid-0011aa@test.com
|
||||
From: MAILER-DAEMON@amazonses.com
|
||||
Subject: Delivery Status Notification (Failure)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/report; report-type=delivery-status; boundary="ACnzx.4lvBb052b.srYYd.CyGnkMZ"
|
||||
X-AWS-Outgoing: 199.255.192.13
|
||||
|
||||
--ACnzx.4lvBb052b.srYYd.CyGnkMZ
|
||||
content-type: text/plain;
|
||||
charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
The following message to <wrongster@test.com> was undeliverable.
|
||||
The reason for the problem:
|
||||
5.4.7 - Delivery expired (message too old) 'no valid ip addresses'
|
||||
|
||||
--ACnzx.4lvBb052b.srYYd.CyGnkMZ
|
||||
content-type: message/delivery-status
|
||||
|
||||
Reporting-MTA: dns; na-mm-outgoing-7101-bacon.iad7.amazon.com
|
||||
|
||||
Final-Recipient: rfc822;wrongster@test.com
|
||||
Action: failed
|
||||
Status: 5.0.0 (permanent failure)
|
||||
Diagnostic-Code: smtp; 5.4.7 - Delivery expired (message too old) 'no valid ip addresses' (delivery attempts: 0)
|
||||
|
||||
--ACnzx.4lvBb052b.srYYd.CyGnkMZ
|
||||
content-type: message/rfc822
|
||||
|
||||
Received: from unknown (HELO aws-bacon-dlvr-svc-na-i-986ddefa.us-east-1.amazon.com) ([10.13.133.79])
|
||||
by na-mm-outgoing-7101-bacon.iad7.amazon.com with ESMTP; 08 May 2012 16:15:55 +0000
|
||||
Return-Path: 000001372d0dbf88-76d26d51-9d96-468a-9071-318ba2c35003-000000@amazonses.com
|
||||
Date: Tue, 8 May 2012 15:25:04 +0000
|
||||
From: info@test.com
|
||||
To: wrongster@test.com
|
||||
Message-ID: <000001372d0dbf88-76d26d51-9d96-468a-9071-318ba2c35003-000000@email.amazonses.com>
|
||||
Subject: Test subject
|
||||
Mime-Version: 1.0
|
||||
Content-Type: text/plain;
|
||||
charset=UTF-8
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-AWS-Outgoing: 199.127.232.7
|
||||
|
||||
Test message.
|
||||
|
||||
--ACnzx.4lvBb052b.srYYd.CyGnkMZ--
|
||||
@@ -0,0 +1,41 @@
|
||||
Date: Thu, 7 Jul 1994 17:16:05 -0400
|
||||
From: Mail Delivery Subsystem
|
||||
<REPLACED_DAEMON@CS.UTK.EDU> Message-Id:
|
||||
<199407072116.RAA14128@CS.UTK.EDU>
|
||||
Subject: Returned mail: Cannot
|
||||
send message for 5 days
|
||||
To: <owner-info-mime@cs.utk.edu> MIME-Version: 1.0
|
||||
Content-Type: multipart/report; report-type=delivery-status; boundary="RAA14128.773615765/CS.UTK.EDU"
|
||||
|
||||
--RAA14128.773615765/CS.UTK.EDU
|
||||
|
||||
The original message was received at Sat, 2 Jul 1994 17:10:28 -0400
|
||||
from root@localhost
|
||||
|
||||
----- The following addresses had delivery problems -----
|
||||
<louisl@larry.slip.umd.edu> (unrecoverable error)
|
||||
|
||||
----- Transcript of session follows -----
|
||||
<louisl@larry.slip.umd.edu>... Deferred: Connection timed out
|
||||
with larry.slip.umd.edu.
|
||||
Message could not be delivered for 5 days
|
||||
Message will be deleted from queue
|
||||
|
||||
--RAA14128.773615765/CS.UTK.EDU
|
||||
content-type: message/delivery-status
|
||||
|
||||
Reporting-MTA: dns; cs.utk.edu
|
||||
|
||||
Original-Recipient: rfc822;louisl@larry.slip.umd.edu
|
||||
Final-Recipient: rfc822;louisl@larry.slip.umd.edu
|
||||
Action: failed
|
||||
Status: 4.0.0
|
||||
Diagnostic-Code: smtp; 426 connection timed out
|
||||
Last-Attempt-Date: Thu, 7 Jul 1994 17:15:49 -0400
|
||||
|
||||
--RAA14128.773615765/CS.UTK.EDU
|
||||
content-type: message/rfc822
|
||||
|
||||
[original message goes here]
|
||||
|
||||
--RAA14128.773615765/CS.UTK.EDU--
|
||||
Reference in New Issue
Block a user