I have been fooling about with the SMTP client and server components in Indy 9 using demos with Delphi 7. Everything works fine. However, when I telnet into the server, the demo shows only the email subject and mail body, the From: and To: fields are not shown.
The code below shows that AMsg is lacking the relevant data.
procedure TForm1.IdSMTPServer1ReceiveMessageParsed(ASender: TIdCommand;
var AMsg: TIdMessage; RCPT: TIdEMailAddressList;
var CustomError: String);
begin
// This is the main event if you have opted to have the idSMTPServer to do your parsing for you.
// The AMessage contains the completed TIdMessage.
// NOTE: Dont forget to add IdMessage to your USES clause!
ToLabel.Caption := AMsg.Recipients.EMailAddresses;
FromLabel.Caption := AMsg.From.Text;
SubjectLabel.Caption := AMsg.Subject;
Memo1.Lines := AMsg.Body;
// Implement your file system here :)
end;
Can anybody suggest a reason? First of all, a thankyou to Remy for his response. Second, it seems I can't post images here, yet, but here is a link to images of server-telnet session https://postimg.org/image/f0n9j0kcx/. The telnet session shows the server responses. Thanks also for reminding me about Wireshark, and the suggestion of using a TIdLog component.
It is tricky to know for sure since you did not show the actual SMTP commands you are sending via Telnet, but you are likely missing required commands/data that
TIdSMTPsends. To see the actual SMTP commands/responses that are being exchanged, you can use a packet sniffer like Wireshark, or attach one of Indy'sTIdLog...components to theTIdSMTPand/orTIdSMTPServersocket connections.Any email address that is received via a
MAIL FROMcommand and accepted by the server (see theOnCommandMailevent) is passed to theOnReceive...events in theTIdSMTPServerThread(ASender.Thread).Fromproperty. The server will not accept aRCPT TOcommand if an email address has not been accepted fromMAIL FROMfirst. If you do not assign anOnCommandMailhandler, the server will accept any email address it receives.Any email addresses that are received via
RCPT TOcommands and accepted by the server (see theOnCommandRCPTevent) are passed to theOnReceive...events in theRCPTparameter, and also in theTIdSMTPServerThread(ASender.Thread).RCPTListproperty. The server will not accept aDATAcommand if at least one email address was not accepted fromRCPT TOfirst. If you do not assign anOnCommandRCPThandler, the server will accept every email address it receives.In the
OnReceiveMessage...events, the providedTIdMessageobject is first populated from the raw email data that is sent in theDATAcommand only. In the case of theOnReceiveMessageParsedevent only, any email addresses that were previously accepted viaRCPT TOare then merged into theTIdMessage.Recipientsproperty if they do not already exist. However, any email address received in theMAIL FROMcommand is not merged into theTIdMessage.Fromproperty.So, depending on what email data you are actually sending in the
DATAcommand, theAMsg.Fromproperty may or may not be empty. But theAMsg.Recipientsproperty certainly should not be.Also, something else to keep in mind -
TIdSMTPServeris multi-threaded (as most Indy servers are). Its events are fired in the context of worker threads, not the main UI thread. Your code is directly accessing VCL UI controls from outside of the main UI thread, which is not safe and can cause all kinds of problems. You must synchronize with the main UI thread, using either the VCL'sTThread.Synchronize()orTThread.Queue()methods, or Indy'sTIdSyncorTIdNotifyclasses, or any other thread-safe sync mechanism of your choosing, as long as the synced code runs in the context of the main UI thread only.