Incorrect boundary string in multipart/mixed message

旧城冷巷雨未停 提交于 2019-12-04 08:27:48

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.

Try this:

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; 

Or:

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; 

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.

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.

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 is a very tricky protocol to work with in general.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!