multipart / mixed消息中的边界字符串不正确 [英] Incorrect boundary string in multipart/mixed message

查看:1411
本文介绍了multipart / mixed消息中的边界字符串不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Delphi 2006,在个人使用专用应用程序中创建并发送带有附件的电子邮件。我发送带有TIdSMTP实例的消息,然后将副本放在具有TIdIMAP4实例的特定IMAP文件夹中。这一切都非常好地与使用BDS2006分发的Indy 10版本有一个例外:电子邮件头中的时间总是不正确。

I'm using Delphi 2006 to create and send an email message with an attachment in a personal-use-only application. I send the message with an instance of TIdSMTP, and then also put a copy into a specific IMAP folder with an instance of TIdIMAP4. This all works very nicely with the version of Indy 10 that was distributed with BDS2006, with one exception: the time is always incorrect in the email header.

我决定修复如果可以,并且在搜索解决方案之后,最合适的是获取最新的Indy 10快照并使用它。

I decided to fix that if I could, and after searching for a solution it seemed most reasonable to get the latest Indy 10 snapshot and use that.

将正确的时间放入电子邮件标题,但有一个新的问题。在IMAP文件夹中添加的邮件标题中的边界字符串与电子邮件正文中的内容不同! (请注意,通过SMTP发送的消息是正确的。)

That puts the correct time into the email header, but there's a new problem. The boundary string is now different in the header of the message that is added to the IMAP folder than what comes in the body of the email! (Please note that the message that was sent via SMTP is correct.)

这是与旧版本的Indy 10相关的头信息:

This is the relevant header information from the older version of Indy 10:

Content-Type: multipart/mixed; boundary="XNlC6OyS4QSiHY2U=_jsXyps6TR34pFNsh"
MIME-Version: 1.0
Date: Tue, 22 Nov 2011 09:11:58 +0000

A test of the BDS2006-bundled version of Indy

--XNlC6OyS4QSiHY2U=_jsXyps6TR34pFNsh
Content-Type: application/octet-stream;
        name="20111122.xls"

这是与Indy 10.5相同的标题信息.8(昨天安装的快照10_4702):

And this is the same header information from Indy 10.5.8 (snapshot 10_4702 which I installed yesterday):

Content-Type: multipart/mixed; boundary="CDbEncbFvL7RZdOJ3DOIRoRBs=_nBsbZms"
MIME-Version: 1.0
Date: Tue, 22 Nov 2011 07:33:46 -0600

investigating more deeply, why does the boundary indicator change?

--h=_WzGWJei29fng7SqdPpDh1nkJxJZhiGc
Content-Type: application/octet-stream;
    name="20111122.xls"

时间戳是固定的,但现在是边界字符串不正确结果是在邮件中似乎没有任何东西被添加到我的IMAP文件夹中。

The time stamp is fixed, but now the boundary string is incorrect. The result is that there appears to be nothing at all in the message that gets added to my IMAP folder.

以下是创建电子邮件和附件的相关代码,发送它,并将副本放入IMAP文件夹中:

Here is the relevant code that creates the email message and attachment, sends it, and puts a copy into the IMAP folder:

  FTheMsg.Date := Now;  // FTheMsg is a component dropped onto the form
  FTheMsg.Recipients.EMailAddresses := edMailTo.Text;
  FTheMsg.ClearBody;
  FTheMsg.Subject := 'Glucose Readings ' + FormatDateTime('mm/dd/yy', FStartDate) + ' - ' +
              FormatDateTime('mm/dd/yy', FEndDate);
  FTheMsg.Body.Assign(FMemo.Lines);

  // create the attachment
  TIdAttachmentFile.Create(FTheMsg.MessageParts, fileName);

  // send the mail!
  FSmtp.Host := FSMTPHost;  // values set up elsewhere, FSmtp is a component on the form
  FImap.Host := FIMAPHost;  // FImap is also a component on the form

  FSmtp.Connect;
  try
    FSmtp.Send(FTheMsg);
    FImap.Connect;
    try
      if (not FImap.AppendMsg('Sent Items', FTheMsg, FTheMsg.LastGeneratedHeaders, [mfSeen]))     then
        StatusBar1.Panels[4].Text := 'Failed append msg';
    finally
      FImap.Disconnect;
    end;
  finally
    FSmtp.Disconnect;
  end;

正如我所说,发送的电子邮件是正常的,正常显示。但是添加到我的IMAP文件夹(在上面的FImap.AppendMsg())中是不正确的。我试图通过代码来查看可能出错的地方,但坦白的说,我对Indy和各种电子邮件协议/ RFC都不够熟悉,以确定出了什么问题。关于我所有可以告诉的是,较旧的版本将邮件保存到临时文件,然后将其附加到文件夹,而较新版本将其保存到内存流。显然,有些东西与此不同,但我目前太无知,无法确定什么。

As I said, the email that gets sent is fine and displays properly. But the one that is added to my IMAP folder (in FImap.AppendMsg() above) is incorrect. I've attempted to trace through the code to see where it might be going wrong, but frankly, I'm not familiar enough with Indy and the various email protocols/RFCs to be able to determine what's going wrong. About all I can tell is that the older version saves the message to a temporary file before appending it to the folder, while the newer version saves it to a memory stream instead. Obviously, something is different about that, but I'm currently too ignorant to determine what.

有没有一种简单的方法来纠正旧版本的时间戳问题?如果是这样,对我来说这样做是正确的,因为一切似乎都是正确的。如果没有,还需要做些什么来解决这里显示的问题,不正确的边界字符串?

Is there a simple way to correct the timestamp problem in the old version? If so, that would be fine for my use, as everything else appears to be correct. If not, what else do I need to do to fix the problem exhibited here with the incorrect boundary string?

(因为这是一个严格用于我自己使用的应用程序,如果我必须,但不是在我的已发送邮件文件夹中的空出现副本,则可以使用不正确的日期。)

(As this is an application strictly for my own use, I can live with the incorrect date if I have to, but not with the "empty-appearing" copy in my 'Sent Items' folder.)

如果需要更多信息我很乐意为我提供任何东西。

If more information is needed, I'll gladly supply whatever I can.

推荐答案

不要使用 TIdMessage.Body 属性用于在附件存在时保存文本。将文本改为 TIdText 对象。更好的是,使用 TIdMessageBuilder ... 类,例如 TIdMessageBuilderPlain ,以准备

Don't use the TIdMessage.Body property to hold your text when an attachment is present. Put the text into a TIdText object instead. Even better, use the TIdMessageBuilder... classes, such as TIdMessageBuilderPlain, to prepare the TIdMessage body for you.

尝试这样:

FTheMsg.Clear; 
FTheMsg.Date := Now;  // FTheMsg is a component dropped onto the form 
FTheMsg.Recipients.EMailAddresses := edMailTo.Text; 
FTheMsg.Subject := 'Glucose Readings ' + FormatDateTime('mm/dd/yy', FStartDate) + ' - ' + FormatDateTime('mm/dd/yy', FEndDate); 
FTheMsg.ContentType := 'multipart/mixed'; 

TIdText.Create(FTheMsg.MessageParts, FMemo.Lines).ContentType := 'text/plain';
TIdAttachmentFile.Create(FTheMsg.MessageParts, fileName); 

FSmtp.Connect; 
try 
  FSmtp.Send(FTheMsg); 
  FImap.Connect; 
  try 
    if (not FImap.AppendMsg('Sent Items', FTheMsg, nil, [mfSeen])) then 
      StatusBar1.Panels[4].Text := 'Failed append msg'; 
  finally 
    FImap.Disconnect; 
  end; 
finally 
  FSmtp.Disconnect; 
end; 

或:

FTheMsg.Clear; 
FTheMsg.Date := Now;  // FTheMsg is a component dropped onto the form 
FTheMsg.Recipients.EMailAddresses := edMailTo.Text; 
FTheMsg.Subject := 'Glucose Readings ' + FormatDateTime('mm/dd/yy', FStartDate) + ' - ' + FormatDateTime('mm/dd/yy', FEndDate); 

with TIdMessageBuilderPlain.Create do
try
  PlainText.Assign(FMemo.Lines);
  Attachments.Add(fileName); 
  FillMessage(FTheMsg);
finally
  Free;
end;

FSmtp.Connect; 
try 
  FSmtp.Send(FTheMsg); 
  FImap.Connect; 
  try 
    if (not FImap.AppendMsg('Sent Items', FTheMsg, nil, [mfSeen])) then 
      StatusBar1.Panels[4].Text := 'Failed append msg'; 
  finally 
    FImap.Disconnect; 
  end; 
finally 
  FSmtp.Disconnect; 
end; 

现在,就这样说,它可能仍然无法正常工作。 TIdIMAP4.AppendMsg()调用 TIdMessage.SaveToStream()内部,这会重新生成电子邮件内容(从而更改身体中使用的边界)。是否传递预先存在的 TIdMessage.LastGeneratedHeaders 或让 TIdIMAP4.AppendMsg()抓住当前 TIdMessage.Headers ,它们将与 TIdMessage.SaveToStream()生成的新边界不同步。

Now, with that said, it is likely that it will still not work correctly either way. TIdIMAP4.AppendMsg() calls TIdMessage.SaveToStream() internally, which regenerates the email content fresh (and thus alters the boundary used in the body). Whether you pass in the pre-existing TIdMessage.LastGeneratedHeaders or let TIdIMAP4.AppendMsg() grab the current TIdMessage.Headers, they will be out of sync with the new boundary that TIdMessage.SaveToStream() generates.

为了确保SMTP和IMAP4都同步,他们需要接收相同的数据。首先手动调用 TIdMessage.SaveToStream(),将 TIdMessage.NoEncode 属性设置为False,然后设置 TIdMessage.NoDecode 属性为True并调用 TIdMessage.LoadFromStream()将保存的数据按原样重新加载到 TIdMessage.Headers TIdMessage.Body 属性,然后调用 TIdSMTP.Send() TIdIMAP4.AppendMsg(),将 TIdMessage.NoEncode 属性设置为True,以便 TIdMessage.Headers TIdMessage.Body 按原样发送。

To make sure both SMTP and IMAP4 are in sync, they need to receive the same data. Try calling TIdMessage.SaveToStream() manually first with the TIdMessage.NoEncode property set to False, then set the TIdMessage.NoDecode property to True and call TIdMessage.LoadFromStream() to reload the saved data as-is into the TIdMessage.Headers and TIdMessage.Body properties, then call TIdSMTP.Send() and TIdIMAP4.AppendMsg() with the TIdMessage.NoEncode property set to True so the TIdMessage.Headers and TIdMessage.Body are sent as-is.

我知道,这违反了 TIdIMAP4.AppendMsg() comments / docs所说的做法。 AppendMsg()根本没有考虑MIME,所以它不能保证标题和正文中的MIME边界彼此匹配。我会尝试检查一下修复。对于Indy 11,Indy的整个MIME处理系统将被重新设计,所以我将确保可以保留边界和/或指定自定义边界,所以 AppendMsg()可以更好地匹配身体边界到标题边界。

I know, this goes against what the TIdIMAP4.AppendMsg() comments/docs say to do. AppendMsg() does not currently take MIME into account at all, so it does not ensure the MIME boundary in the header and body match each other. I will try to check in a fix for that. For Indy 11, Indy's entire MIME handling system is going to be redesigned, so I'll make sure it is possible to preserve boundaries, and/or to specify custom boundaries, so AppendMsg() can match the body boundary to the header boundary better.

IMAP4是一个非常棘手的协议,通常使用。

IMAP4 is a very tricky protocol to work with in general.

这篇关于multipart / mixed消息中的边界字符串不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆