2
0

IdGopherServer.pas 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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.7 12/2/2004 4:23:54 PM JPMugaas
  18. Adjusted for changes in Core.
  19. Rev 1.6 2004.02.03 5:44:48 PM czhower
  20. Name changes
  21. Rev 1.5 1/21/2004 3:26:46 PM JPMugaas
  22. InitComponent
  23. Rev 1.4 2/24/2003 08:54:00 PM JPMugaas
  24. Rev 1.3 1/17/2003 07:10:26 PM JPMugaas
  25. Now compiles under new framework.
  26. Rev 1.2 1-1-2003 20:13:12 BGooijen
  27. Changed to support the new TIdContext class
  28. Rev 1.1 12/6/2002 04:35:10 PM JPMugaas
  29. Now compiles with new code.
  30. Rev 1.0 11/13/2002 08:30:20 AM JPMugaas
  31. Initial import from FTP VC.
  32. 2000-Apr-29 Pete Mee
  33. - Converted to new Indy format.
  34. 1999-Oct-03 Pete Mee
  35. - Gopher server is very basic... started & completed...
  36. }
  37. unit IdGopherServer;
  38. interface
  39. {$i IdCompilerDefines.inc}
  40. uses
  41. Classes,
  42. IdAssignedNumbers,
  43. IdContext,
  44. IdCustomTCPServer,
  45. IdGlobal;
  46. {
  47. Typical connection:
  48. - Client attaches with no data
  49. - Server accepts with no data
  50. - Client sends request with CR LF termate (CRLF only for root)
  51. - Server sends items available each with CRLF termating
  52. - Server sends .CRLF
  53. - Server close connection
  54. }
  55. type
  56. TRequestEvent = procedure(AContext: TIdContext; ARequest: String) of object;
  57. TPlusRequestEvent = procedure(AContext: TIdContext; ARequest: String; APlusData: String) of object;
  58. TIdGopherServer = class(TIdCustomTCPServer)
  59. private
  60. fAdminEmail : String;
  61. fOnRequest : TRequestEvent;
  62. fOnPlusRequest : TPlusRequestEvent;
  63. fTruncateUserFriendly : Boolean;
  64. fTruncateLength : Integer;
  65. protected
  66. function DoExecute(AContext: TIdContext): Boolean; override;
  67. public
  68. constructor Create(AOwner: TComponent); override;
  69. function ReturnGopherItem(ItemType : Char;
  70. UserFriendlyName, RealResourceName : String;
  71. HostServer : String; HostPort : TIdPort): String;
  72. procedure SendDirectoryEntry(AContext:TIdContext;
  73. ItemType : Char; UserFriendlyName, RealResourceName : String;
  74. HostServer : String; HostPort : TIdPort);
  75. published
  76. property AdminEmail : String read fAdminEmail write fAdminEmail;
  77. property OnRequest: TRequestEvent read fOnRequest write fOnRequest;
  78. property OnPlusRequest : TPlusRequestEvent read fOnPlusRequest
  79. write fOnPlusRequest;
  80. property TruncateUserFriendlyName : Boolean read fTruncateUserFriendly
  81. write fTruncateUserFriendly default True;
  82. property TruncateLength : Integer read fTruncateLength
  83. write fTruncateLength default 70;
  84. property DefaultPort default IdPORT_GOPHER;
  85. end;
  86. implementation
  87. uses
  88. IdGopherConsts, IdResourceStringsProtocols, SysUtils;
  89. constructor TIdGopherServer.Create(AOwner: TComponent);
  90. begin
  91. inherited Create(AOwner);
  92. DefaultPort := IdPORT_GOPHER;
  93. fAdminEmail := '<[email protected]>'; {Do not Localize}
  94. fTruncateUserFriendly := True;
  95. fTruncateLength := 70;
  96. end;
  97. function TIdGopherServer.DoExecute(AContext: TIdContext): boolean;
  98. var
  99. s : String;
  100. i : Integer;
  101. begin
  102. Result := True;
  103. s := AContext.Connection.IOHandler.ReadLn;
  104. i := Pos(TAB, s);
  105. if i > 0 then begin
  106. // Is a Gopher+ request
  107. if Assigned(OnPlusRequest) then begin
  108. OnPlusRequest(AContext, Copy(s, 1, i - 1), Copy(s, i + 1, Length(s)));
  109. end else if Assigned(OnRequest) then begin
  110. OnRequest(AContext, s);
  111. end else begin
  112. AContext.Connection.IOHandler.Write(
  113. IdGopherPlusData_ErrorBeginSign
  114. + IdGopherPlusError_NotAvailable
  115. + RSGopherServerNoProgramCode + EOL
  116. + IdGopherPlusData_EndSign);
  117. end;
  118. end else if Assigned(OnRequest) then begin
  119. OnRequest(AContext, s);
  120. end else begin
  121. AContext.Connection.IOHandler.Write(RSGopherServerNoProgramCode + EOL + IdGopherPlusData_EndSign);
  122. end;
  123. AContext.Connection.Disconnect;
  124. end;
  125. function TIdGopherServer.ReturnGopherItem(ItemType : Char;
  126. UserFriendlyName, RealResourceName : String;
  127. HostServer : String; HostPort : TIdPort): String;
  128. begin
  129. if fTruncateUserFriendly then begin
  130. if (Length(UserFriendlyName) > fTruncateLength) and (fTruncateLength <> 0) then begin
  131. UserFriendlyName := Copy(UserFriendlyName, 1, fTruncateLength);
  132. end;
  133. end;
  134. Result := ItemType + UserFriendlyName +
  135. TAB + RealResourceName + TAB + HostServer + TAB + IntToStr(HostPort);
  136. end;
  137. procedure TIdGopherServer.SendDirectoryEntry;
  138. {
  139. Format of server reply to directory (assume no spacing between - i.e.,
  140. one line, with CR LF at the end)
  141. - Item Type
  142. - User Description (without tab characters)
  143. - Tab
  144. - Server-assigned string to this individual Item Type resource
  145. - Tab
  146. - Domain Name of host
  147. - Tab
  148. - Port # of host
  149. }
  150. begin
  151. AContext.Connection.IOHandler.WriteLn(
  152. ReturnGopherItem(ItemType, UserFriendlyName, RealResourceName, HostServer, HostPort)
  153. );
  154. end;
  155. end.