fpweb.pp 14 KB

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