193 lines
5.4 KiB
Plaintext
193 lines
5.4 KiB
Plaintext
{
|
|
$Project$
|
|
$Workfile$
|
|
$Revision$
|
|
$DateUTC$
|
|
$Id$
|
|
|
|
This file is part of the Indy (Internet Direct) project, and is offered
|
|
under the dual-licensing agreement described on the Indy website.
|
|
(http://www.indyproject.org/)
|
|
|
|
Copyright:
|
|
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
|
}
|
|
{
|
|
$Log$
|
|
}
|
|
{
|
|
Rev 1.7 12/2/2004 4:23:54 PM JPMugaas
|
|
Adjusted for changes in Core.
|
|
|
|
Rev 1.6 2004.02.03 5:44:48 PM czhower
|
|
Name changes
|
|
|
|
Rev 1.5 1/21/2004 3:26:46 PM JPMugaas
|
|
InitComponent
|
|
|
|
Rev 1.4 2/24/2003 08:54:00 PM JPMugaas
|
|
|
|
Rev 1.3 1/17/2003 07:10:26 PM JPMugaas
|
|
Now compiles under new framework.
|
|
|
|
Rev 1.2 1-1-2003 20:13:12 BGooijen
|
|
Changed to support the new TIdContext class
|
|
|
|
Rev 1.1 12/6/2002 04:35:10 PM JPMugaas
|
|
Now compiles with new code.
|
|
|
|
Rev 1.0 11/13/2002 08:30:20 AM JPMugaas
|
|
Initial import from FTP VC.
|
|
|
|
2000-Apr-29 Pete Mee
|
|
- Converted to new Indy format.
|
|
|
|
1999-Oct-03 Pete Mee
|
|
- Gopher server is very basic... started & completed...
|
|
}
|
|
|
|
unit IdGopherServer;
|
|
|
|
interface
|
|
|
|
{$i IdCompilerDefines.inc}
|
|
|
|
uses
|
|
Classes,
|
|
IdAssignedNumbers,
|
|
IdContext,
|
|
IdCustomTCPServer,
|
|
IdGlobal;
|
|
|
|
{
|
|
Typical connection:
|
|
- Client attaches with no data
|
|
- Server accepts with no data
|
|
- Client sends request with CR LF termate (CRLF only for root)
|
|
- Server sends items available each with CRLF termating
|
|
- Server sends .CRLF
|
|
- Server close connection
|
|
}
|
|
|
|
type
|
|
TRequestEvent = procedure(AContext:TIdContext;ARequest:String) of object;
|
|
TPlusRequestEvent = procedure(AContext:TIdContext;ARequest:String;
|
|
APlusData : String) of object;
|
|
|
|
TIdGopherServer = class(TIdCustomTCPServer)
|
|
private
|
|
fAdminEmail : String;
|
|
|
|
fOnRequest : TRequestEvent;
|
|
fOnPlusRequest : TPlusRequestEvent;
|
|
|
|
fTruncateUserFriendly : Boolean;
|
|
fTruncateLength : Integer;
|
|
protected
|
|
function DoExecute(AContext: TIdContext): Boolean; override;
|
|
procedure InitComponent; override;
|
|
public
|
|
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
|
|
constructor Create(AOwner: TComponent); reintroduce; overload;
|
|
{$ENDIF}
|
|
function ReturnGopherItem(ItemType : Char;
|
|
UserFriendlyName, RealResourceName : String;
|
|
HostServer : String; HostPort : TIdPort): String;
|
|
procedure SendDirectoryEntry(AContext:TIdContext;
|
|
ItemType : Char; UserFriendlyName, RealResourceName : String;
|
|
HostServer : String; HostPort : TIdPort);
|
|
published
|
|
property AdminEmail : String read fAdminEmail write fAdminEmail;
|
|
property OnRequest: TRequestEvent read fOnRequest write fOnRequest;
|
|
property OnPlusRequest : TPlusRequestEvent read fOnPlusRequest
|
|
write fOnPlusRequest;
|
|
property TruncateUserFriendlyName : Boolean read fTruncateUserFriendly
|
|
write fTruncateUserFriendly default True;
|
|
property TruncateLength : Integer read fTruncateLength
|
|
write fTruncateLength default 70;
|
|
property DefaultPort default IdPORT_GOPHER;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
IdGopherConsts, IdResourceStringsProtocols, SysUtils;
|
|
|
|
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
|
|
constructor TIdGopherServer.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TIdGopherServer.InitComponent;
|
|
begin
|
|
inherited InitComponent;
|
|
DefaultPort := IdPORT_GOPHER;
|
|
fAdminEmail := '<gopher@domain.example>'; {Do not Localize}
|
|
fTruncateUserFriendly := True;
|
|
fTruncateLength := 70;
|
|
end;
|
|
|
|
function TIdGopherServer.DoExecute(AContext: TIdContext): boolean;
|
|
var
|
|
s : String;
|
|
i : Integer;
|
|
begin
|
|
Result := True;
|
|
s := AContext.Connection.IOHandler.ReadLn;
|
|
i := Pos(TAB, s);
|
|
if i > 0 then begin
|
|
// Is a Gopher+ request
|
|
if Assigned(OnPlusRequest) then begin
|
|
OnPlusRequest(AContext, Copy(s, 1, i - 1), Copy(s, i + 1, Length(s)));
|
|
end else if Assigned(OnRequest) then begin
|
|
OnRequest(AContext, s);
|
|
end else begin
|
|
AContext.Connection.IOHandler.Write(
|
|
IdGopherPlusData_ErrorBeginSign
|
|
+ IdGopherPlusError_NotAvailable
|
|
+ RSGopherServerNoProgramCode + EOL
|
|
+ IdGopherPlusData_EndSign);
|
|
end;
|
|
end else if Assigned(OnRequest) then begin
|
|
OnRequest(AContext, s);
|
|
end else begin
|
|
AContext.Connection.IOHandler.Write(RSGopherServerNoProgramCode + EOL + IdGopherPlusData_EndSign);
|
|
end;
|
|
AContext.Connection.Disconnect;
|
|
end;
|
|
|
|
function TIdGopherServer.ReturnGopherItem(ItemType : Char;
|
|
UserFriendlyName, RealResourceName : String;
|
|
HostServer : String; HostPort : TIdPort): String;
|
|
begin
|
|
if fTruncateUserFriendly then begin
|
|
if (Length(UserFriendlyName) > fTruncateLength) and (fTruncateLength <> 0) then begin
|
|
UserFriendlyName := Copy(UserFriendlyName, 1, fTruncateLength);
|
|
end;
|
|
end;
|
|
Result := ItemType + UserFriendlyName +
|
|
TAB + RealResourceName + TAB + HostServer + TAB + IntToStr(HostPort);
|
|
end;
|
|
|
|
procedure TIdGopherServer.SendDirectoryEntry;
|
|
{
|
|
Format of server reply to directory (assume no spacing between - i.e.,
|
|
one line, with CR LF at the end)
|
|
- Item Type
|
|
- User Description (without tab characters)
|
|
- Tab
|
|
- Server-assigned string to this individual Item Type resource
|
|
- Tab
|
|
- Domain Name of host
|
|
- Tab
|
|
- Port # of host
|
|
}
|
|
begin
|
|
AContext.Connection.IOHandler.WriteLn(ReturnGopherItem(ItemType, UserFriendlyName,
|
|
RealResourceName, HostServer, HostPort));
|
|
end;
|
|
|
|
end.
|