mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-02-04 05:34:53 +01:00
537 lines
14 KiB
ObjectPascal
537 lines
14 KiB
ObjectPascal
{
|
|
$Id: header,v 1.1 2000/07/13 06:33:45 michael Exp $
|
|
This file is part of the Free Component Library (FCL)
|
|
Copyright (c) 1999-2000 by the Free Pascal development team
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
{$mode objfpc}
|
|
{$H+}
|
|
unit fpWeb;
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, httpdefs, fphttp, inifiles, fptemplate, websession;
|
|
|
|
Type
|
|
|
|
{ TFPWebAction }
|
|
|
|
TFPWebAction = Class(TCustomWebAction)
|
|
Private
|
|
FOnrequest: TWebActionEvent;
|
|
FContents : TStrings;
|
|
FTemplate : TFPTemplate;
|
|
function GetStringContent: String;
|
|
function GetContents: TStrings;
|
|
procedure SetContent(const AValue: String);
|
|
procedure SetContents(const AValue: TStrings);
|
|
Procedure SetTemplate(const AValue : TFPTemplate);
|
|
Protected
|
|
Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); override;
|
|
Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
|
|
Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
|
|
Procedure Assign(Source : TPersistent); override;
|
|
Public
|
|
Constructor create(ACollection : TCollection); override;
|
|
Destructor destroy; override;
|
|
published
|
|
Property Content : String Read GetStringContent Write SetContent;
|
|
Property Contents : TStrings Read GetContents Write SetContents;
|
|
Property OnRequest: TWebActionEvent Read FOnrequest Write FOnrequest;
|
|
Property Template : TFPTemplate Read FTemplate Write SetTemplate;
|
|
end;
|
|
|
|
{ TFPWebActions }
|
|
|
|
TFPWebActions = Class(TCustomWebActions)
|
|
Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); virtual;
|
|
Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
|
|
Public
|
|
Property ActionVar;
|
|
end;
|
|
|
|
{ TTemplateVar }
|
|
|
|
|
|
TTemplateVar = Class(TCollectionItem)
|
|
Private
|
|
FName: String;
|
|
FValue: String;
|
|
Public
|
|
Procedure Assign(Source : TPersistent); override;
|
|
Function GetDisplayName : String; override;
|
|
Published
|
|
Property Name : String Read FName Write FName;
|
|
Property Value : String Read FValue Write FValue;
|
|
end;
|
|
|
|
{ TTemplateVars }
|
|
|
|
TTemplateVars = Class(TCollection)
|
|
Private
|
|
function GetVar(I : Integer): TTemplateVar;
|
|
procedure Setvar(I : Integer; const AValue: TTemplateVar);
|
|
Public
|
|
Function IndexOfVar(AName : String) : Integer;
|
|
Function VarByName(AName : String) : TTemplateVar;
|
|
Function FindVar(AName : String) : TTemplateVar;
|
|
Property Variables[I : Integer] : TTemplateVar Read GetVar Write Setvar; default;
|
|
end;
|
|
|
|
TContentEvent = Procedure (Sender : TObject; Content : TStream) of object;
|
|
|
|
{ TCustomFPWebModule }
|
|
|
|
TCustomFPWebModule = Class(TSessionHTTPModule)
|
|
private
|
|
FActions: TFPWebActions;
|
|
FAfterResponse: TResponseEvent;
|
|
FBeforeRequest: TRequestEvent;
|
|
FOnGetParam: TGetParamEvent;
|
|
FOnRequest: TWebActionEvent;
|
|
FTemplate: TFPTemplate;
|
|
FTemplateVars : TTemplateVars;
|
|
function GetActionVar: String;
|
|
function GetOnGetAction: TGetActionEvent;
|
|
procedure SetActions(const AValue: TFPWebActions);
|
|
procedure SetActionVar(const AValue: String);
|
|
procedure SetOnGetAction(const AValue: TGetActionEvent);
|
|
procedure SetTemplate(const AValue: TFPTemplate);
|
|
|
|
Protected
|
|
Procedure DoBeforeRequest(ARequest : TRequest); virtual;
|
|
Procedure DoAfterResponse(AResponse : TResponse); virtual;
|
|
Procedure GetParam(Const ParamName : String; Out Value : String); virtual; // Called by template
|
|
Procedure GetTemplateContent(ARequest : TRequest; AResponse : TResponse); virtual;
|
|
function GetContent: String;virtual;
|
|
Public
|
|
Constructor CreateNew(AOwner : TComponent; CreateMode : Integer); override;
|
|
Destructor Destroy; override;
|
|
Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); override;
|
|
Property Actions : TFPWebActions Read FActions Write SetActions;
|
|
Property ActionVar : String Read GetActionVar Write SetActionVar;
|
|
Property BeforeRequest : TRequestEvent Read FBeforeRequest Write FBeforeRequest;
|
|
Property OnRequest : TWebActionEvent Read FOnRequest Write FOnRequest;
|
|
Property AfterResponse : TResponseEvent Read FAfterResponse Write FAfterResponse;
|
|
Property OnGetAction : TGetActionEvent Read GetOnGetAction Write SetOnGetAction;
|
|
Property Template : TFPTemplate Read FTemplate Write SetTemplate;
|
|
Property OnGetParam : TGetParamEvent Read FOnGetParam Write FOnGetParam;
|
|
Property OnTemplateContent : TGetParamEvent Read FOnGetParam Write FOnGetParam;
|
|
end;
|
|
|
|
{ TFPWebModule }
|
|
|
|
TFPWebModule = Class(TCustomFPWebModule)
|
|
Published
|
|
Property Actions;
|
|
Property ActionVar;
|
|
Property BeforeRequest;
|
|
Property OnRequest;
|
|
Property AfterResponse;
|
|
Property OnGetAction;
|
|
Property CreateSession;
|
|
Property Session;
|
|
Property OnNewSession;
|
|
Property OnSessionExpired;
|
|
end;
|
|
|
|
EFPWebError = Class(HTTPError);
|
|
|
|
resourcestring
|
|
SErrInvalidVar = 'Invalid template variable name : "%s"';
|
|
SErrInvalidWebAction = 'Invalid action for "%s".';
|
|
SErrNoContentProduced = 'No template content was produced.';
|
|
|
|
implementation
|
|
|
|
{$ifdef cgidebug}
|
|
uses dbugintf;
|
|
{$endif cgidebug}
|
|
|
|
procedure TFPWebAction.GetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
|
|
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TFPWebAction.Assign(Source: TPersistent);
|
|
|
|
Var
|
|
A : TFPWebAction;
|
|
|
|
begin
|
|
If (Source is TFPWebAction) then
|
|
begin
|
|
A:=Source as TFPWebAction;
|
|
Name:=A.Name;
|
|
Content:=A.Content;
|
|
AfterResponse:=A.AfterResponse;
|
|
BeforeRequest:=A.BeforeRequest;
|
|
Default:=A.default;
|
|
ContentProducer:=A.ContentProducer;
|
|
OnRequest:=A.OnRequest;
|
|
FTemplate.Assign(A.Template);
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
constructor TFPWebAction.create(ACollection: TCollection);
|
|
begin
|
|
inherited create(ACollection);
|
|
FTemplate:=TFPtemplate.Create;
|
|
end;
|
|
|
|
destructor TFPWebAction.destroy;
|
|
begin
|
|
FreeAndNil(FTemplate);
|
|
inherited destroy;
|
|
end;
|
|
|
|
function TFPWebAction.GetStringContent: String;
|
|
begin
|
|
Result:=Contents.Text;
|
|
end;
|
|
|
|
function TFPWebAction.GetContents: TStrings;
|
|
begin
|
|
If Not Assigned(FContents) then
|
|
FContents:=TStringList.Create;
|
|
Result:=FContents;
|
|
end;
|
|
|
|
procedure TFPWebAction.SetContent(const AValue: String);
|
|
begin
|
|
If (AValue='') then
|
|
FreeAndNil(FContents)
|
|
else
|
|
Contents.Text:=AValue;
|
|
end;
|
|
|
|
procedure TFPWebAction.SetContents(const AValue: TStrings);
|
|
begin
|
|
Contents.Assign(AValue);
|
|
end;
|
|
|
|
procedure TFPWebAction.SetTemplate(const AValue: TFPTemplate);
|
|
begin
|
|
If Assigned(AValue) then
|
|
FTemplate.Assign(AValue);
|
|
end;
|
|
|
|
|
|
procedure TFPWebAction.DoHandleRequest(ARequest: TRequest; AResponse: TResponse; Var Handled : Boolean);
|
|
|
|
begin
|
|
{$ifdef cgidebug}
|
|
SendMethodEnter('TFPWebAction('+Name+').Dohandlerequest');
|
|
If Handled then
|
|
SendDebug('Handled !!')
|
|
else
|
|
SendDebug('Not yet handled.');
|
|
{$endif cgidebug}
|
|
If Assigned(FOnRequest) then
|
|
begin
|
|
{$ifdef cgidebug}
|
|
SendDebug('Executing user action');
|
|
{$endif cgidebug}
|
|
FOnrequest(Self,Arequest,AResponse,Handled);
|
|
end;
|
|
If Not Handled then
|
|
begin
|
|
{$ifdef cgidebug}
|
|
SendDebug('Executing inherited');
|
|
{$endif cgidebug}
|
|
Inherited DoHandleRequest(ARequest,AResponse,Handled);
|
|
If not Handled then
|
|
begin
|
|
AResponse.Content:=Self.Content;
|
|
Handled:=(AResponse.Content<>'');
|
|
end;
|
|
end;
|
|
{$ifdef cgidebug}
|
|
SendMethodExit('TFPWebAction('+Name+').Dohandlerequest');
|
|
{$endif cgidebug}
|
|
end;
|
|
|
|
procedure TFPWebAction.DoGetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
|
|
|
|
begin
|
|
If Assigned(ContentProducer) then
|
|
ContentProducer.GetContent(ARequest,Content,Handled)
|
|
else
|
|
If (Self.Content<>'') then
|
|
Content.Write(Self.Content[1],Length(Self.Content));
|
|
end;
|
|
|
|
|
|
{ TFPWebTemplate }
|
|
Type
|
|
TFPWebTemplate = Class(TFPTemplate)
|
|
Private
|
|
FOwner: TCustomFPWebModule;
|
|
FRequest : TRequest;
|
|
Public
|
|
Constructor Create(AOwner :TCustomFPWebModule);
|
|
Procedure GetParam(Sender : TObject; Const ParamName : String; Out AValue : String);override;
|
|
Property Owner : TCustomFPWebModule Read FOwner;
|
|
Property Request : TRequest Read FRequest Write FRequest;
|
|
end;
|
|
|
|
constructor TFPWebTemplate.Create(AOwner: TCustomFPWebModule);
|
|
begin
|
|
Inherited create;
|
|
FOwner:=AOwner;
|
|
end;
|
|
|
|
procedure TFPWebTemplate.GetParam(Sender: TObject; const ParamName: String;
|
|
out AValue: String);
|
|
begin
|
|
FOwner.GetParam(ParamName, AValue);
|
|
end;
|
|
|
|
{ TFPWebModule }
|
|
|
|
function TCustomFPWebModule.GetActionVar: String;
|
|
begin
|
|
Result:=FActions.ActionVar;
|
|
end;
|
|
|
|
function TCustomFPWebModule.GetOnGetAction: TGetActionEvent;
|
|
begin
|
|
Result:=FActions.OnGetAction;
|
|
end;
|
|
|
|
|
|
procedure TCustomFPWebModule.SetActions(const AValue: TFPWebActions);
|
|
begin
|
|
if (FActions<>AValue) then;
|
|
FActions.Assign(AValue);
|
|
end;
|
|
|
|
procedure TCustomFPWebModule.SetActionVar(const AValue: String);
|
|
begin
|
|
FActions.ActionVar:=AValue;
|
|
end;
|
|
|
|
procedure TCustomFPWebModule.SetOnGetAction(const AValue: TGetActionEvent);
|
|
begin
|
|
FActions.OnGetAction:=AValue;
|
|
end;
|
|
|
|
|
|
procedure TCustomFPWebModule.SetTemplate(const AValue: TFPTemplate);
|
|
begin
|
|
if FTemplate<>AValue then
|
|
FTemplate.Assign(AValue);
|
|
end;
|
|
|
|
procedure TCustomFPWebModule.DoBeforeRequest(ARequest : TRequest);
|
|
begin
|
|
If Assigned(FBeforeRequest) then
|
|
FBeforeRequest(Self,ARequest);
|
|
end;
|
|
|
|
procedure TCustomFPWebModule.DoAfterResponse(AResponse : TResponse);
|
|
begin
|
|
If Assigned(FAfterResponse) then
|
|
FAfterResponse(Self,AResponse);
|
|
end;
|
|
|
|
procedure TCustomFPWebModule.GetParam(const ParamName: String; out Value: String);
|
|
|
|
Var
|
|
T : TTemplateVar;
|
|
|
|
begin
|
|
If (0=CompareText(ParamName,'CONTENT')) then
|
|
Value:=GetContent
|
|
else
|
|
begin
|
|
T:=FTemplateVars.FindVar(ParamName);
|
|
If (T<>Nil) then
|
|
Value:=T.Value
|
|
else
|
|
If Assigned(FOnGetParam) then
|
|
FOngetParam(Self,ParamName,Value);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomFPWebModule.GetTemplateContent(ARequest: TRequest;
|
|
AResponse: TResponse);
|
|
|
|
begin
|
|
TFPWebTemplate(FTemplate).Request:=ARequest;
|
|
AResponse.Content:=FTemplate.GetContent;
|
|
end;
|
|
|
|
function TCustomFPWebModule.GetContent: String;
|
|
|
|
Var
|
|
S : TStringStream;
|
|
B : Boolean;
|
|
|
|
begin
|
|
S:=TStringStream.Create('');
|
|
Try
|
|
FActions.GetContent(TFPWebTemplate(FTemplate).Request,S,B);
|
|
If Not B then
|
|
Raise EFPWebError.Create(SErrNoContentProduced);
|
|
Result:=S.DataString;
|
|
finally
|
|
S.Free;
|
|
end;
|
|
end;
|
|
|
|
constructor TCustomFPWebModule.CreateNew(AOwner: TComponent; CreateMode : Integer);
|
|
begin
|
|
inherited;
|
|
FActions:=TFPWebActions.Create(TFPWebAction);
|
|
FTemplate:=TFPWebTemplate.Create(Self);
|
|
FTemplateVars:=TTemplateVars.Create(TTemplateVar);
|
|
end;
|
|
|
|
destructor TCustomFPWebModule.Destroy;
|
|
begin
|
|
FreeAndNil(FTemplateVars);
|
|
FreeAndNil(FTemplate);
|
|
FreeAndNil(FActions);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
|
|
procedure TCustomFPWebModule.HandleRequest(ARequest: TRequest; AResponse: TResponse);
|
|
|
|
Var
|
|
B : Boolean;
|
|
|
|
begin
|
|
{$ifdef cgidebug}
|
|
SendMethodEnter('WebModule('+Name+').handlerequest');
|
|
{$endif cgidebug}
|
|
CheckSession(ARequest);
|
|
DoBeforeRequest(ARequest);
|
|
B:=False;
|
|
InitSession(AResponse);
|
|
If Assigned(FOnRequest) then
|
|
FOnRequest(Self,ARequest,AResponse,B);
|
|
If Not B then
|
|
if FTemplate.HasContent then
|
|
GetTemplateContent(ARequest,AResponse)
|
|
else
|
|
begin
|
|
Actions.HandleRequest(ARequest,AResponse,B);
|
|
If Not B then
|
|
Raise EFPWebError.Create(SErrRequestNotHandled);
|
|
end;
|
|
DoAfterResponse(AResponse);
|
|
UpdateSession(AResponse);
|
|
{$ifdef cgidebug}
|
|
SendMethodExit('WebModule('+Name+').handlerequest');
|
|
{$endif cgidebug}
|
|
end;
|
|
|
|
|
|
|
|
|
|
{ TTemplateVar }
|
|
|
|
procedure TTemplateVar.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TTemplateVar then
|
|
With Source as TTemplateVar do
|
|
begin
|
|
Self.Name:=Name;
|
|
Self.Value:=Value;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TTemplateVar.GetDisplayName: String;
|
|
begin
|
|
Result:=FName;
|
|
end;
|
|
|
|
{ TTemplateVars }
|
|
|
|
function TTemplateVars.GetVar(I : Integer): TTemplateVar;
|
|
begin
|
|
Result:=TTemplateVar(Items[I])
|
|
end;
|
|
|
|
procedure TTemplateVars.Setvar(I : Integer; const AValue: TTemplateVar);
|
|
begin
|
|
Items[i]:=AValue;
|
|
end;
|
|
|
|
function TTemplateVars.IndexOfVar(AName: String): Integer;
|
|
|
|
begin
|
|
Result:=Count-1;
|
|
While (Result>=0) and (CompareText(AName,GetVar(Result).Name)<>0) do
|
|
Dec(Result);
|
|
end;
|
|
|
|
function TTemplateVars.VarByName(AName: String): TTemplateVar;
|
|
begin
|
|
Result:=FindVar(AName);
|
|
If (Result=Nil) then
|
|
Raise EFPWebError.CreateFmt(SErrInvalidVar,[AName]);
|
|
end;
|
|
|
|
function TTemplateVars.FindVar(AName: String): TTemplateVar;
|
|
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
I:=IndexOfVar(AName);
|
|
If (I=-1) then
|
|
Result:=Nil
|
|
else
|
|
Result:=GetVar(I);
|
|
end;
|
|
|
|
{ TFPWebActions }
|
|
|
|
procedure TFPWebActions.HandleRequest(ARequest: TRequest; AResponse: TResponse; Var Handled : Boolean);
|
|
|
|
Var
|
|
A : TCustomWebAction;
|
|
|
|
begin
|
|
{$ifdef cgidebug}SendMethodEnter('FPWebActions.handlerequest');{$endif cgidebug}
|
|
A:=GetRequestAction(ARequest);
|
|
if Assigned(A) then
|
|
(A as TFPWebAction).HandleRequest(ARequest,AResponse,Handled);
|
|
{$ifdef cgidebug}SendMethodExit('FPWebActions.handlerequest');{$endif cgidebug}
|
|
end;
|
|
|
|
procedure TFPWebActions.GetContent(ARequest: TRequest; Content: TStream;
|
|
var Handled: Boolean);
|
|
|
|
Var
|
|
A : TCustomWebAction;
|
|
|
|
begin
|
|
{$ifdef cgidebug}SendMethodEnter('WebActions.GetContent');{$endif cgidebug}
|
|
A:=GetRequestAction(ARequest);
|
|
If A is TFPWebAction then
|
|
TFPWebAction(A).GetContent(ARequest,Content,Handled)
|
|
else
|
|
Raise EFPWebError.CreateFmt(SErrInvalidWebAction,[A.ClassName]);
|
|
{$ifdef cgidebug}SendMethodExit('WebActions.GetContent');{$endif cgidebug}
|
|
end;
|
|
|
|
end.
|
|
|