IdMappedPOP3.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. Rev 1.6 2/8/05 5:58:32 PM RLebeau
  18. Updated InitComponent() to call TIdReply.SetReply() instead of setting the
  19. Code and Text properties individually
  20. Rev 1.5 11/15/04 11:31:20 AM RLebeau
  21. Bug fix for OutboundConnect() assigning the IOHandler.ConnectTimeout property
  22. before the IOHandler has been assigned.
  23. Rev 1.4 11/14/04 11:39:24 AM RLebeau
  24. Updated OutboundConnect() to send the Greeting
  25. Rev 1.3 5/18/04 1:02:02 PM RLebeau
  26. Removed GetReplyClass() and GetRepliesClass() overrides.
  27. Rev 1.2 5/16/04 5:28:40 PM RLebeau
  28. Added GetReplyClass() and GetRepliesClass() overrides.
  29. Rev 1.1 2004.02.03 5:45:52 PM czhower
  30. Name changes
  31. Rev 1.0 2/2/2004 4:11:36 PM JPMugaas
  32. Recased to be consistant with IdPOP3 and IdPOP3Server. I also fixed several
  33. bugs that could cause AV's.
  34. Rev 1.0 2/1/2004 4:22:48 AM JPMugaas
  35. Components from IdMappedPort are now in their own units.
  36. }
  37. unit IdMappedPOP3;
  38. interface
  39. {$i IdCompilerDefines.inc}
  40. uses
  41. {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
  42. Classes,
  43. {$ENDIF}
  44. IdAssignedNumbers,
  45. IdMappedPortTCP, IdMappedTelnet, IdReplyPOP3;
  46. type
  47. TIdMappedPOP3Context = class (TIdMappedTelnetContext)
  48. protected
  49. FErrorMsg: String;
  50. FGreeting: String;
  51. FUserName: String;
  52. procedure OutboundConnect; override;
  53. public
  54. property ErrorMsg: String read FErrorMsg;
  55. property Greeting: String read FGreeting;
  56. property UserName: String read FUsername write FUserName;
  57. end;
  58. TIdMappedPOP3 = class (TIdMappedTelnet)
  59. protected
  60. FReplyUnknownCommand: TIdReplyPOP3;
  61. FGreeting: TIdReplyPOP3;
  62. FUserHostDelimiter: String;
  63. procedure InitComponent; override;
  64. procedure SetGreeting(AValue: TIdReplyPOP3);
  65. procedure SetReplyUnknownCommand(const AValue: TIdReplyPOP3);
  66. public
  67. {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
  68. constructor Create(AOwner: TComponent); reintroduce; overload;
  69. {$ENDIF}
  70. destructor Destroy; override;
  71. published
  72. property Greeting : TIdReplyPOP3 read FGreeting write SetGreeting;
  73. property ReplyUnknownCommand: TIdReplyPOP3 read FReplyUnknownCommand
  74. write SetReplyUnknownCommand;
  75. property DefaultPort default IdPORT_POP3;
  76. property MappedPort default IdPORT_POP3;
  77. property UserHostDelimiter: String read FUserHostDelimiter write FUserHostDelimiter;
  78. end;
  79. implementation
  80. uses
  81. IdGlobal, IdException, IdResourceStringsProtocols,
  82. IdTCPClient, IdTCPConnection, SysUtils;
  83. { TIdMappedPOP3 }
  84. {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
  85. constructor TIdMappedPOP3.Create(AOwner: TComponent);
  86. begin
  87. inherited Create(AOwner);
  88. end;
  89. {$ENDIF}
  90. destructor TIdMappedPOP3.Destroy;
  91. begin
  92. FreeAndNil(FReplyUnknownCommand);
  93. FreeAndNil(FGreeting);
  94. inherited Destroy;
  95. end;
  96. procedure TIdMappedPOP3.InitComponent;
  97. Begin
  98. inherited InitComponent;
  99. FUserHostDelimiter := '#';//standard {Do not Localize}
  100. FGreeting := TIdReplyPOP3.Create(nil);
  101. FGreeting.SetReply('+OK', RSPop3ProxyGreeting); {Do not Localize}
  102. FReplyUnknownCommand := TIdReplyPOP3.Create(nil);
  103. FReplyUnknownCommand.SetReply('-ERR', RSPop3UnknownCommand); {Do not Localize}
  104. DefaultPort := IdPORT_POP3;
  105. MappedPort := IdPORT_POP3;
  106. FContextClass := TIdMappedPOP3Context;
  107. end;
  108. procedure TIdMappedPOP3.SetGreeting(AValue: TIdReplyPOP3);
  109. begin
  110. FGreeting.Assign(AValue);
  111. end;
  112. procedure TIdMappedPOP3.SetReplyUnknownCommand(const AValue: TIdReplyPOP3);
  113. begin
  114. FReplyUnknownCommand.Assign(AValue);
  115. end;
  116. { TIdMappedPOP3Context }
  117. procedure TIdMappedPOP3Context.OutboundConnect;
  118. var
  119. LHostPort, LPop3Cmd: String;
  120. LServer: TIdMappedPOP3;
  121. Begin
  122. //don`t call inherited, NEW behavior
  123. LServer := TIdMappedPOP3(Server);
  124. Connection.IOHandler.Write(LServer.Greeting.FormattedReply);
  125. FOutboundClient := TIdTCPClient.Create(nil);
  126. TIdTcpClient(FOutboundClient).Port := LServer.MappedPort;
  127. TIdTcpClient(FOutboundClient).Host := LServer.MappedHost;
  128. FAllowedConnectAttempts := LServer.AllowedConnectAttempts;
  129. LServer.DoLocalClientConnect(Self);
  130. repeat
  131. if FAllowedConnectAttempts > 0 then begin
  132. Dec(FAllowedConnectAttempts);
  133. end;
  134. try
  135. // Greeting
  136. LHostPort := Trim(Connection.IOHandler.ReadLn);//USER username#host OR QUIT
  137. LPop3Cmd := Fetch(LHostPort, ' ', True); {Do not Localize}
  138. if TextIsSame(LPop3Cmd, 'QUIT') then {Do not Localize}
  139. begin
  140. Connection.IOHandler.WriteLn('+OK ' + RSPop3QuitMsg); {Do not Localize}
  141. Connection.Disconnect;
  142. Break;
  143. end else if TextIsSame(LPop3Cmd, 'USER') then {Do not Localize}
  144. begin
  145. FUserName := Fetch(LHostPort, LServer.FUserHostDelimiter, True, False);//?:CaseSensetive
  146. LHostPort := TrimLeft(LHostPort); //TrimRight above
  147. LServer.ExtractHostAndPortFromLine(Self, LHostPort);
  148. end else begin
  149. Connection.IOHandler.Write(LServer.ReplyUnknownCommand.FormattedReply);
  150. Continue;
  151. end;//if
  152. if Length(TIdTCPClient(FOutboundClient).Host) < 1 then begin
  153. raise EIdException.Create(RSEmptyHost); // TODO: create a new Exception class for this
  154. end;
  155. TIdTCPClient(FOutboundClient).ConnectTimeout := FConnectTimeOut;
  156. TIdTCPClient(FOutboundClient).Connect;
  157. //Read Pop3 Banner for OnOutboundClientConnect
  158. FGreeting := FOutboundClient.IOHandler.ReadLn;
  159. FOutboundClient.IOHandler.WriteLn('USER ' + FUserName); {Do not Localize}
  160. except
  161. on E: Exception do // DONE: Handle connect failures
  162. begin
  163. FErrorMsg := '[' + E.ClassName + '] ' + E.Message; {Do not Localize}
  164. DoException(E);
  165. Connection.IOHandler.WriteLn('-ERR ' + FErrorMsg);
  166. end;
  167. end;//trye
  168. until FOutboundClient.Connected or (FAllowedConnectAttempts < 1);
  169. if FOutboundClient.Connected then begin
  170. LServer.DoOutboundClientConnect(Self);
  171. end else begin
  172. Connection.Disconnect; //prevent all next work
  173. end;
  174. end;
  175. end.