TidSMTPRelay mis-firing OnConnected Event?

Giganews Newsgroups
Subject: TidSMTPRelay mis-firing OnConnected Event?
Posted by:  Khurram Zaveri (no.spam@spam.com)
Date: Wed, 12 Mar 2008

I am using the TidSMTPRelay class in a TThread descendant. While testing the
application behind a firewall (with a 192... DNS address).

In the connected event of the SMTPRelay class, I set a global boolean
variable to true, indicating that the connection was successful. In this
case, however, thats wouldn't be possible.

Is there a way to stop this behaviour (or work around it) so that I can
figure out the true status of the email address and/or connection. The code
for the class is below.

--
Thank You
Khurram Zaveri

unit uDeliveryRelayThread;

interface

uses
  SysUtils, Classes, Windows, uDeliveryMisc, uDeliveryStatus,
uDeliveryThreadBase,
  IdGlobal, IdMessage,  IdSMTP, IdBaseComponent,
  IdIOHandler, IdIOHandlerSocket, IdSSLOpenSSL, IdAntiFreezeBase,
  IdAntiFreeze, IdExplicitTLSClientServerBase, IdSMTPBase, IdIOHandlerStack,
  IdSSL, IdException, IdComponent, IdSASLLogin, IdSASL_CRAM_MD5,
IdSASLAnonymous,
  IdUserPassProvider, IdSMTPRelay, IdCustomTransparentProxy, IdEMailAddress,
  Dialogs;
type
  TDeliveryRelayThread = class(TDeliveryThreadBase)
  private
    tryConnectingCount: Integer;
    //
    hasConnected:Boolean;
    //
    FTransparentProxy: TIdCustomTransparentProxy;
    //
    FDNSServer: string;
    FIdSMTPRelay: TIdSMTPRelay;
    //
    procedure SMTPFailedRecipients(Sender: TObject; const AAddress,
      ACode, AText: string; var VContinue: Boolean);

    procedure DirectSMTPStatus(Sender: TObject;
      AEMailAddress: TIdEMailAddressItem; Action: TIdSMTPRelayStatusAction);
    //
    procedure OnSMTPConnected(Sender: TObject);
  public
    procedure Execute; override;
    procedure DoTerminate; override;
    constructor Create;
    destructor Destroy; override;
    //
  published
    //
    property DNSServer: string read FDNSServer write FDNSServer;
    //
    property TransparentProxy: TIdCustomTransparentProxy read
FTransparentProxy write FTransparentProxy;
    procedure TerminateConnection;override;
  end;

implementation

{ TBISMTPRelayThread }

constructor TDeliveryRelayThread.Create;
begin
  inherited Create;

  FIdSMTPRelay := TIdSMTPRelay.Create;
  //
  FIdSMTPRelay.ReadTimeout := 10 * 1000;
  FIdSMTPRelay.ConnectTimeout := 10 * 1000;
  //
  FIdSMTPRelay.OnConnected := OnSMTPConnected;
  FIdSMTPRelay.OnDirectSMTPStatus := DirectSMTPStatus;
  FIdSMTPRelay.OnFailedRecipient := SMTPFailedRecipients;
end;

procedure TDeliveryRelayThread.TerminateConnection;
begin
  try
    if FIdSMTPRelay.Connected then
    begin
      if(Assigned(FIdSMTPRelay.Socket)) then
        if FIdSMTPRelay.Socket.Opened then
          FIdSMTPRelay.Socket.Close;
      FIdSMTPRelay.Disconnect;
    end;
  except
  end;
end;

destructor TDeliveryRelayThread.Destroy;
begin
  TerminateConnection;
  FIdSMTPRelay.Free;
  inherited;
end;

procedure TDeliveryRelayThread.DoTerminate;
begin
  TerminateConnection;
  inherited DoTerminate;
end;

procedure TDeliveryRelayThread.Execute;

begin
  tryConnectingCount := 0;
  //  Config IdSMTPRelay
  hasConnected := false;
  //
  with FIdSMTPRelay do
  begin
    DNSServer := FDNSServer;
    if Assigned(FTransparentProxy) then
      TransparentProxy := FTransparentProxy;
  end;

  try
    FIdSMTPRelay.Send(Msg);
  except
    on E:Exception do
    begin
      DoStatus(bisDNSTimeOut, '');
    end;
  end;
end;

procedure TDeliveryRelayThread.SMTPFailedRecipients(Sender: TObject; const
AAddress,
  ACode, AText: string; var VContinue: Boolean);
begin
  DoStatus(bisInvalidAddress, AText);
end;

procedure TDeliveryRelayThread.OnSMTPConnected(Sender: TObject);
begin
  hasConnected := true;
end;

procedure TDeliveryRelayThread.DirectSMTPStatus(Sender: TObject;
  AEMailAddress: TIdEMailAddressItem; Action: TIdSMTPRelayStatusAction);
var
  strStatus : String;
begin
  ///
  if Action = dmResolveMS then strStatus := 'Resolving DNS';
  if Action = dmConnecting then strStatus := 'Connecting';
  if Action = dmConnected then strStatus := 'Connected';
  if Action = dmSending then strStatus := 'Sending';

  // after dmResolveMS if we try connect
  if Action = dmConnecting then tryConnectingCount := tryConnectingCount +
1;
  if Action = dmWorkEndWithException then
  begin
    //
    if(hasConnected)then
    begin
      DoStatus(bisInvalidAddress, '');
    end
    else
    begin
      if(tryConnectingCount = 0)then
      begin
        DoStatus(bisInvalidDomain, '');
      end
      else
      begin
        DoStatus(bisDNSTimeOut, '');
      end;
    end;
  end;
  if Action = dmWorkEndOK then
  begin
    DoStatus(bisSent, '');
  end;
end;

end.

Replies