Would be nice to be able to send message from stream

Giganews Newsgroups
Subject: Would be nice to be able to send message from stream
Posted by:  Charles Molnar (charles.moln…@micotan.com)
Date: Tue, 24 Aug 2004

Hi

I've created an smtp relay server, which is saving the whole traffic
into SQL server. Don't ask why, and don't tell me how stupid it is. I
know it is stupid, but we need this stuff desperately. ;-)

When the IdSMTPServerReceiveRaw event appears I grab the incoming stream
and put it in a BLOB, of course save the Bcc as well as the other
parameters for search purposes: from, to, cc, etc...

My other thread picks it up and would send it, here comes the problem
though: There's no way to send the "original" message because I'm forced
to load the message stream into either TIdMessage object via
LoadFromStream or use the TIdMessageClient.ProcessMessage function.
Both ways the original message will be changed and I can tell you that
sometimes the attachments are gone.

Anyway, this is what I did to make it work:
I added a new SendRaw function to the TIdSMTP class which is sending an
email based only on the given parameters. Of course the smtp host, port,
auth, etc... is still defined by the component's properties.

{$ifdef INDY_SMTP_EXTRA}
procedure TIdSMTP.SendRaw(AFrom: TIdEmailAddressItem; ARecipients,
ACCList, ABccList: TIdEmailAddressList; AData: TStream);

  procedure WriteRecipient(const AEmailAddress: TIdEmailAddressItem);
  begin
    SendCmd('RCPT TO:<' + AEMailAddress.Address + '>', [250, 251]);
{Do not Localize}
  end;

  procedure WriteRecipients(AList: TIdEmailAddressList);
  var
    i: integer;
  begin
    for i := 0 to AList.Count - 1 do begin
      WriteRecipient(AList[i]);
    end;
  end;

  function NeedToAuthenticate: Boolean;
  begin
    if FAuthenticationType <> atNone then begin
      Result := IsAuthProtocolAvailable(FAuthenticationType) and
(FDidAuthenticate = False);
    end else begin
      Result := False;
    end;
  end;

begin
  SendCmd('RSET');    {Do not Localize}
  if NeedToAuthenticate then begin
    Authenticate;
  end;
  SendCmd('MAIL FROM:<' + AFrom.Address + '>', 250);    {Do not Localize}
  WriteRecipients(ARecipients);
  WriteRecipients(ACCList);
  WriteRecipients(ABccList);
  SendCmd('DATA', 354);    {Do not Localize}
  AData.Position := 0;
  WriteStream( AData );
  SendCmd('.', 250);    {Do not Localize}
end;
{$endif}

I doubled those three local functions, to make the changes easy to track
or disable. But if it would go into the indy core it is not necessary.

Let me know if anyone of you knew a better solution or a solution
without touching the indy code.

Thanks,

--
Charles Molnar
Software Development
Micotan Software Company Ltd.

Replies