开发者

Indy IdSMTP and attachments in Thunderbird

Using the latest snapshot of Indy tiburon on D20开发者_如何学JAVA10. A very simple project like:

var
  stream: TFileStream; (s is TidSMTP and m is TidMessage)
begin
  s.Connect;
  Stream := TFileStream.Create('c:\Test.zip', fmOpenRead or fmShareExclusive);
  try
    with TIdAttachmentMemory.Create(m.MessageParts, Stream) do
    begin
      ContentType := 'application/x-zip-compressed';
      Name := ExtractFilePath('C:\'); //'
      FileName := 'Test.zip';
    end;
  finally
    FreeAndNil(Stream);
  end;
  s.Send(m);
  s.Disconnect();
end;

Everything works Ok in Outlook, The bat!, OE, yahoo, etc... but in Thunderbird the attachment is not shown. Looking at the source of the message in Thunderbird, the attachment is there. The only difference I can find between messages send by indy and other clients is that Indy messages have this order:

Content-Type: multipart/mixed; boundary="Z\=_7oeC98yIhktvxiwiDTVyhv9R9gwkwT1"
MIME-Version: 1.0

while any other clients have the order:

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="Z\=_7oeC98yIhktvxiwiDTVyhv9R9gwkwT1"

Don't know if THAT is the source of the problem, but if so: is this a bug on Thunderbird or is this a problem with indy which "malforms" the headers of the messages? Is this order a problem? Does that matter anyway?


The latest version (as today) of Indy has a problem in the headers:

The problem seems to be around the line in the mail header with:

Content-Type: multipart/mixed; boundary="oIROJ8Yu4KsL8BbjOo0fc\=_O7oAqLVq97i"

The "=" inside the boundary identifier is prepended with a "\" (probably to escape it), but in the body of the mail the boundary looks like this:

--oIROJ8Yu4KsL8BbjOo0fc=_O7oAqLVq97i

If you look at the source of Indy, in the file idGlobalProtocols, ReplaceHeaderSubItem calls QuoteString, which is the one that adds the backslash. You could carefully change the logic here and recompile Indy.


RFC 1521 explicitly states:

Messages composed in accordance with this document MUST include such a header field, with the following verbatim text:

MIME-Version: 1.0

And note it is an header field:

Header fields are lines composed of a field name, followed by a colon (":"), followed by a field body, and terminated by CRLF. (rfc 2822)

Thereby if Indy does not set it as an header field it's an Indy bug, IMHO its syntax is invalid, it can't be set in the content-type line (maybe just a missing CRLF?) - and TB just follows the RFC verbatim, while the other know the RFC are often not followed completely and process the document anyay.


You should try something like this: (Note: The code doesn't show you how to send the message, just how to create it. There is another service that sends the emails).

Msg := TIdMessage.Create(nil);
try
  {create the message}
  Msg.Subject := Subject;
  with Msg.Recipients.Add do
  begin
    Text := EMailAddress;
  end;
  Msg.From.Address := From;
  Msg.From.Name := Copy(From, 1, pos('@', From) - 1);
  with Msg.ReplyTo.Add do
  begin
    Text := From;
  end;
  with TIdMessageBuilderHtml.Create do
  try
    {plain text}
    PlainText.Text := 'body text'
    {html body}
    Html.Text := '<html><body><p>' + 'body text' + '</p></body></html>';
    {attachments}
    for i := 0 to AttachFiles.Count - 1 do
        Attachments.Add(AttachFiles.Strings[i]);
    FillMessage(Msg);
  finally
    Free;
  end;
  {save the message for sending}
  Msg.NoEncode := False;
  Msg.NoDecode := False;
  Msg.SaveToFile(locfilename + TempExt);
finally
  Msg.Free;
end;

Answer to Rob Kennedy's comment bellow: I posted this code because for me, this code works with all major mail clients. The code is self explanatory, creates the message with attachments, saves it. I posted a solution that works. I don't have time (I'm at work) to compare the headers or message source of the original code the and the one posted by me to see why mine works. The original poster is free to do it and report back.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜