| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- unit IdTestSMTPServer;
- //odd: TIdCommandHandler.DoCommand: Response.Assign(Self.Response);
- interface
- uses
- IdGlobal,
- IdReplySMTP,
- IdTCPClient,
- IdSMTPServer,
- IdMessage,
- IdObjs,
- IdSMTP,
- IdSys,
- IdLogDebug,
- IdTest;
- type
- TIdTestSMTPServer = class(TIdTest)
- private
- FReceivedMsg:TIdMessage;
- FServer:TIdSMTPServer;
- FClient:TIdSMTP;
- FDebug:TIdLogDebug;
- //replace setup/teardown with virtuals
- procedure mySetup;
- procedure myTearDown;
- procedure CallbackRcptTo(ASender: TIdSMTPServerContext; const AAddress : string;
- var VAction : TIdRCPToReply; var VForward : string);
- procedure CallbackMsgReceive(ASender: TIdSMTPServerContext; AMsg : TIdStream;var LAction : TIdDataReply);
- procedure CallbackMailFrom(ASender: TIdSMTPServerContext; const AAddress : string;
- var VAction : TIdMailFromReply);
- published
- procedure TestGreeting;
- procedure TestReceive;
- procedure TestReject;
- end;
- implementation
- const
- cTestPort=20202;
- cSpammerAddress='[email protected]';
- procedure TIdTestSMTPServer.mySetup;
- begin
- Assert(FReceivedMsg=nil);
- FReceivedMsg:=TIdMessage.Create(nil);
- Assert(FServer=nil);
- FServer:=TIdSMTPServer.Create(nil);
- FServer.OnMsgReceive:=CallbackMsgReceive;
- FServer.OnRcptTo:=CallbackRcptTo;
- FServer.OnMailFrom:=CallbackMailFrom;
- FServer.DefaultPort:=cTestPort;
- FDebug:=TIdLogDebug.Create;
- Assert(FClient=nil);
- FClient:=TIdSMTP.Create(nil);
- FClient.ReadTimeout:=5000;
- FClient.Port:=cTestPort;
- FClient.Host:='127.0.0.1';
- FClient.CreateIOHandler;
- FClient.IOHandler.Intercept := FDebug;
- FDebug.Active := True;
- end;
- procedure TIdTestSMTPServer.myTearDown;
- begin
- FDebug.Active := False;
- Sys.FreeAndNil(FDebug);
- Sys.FreeAndNil(FClient);
- Sys.FreeAndNil(FServer);
- Sys.FreeAndNil(FReceivedMsg);
- end;
- procedure TIdTestSMTPServer.CallbackMailFrom(ASender: TIdSMTPServerContext;
- const AAddress: string; var VAction: TIdMailFromReply);
- begin
- if AAddress=cSpammerAddress then
- begin
- VAction:=mReject;
- end;
- end;
- procedure TIdTestSMTPServer.CallbackMsgReceive(
- ASender: TIdSMTPServerContext; AMsg: TIdStream;
- var LAction: TIdDataReply);
- var
- aList:TIdStringList;
- begin
- //do a precheck here.
- aList:=TIdStringList.Create;
- try
- AMsg.Position:=0;
- aList.Text:=ReadStringFromStream(AMsg);
- //should be at least headers for: received from subject to date
- //if this fails, then client hasn't written correctly, or server hasn't read
- Assert(aList.Count>=5);
- finally
- sys.FreeAndNil(aList);
- end;
- AMsg.Position:=0;
- FReceivedMsg.LoadFromStream(AMsg);
- end;
- procedure TIdTestSMTPServer.CallbackRcptTo(ASender: TIdSMTPServerContext;
- const AAddress: string; var VAction: TIdRCPToReply;
- var VForward: string);
- begin
- VAction:=rAddressOk;
- end;
- procedure TIdTestSMTPServer.TestGreeting;
- //checks that the server returns a correct greeting
- //uses tcpclient to check directly
- var
- s:string;
- aClient:TIdTCPClient;
- const
- cGreeting='HELLO';
- begin
- aClient:=TIdTCPClient.Create(nil);
- try
- mySetup;
- //Set a specific greeting, makes easy to test
- (FServer.Greeting as TIdReplySMTP).SetEnhReply(220, '' ,cGreeting);
- FServer.Active:=True;
- aClient.Port:=cTestPort;
- aClient.Host:='127.0.0.1';
- aClient.ReadTimeout:=5000;
- aClient.Connect;
- s:=aClient.IOHandler.Readln;
- //real example '220 mail.example.com ESMTP'
- Assert(s='220 '+cGreeting);
- aClient.Disconnect;
- finally
- Sys.FreeAndNil(aClient);
- myTearDown;
- end;
- end;
- procedure TIdTestSMTPServer.TestReceive;
- //do a round-trip message send using smtp client and server
- //repeat with/without client pipelining?
- var
- aMessage:TIdMessage;
- const
- cFrom='[email protected]';
- cSubject='mysubject';
- cBody='1,2,3';
- cAddress='[email protected]';
- cPriority:TIdMessagePriority=mpHigh;
- begin
- try
- mySetup;
- FServer.Active:=True;
- FClient.Connect;
- aMessage := TIdMessage.Create(nil);
- try
- aMessage.From.Address := cFrom;
- aMessage.Subject := cSubject;
- aMessage.Body.CommaText := cBody;
- //test with multiple recipients
- aMessage.Recipients.Add.Address := cAddress;
- aMessage.Priority :=cPriority;
- aMessage.Encoding := mePlaintext;
- FClient.Send(aMessage);
- finally
- Sys.FreeAndNil(aMessage);
- end;
- Assert(FClient.LastCmdResult.NumericCode =250, 'Code:' + Sys.IntToStr(FClient.LastCmdResult.NumericCode));
- //check that what the server received is same as sent
- Assert(FReceivedMsg.From.Address = cFrom, 'From:' + FReceivedMsg.From.Address);
- Assert(FReceivedMsg.Subject = cSubject, 'Subject:' + FReceivedMsg.Subject);
- Assert(FReceivedMsg.Body.CommaText = cBody, 'Body:' + FReceivedMsg.Body.CommaText);
- Assert(FReceivedMsg.Recipients.EMailAddresses = cAddress, 'To:' + FReceivedMsg.Recipients.EMailAddresses);
- Assert(FReceivedMsg.Priority = cPriority, 'Priority');
- //also check the "Received:" header
- //also check attachments
- //currently breaks due to ioHandler rev26
- finally
- myTearDown;
- end;
- end;
- procedure TIdTestSMTPServer.TestReject;
- //check that if a message is rejected by server, (here using OnMailFrom)
- //the correct status is returned.
- var
- aMessage:TIdMessage;
- begin
- try
- mySetup;
- FServer.Active:=True;
- FClient.Connect;
- aMessage:=TIdMessage.Create(nil);
- try
- aMessage.From.Address:=cSpammerAddress;
- aMessage.Subject:='spam';
- aMessage.Body.CommaText:='spam';
- aMessage.Recipients.Add.Address:='[email protected]';
- try
- FClient.Send(aMessage);
- except
- //want to ignore the exception here
- //EIdSMTPReplyError
- //check class,content
- on E : Exception do
- begin
- //You can NOT do:
- //
- //Assert(FClient.LastCmdResult.NumericCode = 550, FClient.LastCmdResult.FormattedReply.Text);
- //
- //because the exception may be from a line in a pipelined sequence and
- //LastCmdResult probably contains the result from the last command in the pipelined
- //sequence
- if E is EIdSMTPReplyError then
- begin
- with (E as EIdSMTPReplyError) do
- begin
- Assert( (E as EIdSMTPReplyError).ErrorCode = 550, (E as EIdSMTPReplyError).Message);
- end;
- end;
- end;
- end;
- finally
- Sys.FreeAndNil(aMessage);
- end;
- finally
- myTearDown;
- end;
- end;
- initialization
- TIdTest.RegisterTest(TIdTestSMTPServer);
- end.
|