Re: trouble with TIdSMTPServer and BCC

Giganews Newsgroups
Subject: Re: trouble with TIdSMTPServer and BCC
Posted by:  Remy Lebeau (TeamB) (no.spam@no.spam.com)
Date: Wed, 5 Oct 2005

"Alessandro" <petrelliRIMUO…@interfree.it> wrote in message
news:C743CB2AC8DCE240petrelliRIMUO…@interfree.it...

> Everything works correctly, except the fact that original
> BCC addresses get lost.

As well you should be.  BCC addresses are never delivered to recipients.
That is the whole point of the BCC feature - only the SMTP server that
receives the original message knows about the addresses, but recipients that
the message is delivered to will never see them.

>      Log(Msg.BccList.EMailAddresses);    <--- BCCList is empty

You are looking in the wrong place, and you are handling the addresses
incorrectly anyway.

The BCC recipients are never stored in the BccList property for received
messages.  The original email data that is transmitted to the server by the
client never contains the BCC recipients in its headers.  As such, the BCC
addresses are not contained in the TStream that is provided by the
OnMsgReceive event.  That is by design, not just by Indy but in all e-mail
systems in general.

The intended recipients for a message are transmitted to the server
separately then the message data.  That is what allows the BCC feature to
work, since the server still knows about the BCC recipients even though they
are not contained in the actual message data.  The client sends a RCPT TO
command, one per intended recipient, to the server.  Once all of the
recipients have been transmitted to the server, the client then transmits
the actual message data via the DATA command.

The list of intended recipients includes all of the TO, CC, and BCC
recipients.  The server has no way of differentiating between them, nor does
it need to do so anyway.  In the OnMsgReceive event, the list of recipients
is stored in the ASender.RCPTList property, and the the contents of the
TStream should be delivered as-is to all of the recipients in that list.  No
assumptions should be made on the contents of the TStream at all (unless you
are filtering for spam, virus, etc).  For example:

    procedure TEmailProxyService.SMTPServerMsgReceive(ASender:
TIdSMTPServerContext; AMsg: TStream; var LAction: TIdDataReply);
    var
        i: integer;
        item: TIdEMailAddressItem;
    begin
        for i := 0 to Pred(ASender.RCPTList.Count) do
        begin
            // deliver the contents of AMsg to ASender.RCPTList[i].Address
...
        end;
        //...
    end;

If you need to use TIdMessage with TIdSMTP to send the message to someone
else's SMTP server, then after you load the TIdMessage with the TStream
contents, you can then fill in the TIdMessage.BCCList by checking which of
the addresses in the ASender.RCPTList property are not already contained in
the TIdMessage's Recpients and CCList properties.

Also, I strongly suggest that you set the TIdMessage's NoEncode and NoDecode
properties to True so that Indy does not parse, and thus accidently alter,
the original contents of the TStream when re-transmitting it to another
server.

Gambit

Replies

In response to

trouble with TIdSMTPServer and BCC posted by Alessandro on Wed, 5 Oct 2005