Repository URL to install this package:
Version:
3.0.0 ▾
|
{
$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, fptemplate;
Type
{ TFPWebAction }
TFPWebAction = Class(TCustomWebAction)
Private
FOnrequest: TWebActionEvent;
FContents : TStrings;
FTemplate : TFPTemplate;
function GetContents: TStrings;
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);
Public
Constructor create(ACollection : TCollection); override;
Destructor destroy; override;
Procedure Assign(Source : TPersistent); override;
published
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)
private
FCurrentAction : TCustomWebAction;
protected
Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); virtual;
Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
Public
Property ActionVar;
Property CurrentAction: TCustomWebAction read FCurrentAction;
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;
FRequest: TRequest;
FResponse: TResponse;
FTemplate: TFPTemplate;
FTemplateVars : TTemplateVars;
function GetActionVar: String;
function GetDefActionWhenUnknown: Boolean;
function GetOnGetAction: TGetActionEvent;
procedure SetActions(const AValue: TFPWebActions);
procedure SetActionVar(const AValue: String);
procedure SetDefActionWhenUnknown(const AValue: Boolean);
procedure SetOnGetAction(const AValue: TGetActionEvent);
procedure SetTemplate(const AValue: TFPTemplate);
Protected
Function HandleActions(ARequest : TRequest): Boolean; virtual;
procedure DoOnRequest(ARequest: TRequest; AResponse: TResponse; var AHandled: Boolean); virtual;
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 DefActionWhenUnknown : Boolean read GetDefActionWhenUnknown write SetDefActionWhenUnknown default true;
Property ModuleTemplate : TFPTemplate Read FTemplate Write SetTemplate;
Property OnGetParam : TGetParamEvent Read FOnGetParam Write FOnGetParam;
Property OnTemplateContent : TGetParamEvent Read FOnGetParam Write FOnGetParam;
Property Request: TRequest Read FRequest;
Property Response: TResponse Read FResponse;
end;
{ TFPWebModule }
TFPWebModule = Class(TCustomFPWebModule)
Published
Property Actions;
Property ActionVar;
Property BeforeRequest;
Property OnRequest;
Property AfterResponse;
Property OnGetAction;
Property DefActionWhenUnknown;
Property CreateSession;
Property Session;
property Kind;
Property OnNewSession;
Property OnSessionExpired;
Property AfterInitModule;
end;
EFPWebError = Class(EHTTP);
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}
{ TFPWebAction }
procedure TFPWebAction.GetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
begin
DoGetContent(ARequest, Content, Handled);
end;
procedure TFPWebAction.Assign(Source: TPersistent);
Var
A : TFPWebAction;
begin
If (Source is TFPWebAction) then
begin
A:=TFPWebAction(Source);
Name:=A.Name;
AfterResponse:=A.AfterResponse;
BeforeRequest:=A.BeforeRequest;
Default:=A.default;
Contents:=A.FContents;
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(FContents);
FreeAndNil(FTemplate);
inherited destroy;
end;
function TFPWebAction.GetContents: TStrings;
begin
If Not Assigned(FContents) then
FContents:=TStringList.Create;
Result:=FContents;
end;
procedure TFPWebAction.SetContents(const AValue: TStrings);
begin
if AValue = nil then
FreeAndNil(FContents)
else
Contents.Assign(AValue);
end;
procedure TFPWebAction.SetTemplate(const AValue: TFPTemplate);
begin
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
Handled := (FContents <> nil) and (FContents.Count > 0);
if Handled then
AResponse.Contents.AddStrings(FContents);
end;
end;
{$ifdef cgidebug}
SendMethodExit('TFPWebAction('+Name+').Dohandlerequest');
{$endif cgidebug}
end;
procedure TFPWebAction.DoGetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
//isolate string references in a subprocedure to avoid implicit exceptions in main procedure
procedure CopyContent;
var
ContentStr: String;
begin
if FContents <> nil then
begin
ContentStr := FContents.Text;
If ContentStr<>'' then
Content.Write(ContentStr[1],Length(ContentStr));
end;
end;
begin
If Assigned(ContentProducer) then
ContentProducer.GetContent(ARequest,Content,Handled)
else
CopyContent;
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.GetDefActionWhenUnknown: Boolean;
begin
Result:=FActions.DefActionWhenUnknown;
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.SetDefActionWhenUnknown(const AValue: Boolean);
begin
FActions.DefActionWhenUnknown:=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;
function TCustomFPWebModule.HandleActions(ARequest: TRequest): Boolean;
begin
Result:=True;
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
B:=False;
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.DoOnRequest(ARequest: TRequest; AResponse: TResponse; Var AHandled : Boolean);
begin
If Assigned(FOnRequest) then
FOnRequest(Self,ARequest,AResponse,AHandled);
end;
procedure TCustomFPWebModule.HandleRequest(ARequest: TRequest; AResponse: TResponse);
Var
B : Boolean;
begin
{$ifdef cgidebug}
SendMethodEnter('WebModule('+Name+').handlerequest');
{$endif cgidebug}
FRequest := ARequest; //So everything in the web module can access the current request variables
FResponse := AResponse;//So everything in the web module can access the current response variables
CheckSession(ARequest);
DoBeforeRequest(ARequest);
B:=False;
InitSession(AResponse);
DoOnRequest(ARequest,AResponse,B);
If B then
begin
if not AResponse.ContentSent then
AResponse.SendContent;
end
else
if FTemplate.HasContent then
GetTemplateContent(ARequest,AResponse)
else if HandleActions(ARequest) then
begin
Actions.HandleRequest(ARequest,AResponse,B);
FTemplate.Template := '';//if apache mod, then need to clear for next call because it is a webmodule global property,
FTemplate.FileName := '';//so following calls are OK and the above FTemplate.HasContent is not becoming True
If Not B then
Raise EFPWebError.Create(SErrRequestNotHandled);
end;
DoAfterResponse(AResponse);
UpdateSession(AResponse);
FRequest := Nil;
FResponse := Nil;
// Clean up session for the case the webmodule is used again
DoneSession;
{$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
begin
FCurrentAction := A;
(A as TFPWebAction).HandleRequest(ARequest,AResponse,Handled);
end;
{$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.