fpweb.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. {
  2. $Id: header,v 1.1 2000/07/13 06:33:45 michael Exp $
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$mode objfpc}
  12. {$H+}
  13. unit fpWeb;
  14. interface
  15. uses
  16. Classes, SysUtils, httpdefs, fphttp, inifiles, fptemplate, websession;
  17. Type
  18. { TFPWebAction }
  19. TFPWebAction = Class(TCustomWebAction)
  20. Private
  21. FOnrequest: TWebActionEvent;
  22. FContents : TStrings;
  23. FTemplate : TFPTemplate;
  24. function GetStringContent: String;
  25. function GetContents: TStrings;
  26. procedure SetContent(const AValue: String);
  27. procedure SetContents(const AValue: TStrings);
  28. Procedure SetTemplate(const AValue : TFPTemplate);
  29. Protected
  30. Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); override;
  31. Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
  32. Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
  33. Procedure Assign(Source : TPersistent); override;
  34. Public
  35. Constructor create(ACollection : TCollection); override;
  36. Destructor destroy; override;
  37. published
  38. Property Content : String Read GetStringContent Write SetContent;
  39. Property Contents : TStrings Read GetContents Write SetContents;
  40. Property OnRequest: TWebActionEvent Read FOnrequest Write FOnrequest;
  41. Property Template : TFPTemplate Read FTemplate Write SetTemplate;
  42. end;
  43. { TFPWebActions }
  44. TFPWebActions = Class(TCustomWebActions)
  45. private
  46. FCurrentAction : TCustomWebAction;
  47. protected
  48. Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); virtual;
  49. Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
  50. Public
  51. Property ActionVar;
  52. Property CurrentAction: TCustomWebAction read FCurrentAction;
  53. end;
  54. { TTemplateVar }
  55. TTemplateVar = Class(TCollectionItem)
  56. Private
  57. FName: String;
  58. FValue: String;
  59. Public
  60. Procedure Assign(Source : TPersistent); override;
  61. Function GetDisplayName : String; override;
  62. Published
  63. Property Name : String Read FName Write FName;
  64. Property Value : String Read FValue Write FValue;
  65. end;
  66. { TTemplateVars }
  67. TTemplateVars = Class(TCollection)
  68. Private
  69. function GetVar(I : Integer): TTemplateVar;
  70. procedure Setvar(I : Integer; const AValue: TTemplateVar);
  71. Public
  72. Function IndexOfVar(AName : String) : Integer;
  73. Function VarByName(AName : String) : TTemplateVar;
  74. Function FindVar(AName : String) : TTemplateVar;
  75. Property Variables[I : Integer] : TTemplateVar Read GetVar Write Setvar; default;
  76. end;
  77. TContentEvent = Procedure (Sender : TObject; Content : TStream) of object;
  78. { TCustomFPWebModule }
  79. TCustomFPWebModule = Class(TSessionHTTPModule)
  80. private
  81. FActions: TFPWebActions;
  82. FAfterResponse: TResponseEvent;
  83. FBeforeRequest: TRequestEvent;
  84. FOnGetParam: TGetParamEvent;
  85. FOnRequest: TWebActionEvent;
  86. FTemplate: TFPTemplate;
  87. FTemplateVars : TTemplateVars;
  88. function GetActionVar: String;
  89. function GetOnGetAction: TGetActionEvent;
  90. procedure SetActions(const AValue: TFPWebActions);
  91. procedure SetActionVar(const AValue: String);
  92. procedure SetOnGetAction(const AValue: TGetActionEvent);
  93. procedure SetTemplate(const AValue: TFPTemplate);
  94. Protected
  95. Procedure DoBeforeRequest(ARequest : TRequest); virtual;
  96. Procedure DoAfterResponse(AResponse : TResponse); virtual;
  97. Procedure GetParam(Const ParamName : String; Out Value : String); virtual; // Called by template
  98. Procedure GetTemplateContent(ARequest : TRequest; AResponse : TResponse); virtual;
  99. function GetContent: String;virtual;
  100. Public
  101. Constructor CreateNew(AOwner : TComponent; CreateMode : Integer); override;
  102. Destructor Destroy; override;
  103. Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); override;
  104. Property Actions : TFPWebActions Read FActions Write SetActions;
  105. Property ActionVar : String Read GetActionVar Write SetActionVar;
  106. Property BeforeRequest : TRequestEvent Read FBeforeRequest Write FBeforeRequest;
  107. Property OnRequest : TWebActionEvent Read FOnRequest Write FOnRequest;
  108. Property AfterResponse : TResponseEvent Read FAfterResponse Write FAfterResponse;
  109. Property OnGetAction : TGetActionEvent Read GetOnGetAction Write SetOnGetAction;
  110. Property Template : TFPTemplate Read FTemplate Write SetTemplate;
  111. Property OnGetParam : TGetParamEvent Read FOnGetParam Write FOnGetParam;
  112. Property OnTemplateContent : TGetParamEvent Read FOnGetParam Write FOnGetParam;
  113. end;
  114. { TFPWebModule }
  115. TFPWebModule = Class(TCustomFPWebModule)
  116. Published
  117. Property Actions;
  118. Property ActionVar;
  119. Property BeforeRequest;
  120. Property OnRequest;
  121. Property AfterResponse;
  122. Property OnGetAction;
  123. Property CreateSession;
  124. Property Session;
  125. Property OnNewSession;
  126. Property OnSessionExpired;
  127. end;
  128. EFPWebError = Class(HTTPError);
  129. resourcestring
  130. SErrInvalidVar = 'Invalid template variable name : "%s"';
  131. SErrInvalidWebAction = 'Invalid action for "%s".';
  132. SErrNoContentProduced = 'No template content was produced.';
  133. implementation
  134. {$ifdef cgidebug}
  135. uses dbugintf;
  136. {$endif cgidebug}
  137. procedure TFPWebAction.GetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
  138. begin
  139. end;
  140. procedure TFPWebAction.Assign(Source: TPersistent);
  141. Var
  142. A : TFPWebAction;
  143. begin
  144. If (Source is TFPWebAction) then
  145. begin
  146. A:=Source as TFPWebAction;
  147. Name:=A.Name;
  148. Content:=A.Content;
  149. AfterResponse:=A.AfterResponse;
  150. BeforeRequest:=A.BeforeRequest;
  151. Default:=A.default;
  152. ContentProducer:=A.ContentProducer;
  153. OnRequest:=A.OnRequest;
  154. FTemplate.Assign(A.Template);
  155. end
  156. else
  157. inherited Assign(Source);
  158. end;
  159. constructor TFPWebAction.create(ACollection: TCollection);
  160. begin
  161. inherited create(ACollection);
  162. FTemplate:=TFPtemplate.Create;
  163. end;
  164. destructor TFPWebAction.destroy;
  165. begin
  166. FreeAndNil(FTemplate);
  167. inherited destroy;
  168. end;
  169. function TFPWebAction.GetStringContent: String;
  170. begin
  171. Result:=Contents.Text;
  172. end;
  173. function TFPWebAction.GetContents: TStrings;
  174. begin
  175. If Not Assigned(FContents) then
  176. FContents:=TStringList.Create;
  177. Result:=FContents;
  178. end;
  179. procedure TFPWebAction.SetContent(const AValue: String);
  180. begin
  181. If (AValue='') then
  182. FreeAndNil(FContents)
  183. else
  184. Contents.Text:=AValue;
  185. end;
  186. procedure TFPWebAction.SetContents(const AValue: TStrings);
  187. begin
  188. Contents.Assign(AValue);
  189. end;
  190. procedure TFPWebAction.SetTemplate(const AValue: TFPTemplate);
  191. begin
  192. If Assigned(AValue) then
  193. FTemplate.Assign(AValue);
  194. end;
  195. procedure TFPWebAction.DoHandleRequest(ARequest: TRequest; AResponse: TResponse; Var Handled : Boolean);
  196. begin
  197. {$ifdef cgidebug}
  198. SendMethodEnter('TFPWebAction('+Name+').Dohandlerequest');
  199. If Handled then
  200. SendDebug('Handled !!')
  201. else
  202. SendDebug('Not yet handled.');
  203. {$endif cgidebug}
  204. If Assigned(FOnRequest) then
  205. begin
  206. {$ifdef cgidebug}
  207. SendDebug('Executing user action');
  208. {$endif cgidebug}
  209. FOnrequest(Self,Arequest,AResponse,Handled);
  210. end;
  211. If Not Handled then
  212. begin
  213. {$ifdef cgidebug}
  214. SendDebug('Executing inherited');
  215. {$endif cgidebug}
  216. Inherited DoHandleRequest(ARequest,AResponse,Handled);
  217. If not Handled then
  218. begin
  219. AResponse.Contents.AddStrings(Self.Contents);
  220. Handled:=(AResponse.Content<>'');
  221. end;
  222. end;
  223. {$ifdef cgidebug}
  224. SendMethodExit('TFPWebAction('+Name+').Dohandlerequest');
  225. {$endif cgidebug}
  226. end;
  227. procedure TFPWebAction.DoGetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
  228. begin
  229. If Assigned(ContentProducer) then
  230. ContentProducer.GetContent(ARequest,Content,Handled)
  231. else
  232. If (Self.Content<>'') then
  233. Content.Write(Self.Content[1],Length(Self.Content));
  234. end;
  235. { TFPWebTemplate }
  236. Type
  237. TFPWebTemplate = Class(TFPTemplate)
  238. Private
  239. FOwner: TCustomFPWebModule;
  240. FRequest : TRequest;
  241. Public
  242. Constructor Create(AOwner :TCustomFPWebModule);
  243. Procedure GetParam(Sender : TObject; Const ParamName : String; Out AValue : String);override;
  244. Property Owner : TCustomFPWebModule Read FOwner;
  245. Property Request : TRequest Read FRequest Write FRequest;
  246. end;
  247. constructor TFPWebTemplate.Create(AOwner: TCustomFPWebModule);
  248. begin
  249. Inherited create;
  250. FOwner:=AOwner;
  251. end;
  252. procedure TFPWebTemplate.GetParam(Sender: TObject; const ParamName: String;
  253. out AValue: String);
  254. begin
  255. FOwner.GetParam(ParamName, AValue);
  256. end;
  257. { TFPWebModule }
  258. function TCustomFPWebModule.GetActionVar: String;
  259. begin
  260. Result:=FActions.ActionVar;
  261. end;
  262. function TCustomFPWebModule.GetOnGetAction: TGetActionEvent;
  263. begin
  264. Result:=FActions.OnGetAction;
  265. end;
  266. procedure TCustomFPWebModule.SetActions(const AValue: TFPWebActions);
  267. begin
  268. if (FActions<>AValue) then;
  269. FActions.Assign(AValue);
  270. end;
  271. procedure TCustomFPWebModule.SetActionVar(const AValue: String);
  272. begin
  273. FActions.ActionVar:=AValue;
  274. end;
  275. procedure TCustomFPWebModule.SetOnGetAction(const AValue: TGetActionEvent);
  276. begin
  277. FActions.OnGetAction:=AValue;
  278. end;
  279. procedure TCustomFPWebModule.SetTemplate(const AValue: TFPTemplate);
  280. begin
  281. if FTemplate<>AValue then
  282. FTemplate.Assign(AValue);
  283. end;
  284. procedure TCustomFPWebModule.DoBeforeRequest(ARequest : TRequest);
  285. begin
  286. If Assigned(FBeforeRequest) then
  287. FBeforeRequest(Self,ARequest);
  288. end;
  289. procedure TCustomFPWebModule.DoAfterResponse(AResponse : TResponse);
  290. begin
  291. If Assigned(FAfterResponse) then
  292. FAfterResponse(Self,AResponse);
  293. end;
  294. procedure TCustomFPWebModule.GetParam(const ParamName: String; out Value: String);
  295. Var
  296. T : TTemplateVar;
  297. begin
  298. If (0=CompareText(ParamName,'CONTENT')) then
  299. Value:=GetContent
  300. else
  301. begin
  302. T:=FTemplateVars.FindVar(ParamName);
  303. If (T<>Nil) then
  304. Value:=T.Value
  305. else
  306. If Assigned(FOnGetParam) then
  307. FOngetParam(Self,ParamName,Value);
  308. end;
  309. end;
  310. procedure TCustomFPWebModule.GetTemplateContent(ARequest: TRequest;
  311. AResponse: TResponse);
  312. begin
  313. TFPWebTemplate(FTemplate).Request:=ARequest;
  314. AResponse.Content:=FTemplate.GetContent;
  315. end;
  316. function TCustomFPWebModule.GetContent: String;
  317. Var
  318. S : TStringStream;
  319. B : Boolean;
  320. begin
  321. S:=TStringStream.Create('');
  322. Try
  323. FActions.GetContent(TFPWebTemplate(FTemplate).Request,S,B);
  324. If Not B then
  325. Raise EFPWebError.Create(SErrNoContentProduced);
  326. Result:=S.DataString;
  327. finally
  328. S.Free;
  329. end;
  330. end;
  331. constructor TCustomFPWebModule.CreateNew(AOwner: TComponent; CreateMode : Integer);
  332. begin
  333. inherited;
  334. FActions:=TFPWebActions.Create(TFPWebAction);
  335. FTemplate:=TFPWebTemplate.Create(Self);
  336. FTemplateVars:=TTemplateVars.Create(TTemplateVar);
  337. end;
  338. destructor TCustomFPWebModule.Destroy;
  339. begin
  340. FreeAndNil(FTemplateVars);
  341. FreeAndNil(FTemplate);
  342. FreeAndNil(FActions);
  343. inherited Destroy;
  344. end;
  345. procedure TCustomFPWebModule.HandleRequest(ARequest: TRequest; AResponse: TResponse);
  346. Var
  347. B : Boolean;
  348. begin
  349. {$ifdef cgidebug}
  350. SendMethodEnter('WebModule('+Name+').handlerequest');
  351. {$endif cgidebug}
  352. CheckSession(ARequest);
  353. DoBeforeRequest(ARequest);
  354. B:=False;
  355. InitSession(AResponse);
  356. If Assigned(FOnRequest) then
  357. FOnRequest(Self,ARequest,AResponse,B);
  358. If Not B then
  359. if FTemplate.HasContent then
  360. GetTemplateContent(ARequest,AResponse)
  361. else
  362. begin
  363. Actions.HandleRequest(ARequest,AResponse,B);
  364. If Not B then
  365. Raise EFPWebError.Create(SErrRequestNotHandled);
  366. end;
  367. DoAfterResponse(AResponse);
  368. UpdateSession(AResponse);
  369. {$ifdef cgidebug}
  370. SendMethodExit('WebModule('+Name+').handlerequest');
  371. {$endif cgidebug}
  372. end;
  373. { TTemplateVar }
  374. procedure TTemplateVar.Assign(Source: TPersistent);
  375. begin
  376. if Source is TTemplateVar then
  377. With Source as TTemplateVar do
  378. begin
  379. Self.Name:=Name;
  380. Self.Value:=Value;
  381. end
  382. else
  383. inherited Assign(Source);
  384. end;
  385. function TTemplateVar.GetDisplayName: String;
  386. begin
  387. Result:=FName;
  388. end;
  389. { TTemplateVars }
  390. function TTemplateVars.GetVar(I : Integer): TTemplateVar;
  391. begin
  392. Result:=TTemplateVar(Items[I])
  393. end;
  394. procedure TTemplateVars.Setvar(I : Integer; const AValue: TTemplateVar);
  395. begin
  396. Items[i]:=AValue;
  397. end;
  398. function TTemplateVars.IndexOfVar(AName: String): Integer;
  399. begin
  400. Result:=Count-1;
  401. While (Result>=0) and (CompareText(AName,GetVar(Result).Name)<>0) do
  402. Dec(Result);
  403. end;
  404. function TTemplateVars.VarByName(AName: String): TTemplateVar;
  405. begin
  406. Result:=FindVar(AName);
  407. If (Result=Nil) then
  408. Raise EFPWebError.CreateFmt(SErrInvalidVar,[AName]);
  409. end;
  410. function TTemplateVars.FindVar(AName: String): TTemplateVar;
  411. Var
  412. I : Integer;
  413. begin
  414. I:=IndexOfVar(AName);
  415. If (I=-1) then
  416. Result:=Nil
  417. else
  418. Result:=GetVar(I);
  419. end;
  420. { TFPWebActions }
  421. procedure TFPWebActions.HandleRequest(ARequest: TRequest; AResponse: TResponse; Var Handled : Boolean);
  422. Var
  423. A : TCustomWebAction;
  424. begin
  425. {$ifdef cgidebug}SendMethodEnter('FPWebActions.handlerequest');{$endif cgidebug}
  426. A:=GetRequestAction(ARequest);
  427. if Assigned(A) then
  428. begin
  429. FCurrentAction := A;
  430. (A as TFPWebAction).HandleRequest(ARequest,AResponse,Handled);
  431. end;
  432. {$ifdef cgidebug}SendMethodExit('FPWebActions.handlerequest');{$endif cgidebug}
  433. end;
  434. procedure TFPWebActions.GetContent(ARequest: TRequest; Content: TStream;
  435. var Handled: Boolean);
  436. Var
  437. A : TCustomWebAction;
  438. begin
  439. {$ifdef cgidebug}SendMethodEnter('WebActions.GetContent');{$endif cgidebug}
  440. A:=GetRequestAction(ARequest);
  441. If A is TFPWebAction then
  442. TFPWebAction(A).GetContent(ARequest,Content,Handled)
  443. else
  444. Raise EFPWebError.CreateFmt(SErrInvalidWebAction,[A.ClassName]);
  445. {$ifdef cgidebug}SendMethodExit('WebActions.GetContent');{$endif cgidebug}
  446. end;
  447. end.