IdMappedTelnet.pas 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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.4 11/15/04 11:32:50 AM RLebeau
  18. Bug fix for OutboundConnect() assigning the IOHandler.ConnectTimeout property
  19. before the IOHandler has been assigned.
  20. Rev 1.3 11/14/04 11:40:00 AM RLebeau
  21. Removed typecast in OutboundConnect()
  22. Rev 1.2 2004.02.03 5:45:52 PM czhower
  23. Name changes
  24. Rev 1.1 2/2/2004 4:12:02 PM JPMugaas
  25. Should now compile in DotNET.
  26. Rev 1.0 2/1/2004 4:22:50 AM JPMugaas
  27. Components from IdMappedPort are now in their own units.
  28. }
  29. unit IdMappedTelnet;
  30. interface
  31. {$i IdCompilerDefines.inc}
  32. uses
  33. IdAssignedNumbers,
  34. IdMappedPortTCP;
  35. type
  36. TIdMappedTelnetContext = class(TIdMappedPortContext)
  37. protected
  38. FAllowedConnectAttempts: Integer;
  39. FErrorMsg: String;
  40. //
  41. procedure OutboundConnect; override;
  42. public
  43. property AllowedConnectAttempts: Integer read FAllowedConnectAttempts;
  44. property ErrorMsg: String read FErrorMsg;
  45. end;
  46. TIdMappedTelnetCheckHostPort = procedure (AContext: TIdMappedPortContext; const AHostPort: String; var VHost, VPort: String) of object;
  47. TIdCustomMappedTelnet = class (TIdMappedPortTCP)
  48. protected
  49. FAllowedConnectAttempts: Integer;
  50. FOnCheckHostPort: TIdMappedTelnetCheckHostPort;
  51. procedure DoCheckHostPort (AContext: TIdMappedPortContext; const AHostPort: String; var VHost, VPort: String); virtual;
  52. procedure SetAllowedConnectAttempts(const Value: Integer);
  53. procedure ExtractHostAndPortFromLine(AContext: TIdMappedPortContext; const AHostPort: String);
  54. procedure InitComponent; override;
  55. public
  56. //
  57. property AllowedConnectAttempts: Integer read FAllowedConnectAttempts write SetAllowedConnectAttempts default -1;
  58. //
  59. property OnCheckHostPort: TIdMappedTelnetCheckHostPort read FOnCheckHostPort write FOnCheckHostPort;
  60. published
  61. property DefaultPort default IdPORT_TELNET;
  62. property MappedPort default IdPORT_TELNET;
  63. end;
  64. TIdMappedTelnet = class (TIdCustomMappedTelnet)
  65. published
  66. property AllowedConnectAttempts: Integer read FAllowedConnectAttempts write SetAllowedConnectAttempts default -1;
  67. //
  68. property OnCheckHostPort: TIdMappedTelnetCheckHostPort read FOnCheckHostPort write FOnCheckHostPort;
  69. end;
  70. implementation
  71. uses
  72. IdGlobal, IdException, IdResourceStringsProtocols,
  73. IdTCPClient, SysUtils;
  74. const
  75. NAMESEP = #0+#9+' :'; {do not localize}
  76. { TIdCustomMappedTelnet }
  77. procedure TIdCustomMappedTelnet.InitComponent;
  78. begin
  79. inherited InitComponent;
  80. FAllowedConnectAttempts := -1;
  81. FContextClass := TIdMappedTelnetContext;
  82. DefaultPort := IdPORT_TELNET;
  83. MappedPort := IdPORT_TELNET;
  84. end;
  85. procedure TIdCustomMappedTelnet.DoCheckHostPort(AContext: TIdMappedPortContext;
  86. const AHostPort: String; var VHost, VPort: String);
  87. Begin
  88. if Assigned(FOnCheckHostPort) then begin
  89. FOnCheckHostPort(AContext, AHostPort, VHost, VPort);
  90. end;
  91. end;
  92. procedure TIdCustomMappedTelnet.ExtractHostAndPortFromLine(AContext: TIdMappedPortContext;
  93. const AHostPort: String);
  94. var
  95. LHost, LPort: String;
  96. i : Integer;
  97. Begin
  98. LHost := ''; {Do not Localize}
  99. LPort := ''; {Do not Localize}
  100. if Length(AHostPort) > 0 then
  101. begin
  102. i := 1;
  103. while (i <= Length(AHostPort)) and (not CharIsInSet(AHostPort, i, NAMESEP)) do
  104. begin
  105. LHost := LHost + AHostPort[i];
  106. Inc(i);
  107. end;
  108. Inc(i);
  109. while (i <= Length(AHostPort)) and (not CharIsInSet(AHostPort, i, NAMESEP)) do
  110. begin
  111. LPort := LPort + AHostPort[i];
  112. Inc(i);
  113. end;
  114. LHost := TrimRight(LHost);
  115. LPort := TrimLeft(LPort);
  116. end;
  117. DoCheckHostPort(AContext, AHostPort, LHost, LPort);
  118. if Length(LHost) > 0 then begin
  119. TIdTcpClient(AContext.OutboundClient).Host := LHost;
  120. end;
  121. if Length(LPort) > 0 then begin
  122. TIdTcpClient(AContext.OutboundClient).Port := IndyStrToInt(LPort, TIdTcpClient(AContext.OutboundClient).Port);
  123. end;
  124. end;
  125. procedure TIdMappedTelnetContext.OutboundConnect;
  126. var
  127. LHostPort: String;
  128. LServer: TIdCustomMappedTelnet;
  129. LClient: TIdTCPClient;
  130. begin
  131. //don`t call inherited, NEW behavior
  132. LServer := TIdCustomMappedTelnet(Server);
  133. FOutboundClient := TIdTCPClient.Create(nil);
  134. LClient := TIdTCPClient(FOutboundClient);
  135. LClient.Port := LServer.MappedPort;
  136. LClient.Host := LServer.MappedHost;
  137. FAllowedConnectAttempts := LServer.AllowedConnectAttempts;
  138. LServer.DoLocalClientConnect(Self);
  139. repeat
  140. if FAllowedConnectAttempts > 0 then begin
  141. Dec(FAllowedConnectAttempts);
  142. end;
  143. try
  144. LHostPort := Trim(Connection.IOHandler.InputLn); //~telnet input
  145. LServer.ExtractHostAndPortFromLine(Self, LHostPort);
  146. if Length(LClient.Host) < 1 then begin
  147. raise EIdException.Create(RSEmptyHost); // TODO: create a new Exception class for this
  148. end;
  149. LClient.ConnectTimeout := Self.FConnectTimeOut;
  150. LClient.Connect;
  151. except
  152. on E: Exception do // DONE: Handle connect failures
  153. begin
  154. FErrorMsg := 'ERROR: ['+E.ClassName+'] ' + E.Message; {Do not Localize}
  155. DoException(E);
  156. Connection.IOHandler.WriteLn(FErrorMsg);
  157. end;
  158. end;//trye
  159. until FOutboundClient.Connected or (FAllowedConnectAttempts = 0);
  160. if FOutboundClient.Connected then begin
  161. LServer.DoOutboundClientConnect(Self);
  162. end else begin
  163. Connection.Disconnect; //prevent all next work
  164. end;
  165. end;
  166. procedure TIdCustomMappedTelnet.SetAllowedConnectAttempts(const Value: Integer);
  167. Begin
  168. if Value >= 0 then begin
  169. FAllowedConnectAttempts := Value;
  170. end else begin
  171. FAllowedConnectAttempts := -1; //unlimited
  172. end;
  173. end;
  174. end.