fphttp.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  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 fphttp;
  14. Interface
  15. uses sysutils,classes,httpdefs;
  16. Type
  17. { TODO : Implement wkSession }
  18. TWebModuleKind = (wkPooled, wkOneShot{, wkSession});
  19. { THTTPContentProducer }
  20. TWebActionEvent = Procedure (Sender : TObject;
  21. ARequest : TRequest;
  22. AResponse : TResponse;
  23. Var Handled : Boolean) of object;
  24. THTTPContentProducer = Class(TComponent)
  25. private
  26. FAfterResponse: TResponseEvent;
  27. FBeforeRequest: TRequestEvent;
  28. FRequest : TRequest;
  29. FResponse: TResponse;
  30. Protected
  31. Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); virtual;
  32. Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
  33. Function ProduceContent : String; virtual;
  34. Procedure SetRequest(ARequest: TRequest);
  35. Protected
  36. Property BeforeRequest : TRequestEvent Read FBeforeRequest Write FBeforeRequest;
  37. Property AfterResponse : TResponseEvent Read FAfterResponse Write FAfterResponse;
  38. Public
  39. Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean);
  40. Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
  41. Function HaveContent : Boolean; virtual;
  42. function ContentToStream(Stream : TStream) : boolean; virtual;
  43. Property Request : TRequest Read FRequest;
  44. Property Response : TResponse Read FResponse;
  45. end;
  46. { TCustomWebAction }
  47. TCustomWebAction = Class(TCollectionItem)
  48. private
  49. FAfterResponse: TResponseEvent;
  50. FBeforeRequest: TRequestEvent;
  51. FContentproducer: THTTPContentProducer;
  52. FDefault: Boolean;
  53. FName : String;
  54. Protected
  55. procedure SetContentProducer(const AValue: THTTPContentProducer);virtual;
  56. Function GetDisplayName : String; override;
  57. Procedure SetDisplayName(const AValue : String); override;
  58. Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean);
  59. Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); virtual;
  60. Public
  61. Function GetNamePath : String; override;
  62. published
  63. Property Name : String Read GetDisplayName Write SetDisplayName;
  64. Property ContentProducer : THTTPContentProducer Read FContentproducer Write SetContentProducer;
  65. Property Default : Boolean Read FDefault Write FDefault;
  66. Property BeforeRequest : TRequestEvent Read FBeforeRequest Write FBeforeRequest;
  67. Property AfterResponse : TResponseEvent Read FAfterResponse Write FAfterResponse;
  68. end;
  69. { TCustomWebActions }
  70. TGetActionEvent = Procedure (Sender : TObject; ARequest : TRequest; Var ActionName : String) of object;
  71. TCustomWebActions = Class(TCollection)
  72. private
  73. FActionVar : String;
  74. FDefActionWhenUnknown: Boolean;
  75. FOnGetAction: TGetActionEvent;
  76. function GetActions(Index : Integer): TCustomWebAction;
  77. procedure SetActions(Index : Integer; const AValue: TCustomWebAction);
  78. Protected
  79. Function GetRequestAction(ARequest: TRequest) : TCustomWebAction;
  80. Function GetActionName(ARequest : TRequest) : String;
  81. Property ActionVar : String Read FactionVar Write FActionVar;
  82. public
  83. constructor Create(AItemClass: TCollectionItemClass);
  84. Procedure Assign(Source : TPersistent); override;
  85. Function Add : TCustomWebAction;
  86. Function ActionByName(const AName : String) : TCustomWebAction;
  87. Function FindAction(const AName : String): TCustomWebAction;
  88. Function IndexOfAction(const AName : String) : Integer;
  89. Property OnGetAction : TGetActionEvent Read FOnGetAction Write FOnGetAction;
  90. Property Actions[Index : Integer] : TCustomWebAction Read GetActions Write SetActions; Default;
  91. Property DefActionWhenUnknown : Boolean read FDefActionWhenUnknown write FDefActionWhenUnknown;
  92. end;
  93. { TCustomHTTPModule }
  94. TInitModuleEvent = Procedure (Sender : TObject; ARequest : TRequest) of object;
  95. TCustomHTTPModule = Class(TDataModule)
  96. private
  97. FAfterInitModule : TInitModuleEvent;
  98. FBaseURL: String;
  99. FWebModuleKind: TWebModuleKind;
  100. public
  101. Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); virtual; abstract;
  102. Procedure DoAfterInitModule(ARequest : TRequest); virtual;
  103. property Kind: TWebModuleKind read FWebModuleKind write FWebModuleKind default wkPooled;
  104. Property BaseURL : String Read FBaseURL Write FBaseURL;
  105. Property AfterInitModule : TInitModuleEvent Read FAfterInitModule Write FAfterInitModule;
  106. end;
  107. TCustomHTTPModuleClass = Class of TCustomHTTPModule;
  108. { TSessionHTTPModule }
  109. TSessionHTTPModule = Class(TCustomHTTPModule)
  110. Private
  111. FCreateSession : Boolean;
  112. FOnNewSession: TNotifyEvent;
  113. FOnSessionExpired: TNotifyEvent;
  114. FSession: TCustomSession;
  115. FSessionRequest : TRequest;
  116. function GetSession: TCustomSession;
  117. procedure SetSession(const AValue: TCustomSession);
  118. Protected
  119. Procedure CheckSession(ARequest : TRequest);
  120. Procedure InitSession(AResponse : TResponse);
  121. Procedure UpdateSession(AResponse : TResponse);
  122. Procedure DoneSession; virtual;
  123. Public
  124. destructor destroy; override;
  125. Procedure Notification(AComponent : TComponent;Operation : TOperation); override;
  126. Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); override;
  127. Property CreateSession : Boolean Read FCreateSession Write FCreateSession;
  128. Property Session : TCustomSession Read GetSession Write SetSession;
  129. Property OnNewSession : TNotifyEvent Read FOnNewSession Write FOnNewSession;
  130. Property OnSessionExpired : TNotifyEvent Read FOnSessionExpired Write FOnSessionExpired;
  131. end;
  132. TSessionHTTPModuleClass = Class of TSessionHTTPModule;
  133. EWebSessionError = Class(HTTPError);
  134. { TSessionFactory }
  135. TSessionFactory = Class(TComponent)
  136. private
  137. FSessionCookie: String;
  138. FSessionCookiePath: String;
  139. FTimeOut: Integer;
  140. FCleanupInterval: Integer;
  141. FDoneCount: Integer;
  142. protected
  143. // Override in descendants
  144. Function DoCreateSession(ARequest : TRequest) : TCustomSession; virtual; abstract;
  145. Procedure DoDoneSession(Var ASession : TCustomSession); virtual; abstract;
  146. Procedure DoCleanupSessions; virtual; abstract;
  147. Property DoneCount : Integer Read FDoneCount;
  148. Public
  149. Function CreateSession(ARequest : TRequest) : TCustomSession;
  150. Procedure DoneSession(Var ASession : TCustomSession);
  151. Procedure CleanupSessions;
  152. // Number of requests before sweeping sessions for stale sessions.
  153. // Default 1000. Set to 0 to disable.
  154. // Note that for cgi programs, this will never happen, since the count is reset to 0
  155. // with each invocation. It takes a special factory to handle that, or a value of 1.
  156. Property CleanupInterval : Integer read FCleanupInterval Write FCleanUpInterval;
  157. // Default timeout for sessions, in minutes.
  158. Property DefaultTimeOutMinutes : Integer Read FTimeOut Write FTimeOut;
  159. // Default session cookie.
  160. property SessionCookie : String Read FSessionCookie Write FSessionCookie;
  161. // Default session cookie path
  162. Property SessionCookiePath : String Read FSessionCookiePath write FSessionCookiePath;
  163. end;
  164. TSessionFactoryClass = Class of TSessionFactory;
  165. { TModuleItem }
  166. TModuleItem = Class(TCollectionItem)
  167. private
  168. FModuleClass: TCustomHTTPModuleClass;
  169. FModuleName: String;
  170. FSkipStreaming: Boolean;
  171. Public
  172. Property ModuleClass : TCustomHTTPModuleClass Read FModuleClass Write FModuleClass;
  173. Property ModuleName : String Read FModuleName Write FModuleName;
  174. Property SkipStreaming : Boolean Read FSkipStreaming Write FSkipStreaming;
  175. end;
  176. { TModuleFactory }
  177. TModuleFactory = Class(TCollection)
  178. private
  179. function GetModule(Index : Integer): TModuleItem;
  180. procedure SetModule(Index : Integer; const AValue: TModuleItem);
  181. Public
  182. Function FindModule(const AModuleName : String) : TModuleItem;
  183. Function ModuleByName(const AModuleName : String) : TModuleItem;
  184. Function IndexOfModule(const AModuleName : String) : Integer;
  185. Property Modules [Index : Integer]: TModuleItem Read GetModule Write SetModule;default;
  186. end;
  187. EFPHTTPError = Class(Exception);
  188. Procedure RegisterHTTPModule(ModuleClass : TCustomHTTPModuleClass; SkipStreaming : Boolean = False);
  189. Procedure RegisterHTTPModule(Const ModuleName : String; ModuleClass : TCustomHTTPModuleClass; SkipStreaming : Boolean = False);
  190. Var
  191. ModuleFactory : TModuleFactory;
  192. SessionFactoryClass : TSessionFactoryClass = nil;
  193. Function SessionFactory : TSessionFactory;
  194. Resourcestring
  195. SErrNosuchModule = 'No such module registered: "%s"';
  196. SErrNoSuchAction = 'No action found for action: "%s"';
  197. SErrUnknownAction = 'Unknown action: "%s"';
  198. SErrNoDefaultAction = 'No action name and no default action';
  199. SErrInvActNoDefaultAction = 'Invalid action name and no default action';
  200. SErrRequestNotHandled = 'Web request was not handled by actions.';
  201. SErrNoSessionFactoryClass = 'No session manager class available. Include iniwebsession unit and recompile.';
  202. SErrNoSessionOutsideRequest = 'Default session not available outside handlerequest';
  203. Implementation
  204. {$ifdef cgidebug}
  205. uses dbugintf;
  206. {$endif}
  207. Var
  208. GSM : TSessionFactory;
  209. Function SessionFactory : TSessionFactory;
  210. begin
  211. if GSM=Nil then
  212. begin
  213. if (SessionFactoryClass=Nil) then
  214. Raise EFPHTTPError.Create(SErrNoSessionFactoryClass);
  215. GSM:=SessionFactoryClass.Create(Nil)
  216. end;
  217. Result:=GSM;
  218. end;
  219. { TCustomHTTPModule }
  220. procedure TCustomHTTPModule.DoAfterInitModule(ARequest: TRequest);
  221. begin
  222. If Assigned(FAfterInitModule) then
  223. FAfterInitModule(Self, ARequest);
  224. end;
  225. { TSessionFactory }
  226. function TSessionFactory.CreateSession(ARequest: TRequest): TCustomSession;
  227. begin
  228. Result:=DoCreateSession(ARequest);
  229. if Assigned(Result) then
  230. begin
  231. if (FTimeOut<>0) then
  232. Result.TimeoutMinutes:=FTimeOut;
  233. Result.SessionCookie:=Self.SessionCookie;
  234. Result.SessionCookiePath:=Self.SessionCookiePath;
  235. end;
  236. end;
  237. procedure TSessionFactory.DoneSession(var ASession: TCustomSession);
  238. begin
  239. DoDoneSession(ASession);
  240. if (FCleanupInterval>0) then
  241. begin
  242. Inc(FDoneCount);
  243. If (FDoneCount>=FCleanupInterval) then
  244. CleanupSessions;
  245. end;
  246. end;
  247. procedure TSessionFactory.CleanupSessions;
  248. begin
  249. FDoneCount:=0;
  250. DoCleanupSessions;
  251. end;
  252. { TModuleFactory }
  253. function TModuleFactory.GetModule(Index : Integer): TModuleItem;
  254. begin
  255. Result:=TModuleItem(Items[Index]);
  256. end;
  257. procedure TModuleFactory.SetModule(Index : Integer; const AValue: TModuleItem);
  258. begin
  259. Items[Index]:=AValue;
  260. end;
  261. function TModuleFactory.FindModule(const AModuleName: String): TModuleItem;
  262. Var
  263. I : Integer;
  264. begin
  265. I:=IndexOfModule(AModuleName);
  266. If (I=-1) then
  267. Result:=Nil
  268. else
  269. Result:=GetModule(I);
  270. end;
  271. function TModuleFactory.ModuleByName(const AModuleName: String): TModuleItem;
  272. begin
  273. Result:=FindModule(AModuleName);
  274. If (Result=Nil) then
  275. Raise EFPHTTPError.CreateFmt(SErrNosuchModule,[AModuleName]);
  276. end;
  277. function TModuleFactory.IndexOfModule(const AModuleName: String): Integer;
  278. begin
  279. Result:=Count-1;
  280. While (Result>=0) and (CompareText(Modules[Result].ModuleName,AModuleName)<>0) do
  281. Dec(Result);
  282. end;
  283. procedure RegisterHTTPModule(ModuleClass: TCustomHTTPModuleClass; SkipStreaming : Boolean = False);
  284. begin
  285. RegisterHTTPModule(ModuleClass.ClassName,ModuleClass,SkipStreaming);
  286. end;
  287. procedure RegisterHTTPModule(const ModuleName: String;
  288. ModuleClass: TCustomHTTPModuleClass; SkipStreaming : Boolean = False);
  289. Var
  290. I : Integer;
  291. MI : TModuleItem;
  292. begin
  293. I:=ModuleFactory.IndexOfModule(ModuleName);
  294. If (I=-1) then
  295. begin
  296. MI:=ModuleFactory.Add as TModuleItem;
  297. MI.ModuleName:=ModuleName;
  298. end
  299. else
  300. MI:=ModuleFactory[I];
  301. MI.ModuleClass:=ModuleClass;
  302. MI.SkipStreaming:=SkipStreaming;
  303. end;
  304. { THTTPContentProducer }
  305. procedure THTTPContentProducer.HandleRequest(ARequest: TRequest;
  306. AResponse: TResponse; Var Handled : Boolean);
  307. begin
  308. If Assigned(FBeforeRequest) then
  309. FBeforeRequest(Self,ARequest);
  310. DoHandleRequest(Arequest,AResponse,Handled);
  311. If Assigned(FAfterResponse) then
  312. FAfterResponse(Self,AResponse);
  313. end;
  314. procedure THTTPContentProducer.GetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
  315. begin
  316. If Assigned(FBeforeRequest) then
  317. FBeforeRequest(Self,ARequest);
  318. DoGetContent(Arequest,Content,Handled);
  319. end;
  320. procedure THTTPContentProducer.DoHandleRequest(ARequest: TRequest;
  321. AResponse: TResponse; Var Handled : Boolean);
  322. Var
  323. M : TMemoryStream;
  324. begin
  325. FResponse:=AResponse;
  326. M:=TMemoryStream.Create;
  327. DoGetContent(ARequest,M,Handled);
  328. AResponse.ContentStream:=M;
  329. AResponse.ContentLength:=M.Size;
  330. end;
  331. procedure THTTPContentProducer.DoGetContent(ARequest: TRequest; Content: TStream; Var Handled : Boolean);
  332. begin
  333. FRequest := ARequest;
  334. Handled:=ContentToStream(Content);
  335. end;
  336. function THTTPContentProducer.ProduceContent: String;
  337. begin
  338. Result:='';
  339. end;
  340. procedure THTTPContentProducer.SetRequest(ARequest: TRequest);
  341. begin
  342. FRequest := ARequest;
  343. end;
  344. function THTTPContentProducer.HaveContent: Boolean;
  345. begin
  346. Result:=(ProduceContent<>'');
  347. end;
  348. function THTTPContentProducer.ContentToStream(Stream: TStream) : boolean;
  349. Var
  350. S : String;
  351. begin
  352. S:=ProduceContent;
  353. If length(S)>0 then
  354. begin
  355. Stream.WriteBuffer(S[1],Length(S));
  356. Result := True;
  357. end
  358. else
  359. Result := False;
  360. end;
  361. { TCustomWebAction }
  362. procedure TCustomWebAction.SetContentProducer(const AValue: THTTPContentProducer
  363. );
  364. begin
  365. FContentProducer:=AValue;
  366. end;
  367. function TCustomWebAction.GetDisplayName: String;
  368. begin
  369. If (FName='') then
  370. FName:=ClassName+IntToStr(self.Index);
  371. Result:=FName;
  372. end;
  373. Function TCustomWebAction.GetNamePath : String;
  374. begin
  375. If (FName='') then
  376. FName:=ClassName+IntToStr(self.Index);
  377. Result:=FName;
  378. end;
  379. procedure TCustomWebAction.SetDisplayName(const AValue: String);
  380. begin
  381. Inherited;
  382. FName:=AValue;
  383. end;
  384. procedure TCustomWebAction.HandleRequest(ARequest: TRequest; AResponse: TResponse; Var Handled : Boolean);
  385. begin
  386. If Assigned(FBeforeRequest) then
  387. FBeforeRequest(Self,ARequest);
  388. DoHandleRequest(Arequest,AResponse,Handled);
  389. If Assigned(FAfterResponse) then
  390. FAfterResponse(Self,AResponse);
  391. end;
  392. procedure TCustomWebAction.DoHandleRequest(ARequest: TRequest; AResponse: TResponse; Var Handled : Boolean);
  393. begin
  394. If Assigned(FContentProducer) then
  395. FContentProducer.HandleRequest(ARequest,AResponse,Handled)
  396. end;
  397. { TCustomWebActions }
  398. function TCustomWebActions.GetActions(Index : Integer): TCustomWebAction;
  399. begin
  400. Result:=TCustomWebAction(Items[Index]);
  401. end;
  402. procedure TCustomWebActions.SetActions(Index : Integer; const AValue: TCustomWebAction);
  403. begin
  404. Items[Index]:=AValue;
  405. end;
  406. Function TCustomWebActions.GetRequestAction(ARequest: TRequest) : TCustomWebAction;
  407. Var
  408. S : String;
  409. Function GetDefaultAction:TCustomWebAction;
  410. Var I : Integer;
  411. begin
  412. Result := nil;
  413. I:=0;
  414. While (Result=Nil) and (I<Count) do
  415. begin
  416. If Actions[I].Default then
  417. Result:=Actions[I];
  418. Inc(I);
  419. end;
  420. end;
  421. begin
  422. Result:=Nil;
  423. S:=GetActionName(ARequest);
  424. If (S<>'') then
  425. begin
  426. Result:=FindAction(S);
  427. if Result = nil then
  428. begin//no action with that name found
  429. if not DefActionWhenUnknown then
  430. Raise EFPHTTPError.CreateFmt(SErrNoSuchAction,[s])
  431. else begin
  432. Result := GetDefaultAction;
  433. if Result = nil then
  434. Raise EFPHTTPError.Create(SErrInvActNoDefaultAction);
  435. end;
  436. end;
  437. end else begin //no action name was specified
  438. Result := GetDefaultAction;
  439. If (Result=Nil) then
  440. Raise EFPHTTPError.Create(SErrNoDefaultAction);
  441. end;
  442. end;
  443. function TCustomWebActions.GetActionName(ARequest: TRequest): String;
  444. begin
  445. If (FActionVar<>'') then
  446. Result:=ARequest.QueryFields.Values[FActionVar]
  447. else
  448. Result := '';
  449. If Assigned(FOnGetAction) then
  450. FOnGetAction(Self,ARequest,Result);
  451. // GetNextPathInfo is only used after OnGetAction, so that the call to
  452. // GetNextPathInfo can be avoided in the event.
  453. If (Result='') then
  454. Result:=ARequest.GetNextPathInfo;
  455. end;
  456. constructor TCustomWebActions.Create(AItemClass: TCollectionItemClass);
  457. begin
  458. inherited Create(AItemClass);
  459. FDefActionWhenUnknown:=True;
  460. end;
  461. procedure TCustomWebActions.Assign(Source: TPersistent);
  462. begin
  463. If (Source is TCustomWebActions) then
  464. ActionVar:=(Source as TCustomWebActions).ActionVar
  465. else
  466. inherited Assign(Source);
  467. end;
  468. function TCustomWebActions.Add: TCustomWebAction;
  469. begin
  470. Result:=TCustomWebAction(Inherited Add);
  471. end;
  472. function TCustomWebActions.ActionByName(const AName: String): TCustomWebAction;
  473. begin
  474. Result:=FindAction(AName);
  475. If (Result=Nil) then
  476. Raise HTTPError.CreateFmt(SErrUnknownAction,[AName]);
  477. end;
  478. function TCustomWebActions.FindAction(const AName: String): TCustomWebAction;
  479. Var
  480. I : Integer;
  481. begin
  482. I:=IndexOfAction(AName);
  483. If (I=-1) then
  484. Result:=Nil
  485. else
  486. Result:=Actions[I];
  487. end;
  488. function TCustomWebActions.IndexOfAction(const AName: String): Integer;
  489. begin
  490. Result:=Count-1;
  491. While (Result>=0) and (CompareText(Actions[Result].Name,AName)<>0) do
  492. Dec(Result);
  493. end;
  494. function TSessionHTTPModule.GetSession: TCustomSession;
  495. begin
  496. {$ifdef cgidebug}SendMethodEnter('SessionHTTPModule.GetSession');{$endif}
  497. If (csDesigning in ComponentState) then
  498. begin
  499. {$ifdef cgidebug}SendDebug('Sending session');{$endif}
  500. Result:=FSession
  501. end
  502. else
  503. begin
  504. If (FSession=Nil) then
  505. begin
  506. {$ifdef cgidebug}SendDebug('Getting default session');{$endif}
  507. if (FSessionRequest=Nil) then
  508. Raise EFPHTTPError.Create(SErrNoSessionOutsideRequest);
  509. FSession:=SessionFactory.CreateSession(FSessionRequest);
  510. FSession.FreeNotification(Self);
  511. end;
  512. Result:=FSession
  513. end;
  514. {$ifdef cgidebug}SendMethodExit('SessionHTTPModule.GetSession');{$endif}
  515. end;
  516. procedure TSessionHTTPModule.SetSession(const AValue: TCustomSession);
  517. begin
  518. if FSession<>AValue then
  519. begin
  520. If Assigned(FSession) then
  521. FSession.RemoveFreeNotification(Self);
  522. FSession:=AValue;
  523. If Assigned(FSession) then
  524. FSession.FreeNotification(Self);
  525. end;
  526. end;
  527. procedure TSessionHTTPModule.CheckSession(ARequest : TRequest);
  528. begin
  529. {$ifdef cgidebug}SendMethodEnter('SessionHTTPModule('+Name+').CheckSession');{$endif}
  530. If CreateSession then
  531. begin
  532. If (FSession=Nil) then
  533. FSession:=SessionFactory.CreateSession(ARequest);
  534. if Assigned(FSession) then
  535. FSession.InitSession(ARequest,FOnNewSession,FOnSessionExpired);
  536. end;
  537. {$ifdef cgidebug}SendMethodExit('SessionHTTPModule('+Name+').CheckSession');{$endif}
  538. end;
  539. procedure TSessionHTTPModule.InitSession(AResponse: TResponse);
  540. begin
  541. {$ifdef cgidebug}SendMethodEnter('SessionHTTPModule('+Name+').InitSession');{$endif}
  542. If CreateSession and Assigned(FSession) then
  543. FSession.InitResponse(AResponse);
  544. {$ifdef cgidebug}SendMethodExit('SessionHTTPModule('+Name+').InitSession');{$endif}
  545. end;
  546. procedure TSessionHTTPModule.UpdateSession(AResponse: TResponse);
  547. begin
  548. If CreateSession And Assigned(FSession) then
  549. FSession.UpdateResponse(AResponse);
  550. end;
  551. procedure TSessionHTTPModule.DoneSession;
  552. begin
  553. // Session manager may or may not destroy the session.
  554. // Check if we actually have
  555. if Assigned(FSession) then
  556. SessionFactory.DoneSession(FSession);
  557. // In each case, our reference is no longer valid.
  558. FSession:=Nil;
  559. end;
  560. destructor TSessionHTTPModule.destroy;
  561. begin
  562. // Prevent memory leaks.
  563. DoneSession;
  564. inherited destroy;
  565. end;
  566. procedure TSessionHTTPModule.Notification(AComponent: TComponent;
  567. Operation: TOperation);
  568. begin
  569. {$ifdef cgidebug}SendMethodEnter('SessionHTTPModule('+Name+').Notification');{$endif}
  570. inherited Notification(AComponent, Operation);
  571. If (Operation=opRemove) then
  572. if (AComponent=FSession) Then
  573. FSession:=Nil;
  574. {$ifdef cgidebug}SendMethodExit('SessionHTTPModule('+Name+').Notification');{$endif}
  575. end;
  576. procedure TSessionHTTPModule.HandleRequest(ARequest: TRequest;
  577. AResponse: TResponse);
  578. begin
  579. FSessionRequest:=ARequest;
  580. end;
  581. Initialization
  582. ModuleFactory:=TModuleFactory.Create(TModuleItem);
  583. Finalization
  584. FreeAndNil(ModuleFactory);
  585. FreeAndNil(GSM);
  586. end.