IdGopherServer.pas 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 10175: IdGopherServer.pas
  11. {
  12. { Rev 1.0 2002.11.12 10:39:44 PM czhower
  13. }
  14. unit IdGopherServer;
  15. interface
  16. {
  17. 2000-Apr-29 Pete Mee
  18. - Converted to new Indy format.
  19. 1999-Oct-03 Pete Mee
  20. - Gopher server is very basic... started & completed...
  21. }
  22. uses
  23. Classes,
  24. IdAssignedNumbers,
  25. IdTCPServer;
  26. {Typical connection:
  27. - Client attaches with no data
  28. - Server accepts with no data
  29. - Client sends request with CR LF termate (CRLF only for root)
  30. - Server sends items available each with CRLF termating
  31. - Server sends .CRLF
  32. - Server close connection
  33. }
  34. Type
  35. TRequestEvent = procedure(AThread: TIdPeerThread;ARequest:String) of object;
  36. TPlusRequestEvent = procedure(AThread: TIdPeerThread;ARequest:String;
  37. APlusData : String) of object;
  38. TIdGopherServer = class(TIdTCPServer)
  39. private
  40. fAdminEmail : String;
  41. fOnRequest:TRequestEvent;
  42. fOnPlusRequest : TPlusRequestEvent;
  43. fTruncateUserFriendly : Boolean;
  44. fTruncateLength : Integer;
  45. protected
  46. function DoExecute(Thread : TIdPeerThread): boolean; override;
  47. public
  48. constructor Create(AOwner : TComponent); override;
  49. function ReturnGopherItem(ItemType : Char;
  50. UserFriendlyName, RealResourceName : String;
  51. HostServer : String; HostPort : Integer): String;
  52. procedure SendDirectoryEntry(Thread : TIdPeerThread;
  53. ItemType : Char; UserFriendlyName, RealResourceName : String;
  54. HostServer : String; HostPort : Integer);
  55. procedure SetTruncateUserFriendlyName(truncate : Boolean);
  56. procedure SetTruncateLength(length : Integer);
  57. published
  58. property AdminEmail : String read fAdminEmail write fAdminEmail;
  59. property OnRequest: TRequestEvent read fOnRequest write fOnRequest;
  60. property OnPlusRequest : TPlusRequestEvent read fOnPlusRequest
  61. write fOnPlusRequest;
  62. property TruncateUserFriendlyName : Boolean read fTruncateUserFriendly
  63. write SetTruncateUserFriendlyName default True;
  64. property TruncateLength : Integer read fTruncateLength
  65. write SetTruncateLength default 70;
  66. end;
  67. implementation
  68. uses
  69. IdGlobal, IdGopherConsts, IdResourceStrings,
  70. SysUtils;
  71. constructor TIdGopherServer.Create(AOwner: TComponent);
  72. begin
  73. inherited Create(AOwner);
  74. DefaultPort := IdPORT_GOPHER;
  75. fAdminEmail := '<[email protected]>'; {Do not Localize}
  76. end;
  77. function TIdGopherServer.DoExecute(Thread: TIdPeerThread): boolean;
  78. var
  79. s : String;
  80. i : Integer;
  81. begin
  82. result := true;
  83. with Thread.Connection do begin
  84. while Connected do begin
  85. try
  86. s:=ReadLn;
  87. i := Pos(TAB, s);
  88. if i > 0 then begin
  89. // Is a Gopher+ request
  90. if Assigned(OnPlusRequest) then begin
  91. OnPlusRequest(Thread, Copy(s, 1, i - 1), Copy(s, i + 1, length(s)));
  92. end else if Assigned(OnRequest) then begin
  93. OnRequest(Thread, s);
  94. end else begin
  95. Thread.Connection.Write(IdGopherPlusData_ErrorBeginSign
  96. + IdGopherPlusError_NotAvailable
  97. + RSGopherServerNoProgramCode + EOL
  98. + IdGopherPlusData_EndSign);
  99. end;
  100. end else if Assigned(OnRequest) then begin
  101. OnRequest(Thread, s)
  102. end else begin
  103. Thread.Connection.Write(RSGopherServerNoProgramCode
  104. + EOL + IdGopherPlusData_EndSign);
  105. end;
  106. except
  107. break;
  108. end;
  109. Thread.Connection.Disconnect;
  110. end;
  111. end;
  112. end;
  113. function TIdGopherServer.ReturnGopherItem(ItemType : Char;
  114. UserFriendlyName, RealResourceName : String;
  115. HostServer : String; HostPort : Integer): String;
  116. begin
  117. if fTruncateUserFriendly then begin
  118. if (Length(UserFriendlyName) > fTruncateLength)
  119. and (fTruncateLength <> 0) then begin
  120. UserFriendlyName := Copy(UserFriendlyName, 1, fTruncateLength);
  121. end;
  122. end;
  123. result := ItemType + UserFriendlyName +
  124. TAB + RealResourceName + TAB + HostServer + TAB + IntToStr(HostPort);
  125. end;
  126. procedure TIdGopherServer.SendDirectoryEntry;
  127. {
  128. Format of server reply to directory (assume no spacing between - i.e.,
  129. one line, with CR LF at the end)
  130. - Item Type
  131. - User Description (without tab characters)
  132. - Tab
  133. - Server-assigned string to this individual Item Type resource
  134. - Tab
  135. - Domain Name of host
  136. - Tab
  137. - Port # of host
  138. }
  139. begin
  140. Thread.Connection.WriteLn(ReturnGopherItem(ItemType, UserFriendlyName,
  141. RealResourceName, HostServer, HostPort));
  142. end;
  143. procedure TIdGopherServer.SetTruncateUserFriendlyName;
  144. begin
  145. fTruncateUserFriendly := Truncate;
  146. end;
  147. procedure TIdGopherServer.SetTruncateLength;
  148. begin
  149. fTruncateLength := Length;
  150. end;
  151. end.