custapache.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. {
  2. This file is part of the Free Pascal fcl-web package
  3. Copyright (c) 1999-2022 by the Free Pascal development team
  4. Apache customization
  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. unit custapache;
  12. {$mode objfpc}
  13. {$H+}
  14. interface
  15. uses
  16. SysUtils,Classes,CustWeb,httpDefs,fpHTTP,httpd,httpprotocol, apr, SyncObjs;
  17. Type
  18. TApacheHandler = Class;
  19. { TApacheRequest }
  20. TApacheRequest = Class(TRequest)
  21. Private
  22. FApache : TApacheHandler;
  23. FRequest : PRequest_rec;
  24. Protected
  25. Procedure InitFromRequest;
  26. procedure ReadContent; override;
  27. Public
  28. Constructor CreateReq(App : TApacheHandler; ARequest : PRequest_rec);
  29. Function GetCustomHeader(const Name: String) : String; override;
  30. Property ApacheRequest : Prequest_rec Read FRequest;
  31. Property ApacheApp : TApacheHandler Read FApache;
  32. end;
  33. { TApacheResponse }
  34. TApacheResponse = Class(TResponse)
  35. private
  36. FApache : TApacheHandler;
  37. FRequest : PRequest_rec;
  38. procedure SendStream(S: TStream);
  39. Protected
  40. Procedure DoSendHeaders(Headers : TStrings); override;
  41. Procedure DoSendContent; override;
  42. Public
  43. Constructor CreateApache(Req : TApacheRequest);
  44. Property ApacheRequest : Prequest_rec Read FRequest;
  45. Property ApacheApp : TApacheHandler Read FApache;
  46. end;
  47. { TCustomApacheApplication }
  48. THandlerPriority = (hpFirst,hpMiddle,hpLast);
  49. TBeforeRequestEvent = Procedure(Sender : TObject; Const AHandler : String;
  50. Var AllowRequest : Boolean) of object;
  51. TApacheHandler = Class(TWebHandler)
  52. private
  53. FMaxRequests: Integer; //Maximum number of simultaneous web module requests (default=64, if set to zero no limit)
  54. FWorkingWebModules: TList; //List of currently running web modules handling requests
  55. FIdleWebModules: TList; //List of idle web modules available
  56. FCriticalSection: TCriticalSection;
  57. FBaseLocation: String;
  58. FBeforeRequest: TBeforeRequestEvent;
  59. FHandlerName: String;
  60. FModuleName: String;
  61. FModules : Array[0..1] of TStrings;
  62. FPriority: THandlerPriority;
  63. FModuleRecord : PModule;
  64. function GetModules(Index: integer): TStrings;
  65. procedure SetModules(Index: integer; const AValue: TStrings);
  66. function GetIdleModuleCount : Integer;
  67. function GetWorkingModuleCount : Integer;
  68. Protected
  69. Function ProcessRequest(P : PRequest_Rec) : Integer; virtual;
  70. function WaitForRequest(out ARequest : TRequest; out AResponse : TResponse) : boolean; override;
  71. Function AllowRequest(P : PRequest_Rec) : Boolean; virtual;
  72. function GetApplicationURL(ARequest : TRequest): String; override;
  73. Public
  74. Constructor Create(AOwner : TComponent); override;
  75. Destructor Destroy; override;
  76. Procedure Run; override;
  77. Procedure SetModuleRecord(Var ModuleRecord : Module);
  78. Procedure Initialize;
  79. Procedure LogErrorMessage(const Msg : String; LogLevel : integer = APLOG_INFO); virtual;
  80. Procedure handleRequest(ARequest : TRequest; AResponse : TResponse); override;
  81. Property HandlerPriority : THandlerPriority Read FPriority Write FPriority default hpMiddle;
  82. Property BeforeModules : TStrings Index 0 Read GetModules Write SetModules;
  83. Property AfterModules : TStrings Index 1 Read GetModules Write SetModules;
  84. Property BaseLocation : String Read FBaseLocation Write FBaseLocation;
  85. Property ModuleName : String Read FModuleName Write FModuleName;
  86. Property HandlerName : String Read FHandlerName Write FHandlerName;
  87. Property BeforeRequest : TBeforeRequestEvent Read FBeforeRequest Write FBeforeRequest;
  88. Property MaxRequests: Integer read FMaxRequests write FMaxRequests;
  89. Property IdleWebModuleCount: Integer read GetIdleModuleCount;
  90. Property WorkingWebModuleCount: Integer read GetWorkingModuleCount;
  91. end;
  92. TCustomApacheApplication = Class(TCustomWebApplication)
  93. private
  94. function GetAfterModules: TStrings;
  95. function GetBaseLocation: String;
  96. function GetBeforeModules: TStrings;
  97. function GetBeforeRequest: TBeforeRequestEvent;
  98. function GetHandlerName: String;
  99. function GetIdleModuleCount: Integer;
  100. function GetMaxRequests: Integer;
  101. function GetModuleName: String;
  102. function GetPriority: THandlerPriority;
  103. function GetWorkingModuleCount: Integer;
  104. procedure SetAfterModules(const AValue: TStrings);
  105. procedure SetBaseLocation(const AValue: String);
  106. procedure SetBeforeModules(const AValue: TStrings);
  107. procedure SetBeforeRequest(const AValue: TBeforeRequestEvent);
  108. procedure SetHandlerName(const AValue: String);
  109. procedure SetMaxRequests(const AValue: Integer);
  110. procedure SetModuleName(const AValue: String);
  111. procedure SetPriority(const AValue: THandlerPriority);
  112. public
  113. function InitializeWebHandler: TWebHandler; override;
  114. Procedure Initialize;override;
  115. procedure ShowException(E: Exception); override;
  116. Function ProcessRequest(P : PRequest_Rec) : Integer; virtual;
  117. Function AllowRequest(P : PRequest_Rec) : Boolean; virtual;
  118. Procedure SetModuleRecord(Var ModuleRecord : Module);
  119. Property HandlerPriority : THandlerPriority Read GetPriority Write SetPriority default hpMiddle;
  120. Property BeforeModules : TStrings Read GetBeforeModules Write SetBeforeModules;
  121. Property AfterModules : TStrings Read GetAfterModules Write SetAfterModules;
  122. Property BaseLocation : String Read GetBaseLocation Write SetBaseLocation;
  123. Property ModuleName : String Read GetModuleName Write SetModuleName;
  124. Property HandlerName : String Read GetHandlerName Write SetHandlerName;
  125. Property BeforeRequest : TBeforeRequestEvent Read GetBeforeRequest Write SetBeforeRequest;
  126. Property MaxRequests: Integer read GetMaxRequests write SetMaxRequests;
  127. Property IdleWebModuleCount: Integer read GetIdleModuleCount;
  128. Property WorkingWebModuleCount: Integer read GetWorkingModuleCount;
  129. end;
  130. EFPApacheError = Class(EHTTP);
  131. Var
  132. Application : TCustomApacheApplication;
  133. ShowCleanUpErrors : Boolean = False;
  134. AlternateHandler : ap_hook_handler_t = Nil;
  135. implementation
  136. uses CustApp;
  137. resourcestring
  138. SErrNoModuleNameForRequest = 'Could not determine HTTP module name for request';
  139. SErrNoModuleForRequest = 'Could not determine HTTP module for request "%s"';
  140. SErrNoModuleRecord = 'No module record location set.';
  141. SErrNoModuleName = 'No module name set';
  142. SErrTooManyRequests = 'Too many simultaneous requests.';
  143. const
  144. HPRIO : Array[THandlerPriority] of Integer
  145. = (APR_HOOK_FIRST,APR_HOOK_MIDDLE,APR_HOOK_LAST);
  146. Function MaybeP(P : Pchar) : String;
  147. begin
  148. If (P<>Nil) then
  149. Result:=StrPas(P);
  150. end;
  151. Function DefaultApacheHandler(P : PRequest_Rec) : integer;cdecl;
  152. begin
  153. If (AlternateHandler<>Nil) then
  154. Result:=AlternateHandler(P)
  155. else
  156. If Application.AllowRequest(P) then
  157. Result:=Application.ProcessRequest(P)
  158. else
  159. Result:=DECLINED;
  160. end;
  161. Procedure RegisterApacheHooks(P: PApr_pool_t);cdecl;
  162. Var
  163. H : ap_hook_handler_t;
  164. PP1,PP2 : PPChar;
  165. begin
  166. H:=AlternateHandler;
  167. If (H=Nil) then
  168. H:=@DefaultApacheHandler;
  169. PP1:=Nil;
  170. PP2:=Nil;
  171. ap_hook_handler(H,PP1,PP2,HPRIO[Application.HandlerPriority]);
  172. end;
  173. { TApacheHandler }
  174. function TApacheHandler.GetModules(Index: integer): TStrings;
  175. begin
  176. If (FModules[Index]=Nil) then
  177. FModules[Index]:=TStringList.Create;
  178. Result:=FModules[Index];
  179. end;
  180. procedure TApacheHandler.SetModules(Index: integer;
  181. const AValue: TStrings);
  182. begin
  183. If (FModules[Index]=Nil) then
  184. FModules[Index]:=TStringList.Create;
  185. FModules[Index].Assign(AValue);
  186. end;
  187. Function TApacheHandler.ProcessRequest(P: PRequest_Rec) : Integer;
  188. Var
  189. Req : TApacheRequest;
  190. Resp : TApacheResponse;
  191. begin
  192. Req:=TApacheRequest.CreateReq(Self,P);
  193. Try
  194. InitRequest(Req);
  195. Req.InitRequestVars;
  196. Resp:=TApacheResponse.CreateApache(Req);
  197. Try
  198. InitResponse(Resp);
  199. HandleRequest(Req,Resp);
  200. If Not Resp.ContentSent then
  201. Resp.SendContent;
  202. Finally
  203. Result:=OK;
  204. Resp.Free;
  205. end;
  206. Finally
  207. Req.Free;
  208. end;
  209. end;
  210. procedure TApacheHandler.Run;
  211. begin
  212. // Do nothing. This is a library
  213. Initialize;
  214. end;
  215. function TApacheHandler.WaitForRequest(out ARequest: TRequest; out AResponse: TResponse): boolean;
  216. begin
  217. Result:=False;
  218. ARequest:=Nil;
  219. AResponse:=Nil;
  220. end;
  221. function TApacheHandler.AllowRequest(P: PRequest_Rec): Boolean;
  222. Var
  223. Hn : String;
  224. begin
  225. HN:=StrPas(p^.Handler);
  226. Result:=CompareText(HN,FHandlerName)=0;
  227. If Assigned(FBeforeRequest) then
  228. FBeforeRequest(Self,HN,Result);
  229. end;
  230. function TApacheHandler.GetApplicationURL(ARequest: TRequest): String;
  231. begin
  232. Result:=inherited GetApplicationURL(ARequest);
  233. If (Result='') then
  234. Result:=BaseLocation;
  235. end;
  236. constructor TApacheHandler.Create(AOwner: TComponent);
  237. begin
  238. inherited Create(AOwner);
  239. FPriority:=hpMiddle;
  240. FMaxRequests:=64;
  241. FWorkingWebModules:=TList.Create;
  242. FIdleWebModules:=TList.Create;
  243. FCriticalSection:=TCriticalSection.Create;
  244. end;
  245. destructor TApacheHandler.Destroy;
  246. var I:Integer;
  247. begin
  248. FCriticalSection.Free;
  249. for I := FIdleWebModules.Count - 1 downto 0 do
  250. TComponent(FIdleWebModules[I]).Free;
  251. FIdleWebModules.Free;
  252. for I := FWorkingWebModules.Count - 1 downto 0 do
  253. TComponent(FWorkingWebModules[I]).Free;
  254. FWorkingWebModules.Free;
  255. inherited Destroy;
  256. end;
  257. procedure TApacheHandler.SetModuleRecord(var ModuleRecord: Module);
  258. begin
  259. FModuleRecord:=@ModuleRecord;
  260. FillChar(ModuleRecord,SizeOf(ModuleRecord),0);
  261. end;
  262. procedure TApacheHandler.Initialize;
  263. begin
  264. If (FModuleRecord=nil) then
  265. Raise EFPApacheError.Create(SErrNoModuleRecord);
  266. if (FModuleName='') and (FModuleRecord^.Name=Nil) then
  267. Raise EFPApacheError.Create(SErrNoModuleName);
  268. STANDARD20_MODULE_STUFF(FModuleRecord^);
  269. If (StrPas(FModuleRecord^.name)<>FModuleName) then
  270. FModuleRecord^.Name:=PChar(FModuleName);
  271. FModuleRecord^.register_hooks:=@RegisterApacheHooks;
  272. end;
  273. procedure TApacheHandler.LogErrorMessage(const Msg: String; LogLevel: integer);
  274. begin
  275. ap_log_error(pchar(FModuleName),0,LogLevel,0,Nil,'module: %s',[pchar(Msg)]);
  276. end;
  277. function TApacheHandler.GetIdleModuleCount : Integer;
  278. begin
  279. FCriticalSection.Enter;
  280. try
  281. Result := FIdleWebModules.Count;
  282. finally
  283. FCriticalSection.Leave;
  284. end;
  285. end;
  286. function TApacheHandler.GetWorkingModuleCount : Integer;
  287. begin
  288. FCriticalSection.Enter;
  289. try
  290. Result := FWorkingWebModules.Count;
  291. finally
  292. FCriticalSection.Leave;
  293. end;
  294. end;
  295. procedure TApacheHandler.HandleRequest(ARequest: TRequest; AResponse: TResponse);
  296. Var
  297. MC : TCustomHTTPModuleClass;
  298. M : TCustomHTTPModule;
  299. MN : String;
  300. MI : TModuleItem;
  301. Procedure GetAWebModule;
  302. Var II:Integer;
  303. begin
  304. FCriticalSection.Enter;
  305. try
  306. if (FMaxRequests>0) and (FWorkingWebModules.Count>=FMaxRequests) then
  307. Raise EFPApacheError.Create(SErrTooManyRequests);
  308. if (FIdleWebModules.Count>0) then
  309. begin
  310. II := FIdleWebModules.Count - 1;
  311. while (II>=0) and not (TComponent(FIdleWebModules[II]) is MC) do
  312. Dec(II);
  313. if (II>=0) then
  314. begin
  315. M:=TCustomHTTPModule(FIdleWebModules[II]);
  316. FIdleWebModules.Delete(II);
  317. end;
  318. end;
  319. if (M=nil) then
  320. begin
  321. M:=MC.Create(Self);
  322. M.Name := '';
  323. end;
  324. FWorkingWebModules.Add(M);
  325. finally
  326. FCriticalSection.Leave;
  327. end;
  328. end;
  329. begin
  330. try
  331. MC:=Nil;
  332. M := Nil;
  333. If (OnGetModule<>Nil) then
  334. OnGetModule(Self,ARequest,MC);
  335. If (MC=Nil) then
  336. begin
  337. MN:=GetModuleName(ARequest);
  338. If (MN='') and Not AllowDefaultModule then
  339. Raise EFPApacheError.Create(SErrNoModuleNameForRequest);
  340. MI:=ModuleFactory.FindModule(MN);
  341. If (MI=Nil) and (ModuleFactory.Count=1) then
  342. MI:=ModuleFactory[0];
  343. if (MI=Nil) then
  344. Raise EFPApacheError.CreateFmt(SErrNoModuleForRequest,[MN]);
  345. MC:=MI.ModuleClass;
  346. end;
  347. GetAWebModule;
  348. M.HandleRequest(ARequest,AResponse);
  349. FCriticalSection.Enter;
  350. try
  351. FWorkingWebModules.Remove(M);
  352. FIdleWebModules.Add(M);
  353. finally
  354. FCriticalSection.Leave;
  355. end;
  356. except
  357. On E : Exception do
  358. begin
  359. LogErrorMessage(E.Message,APLOG_ERR);
  360. ShowRequestException(AResponse,E);
  361. end;
  362. end;
  363. end;
  364. { TApacheRequest }
  365. procedure TApacheRequest.ReadContent;
  366. Function MinS(A,B : Integer) : Integer;
  367. begin
  368. If A<B then
  369. Result:=A
  370. else
  371. Result:=B;
  372. end;
  373. Var
  374. Left,Len,Count,Bytes : Integer;
  375. P : Pchar;
  376. S : String;
  377. begin
  378. ap_setup_client_block(FRequest,REQUEST_CHUNKED_DECHUNK);
  379. If (ap_should_client_block(FRequest)=1) then
  380. begin
  381. Len:=ContentLength;
  382. If (Len>0) then
  383. begin
  384. SetLength(S,Len);
  385. P:=PChar(S);
  386. Left:=Len;
  387. Count:=0;
  388. Repeat
  389. Bytes:=ap_get_client_block(FRequest,P,MinS(10*1024,Left));
  390. Dec(Left,Bytes);
  391. Inc(P,Bytes);
  392. Inc(Count,Bytes);
  393. Until (Count>=Len) or (Bytes=0);
  394. SetLength(S,Count);
  395. end;
  396. end;
  397. InitContent(S);
  398. end;
  399. procedure TApacheRequest.InitFromRequest;
  400. Var
  401. H : THeader;
  402. V : String;
  403. I : Integer;
  404. begin
  405. ParseCookies;
  406. For H in THeader do
  407. begin
  408. V:=MaybeP(apr_table_get(FRequest^.headers_in,PAnsiChar(HTTPHeaderNames[h])));
  409. If (V<>'') then
  410. SetHeader(H,V);
  411. end;
  412. // Some Specials;
  413. SetHeader(hhContentEncoding,MaybeP(FRequest^.content_encoding));
  414. SetHTTPVariable(hvHTTPVersion,MaybeP(FRequest^.protocol));
  415. SetHTTPVariable(hvPathInfo,MaybeP(FRequest^.path_info));
  416. SetHTTPVariable(hvPathTranslated,MaybeP(FRequest^.filename));
  417. If (FRequest^.Connection<>Nil) then
  418. begin
  419. SetHTTPVariable(hvRemoteAddress,MaybeP(FRequest^.Connection^.remote_ip));
  420. SetHTTPVariable(hvRemoteHost,MaybeP(ap_get_remote_host(FRequest^.Connection,
  421. FRequest^.per_dir_config, REMOTE_NAME,@i)));
  422. end;
  423. V:=MaybeP(FRequest^.unparsed_uri);
  424. I:=Pos('?',V)-1;
  425. If (I=-1) then
  426. I:=Length(V);
  427. SetHTTPVariable(hvScriptName,Copy(V,1,I-Length(PathInfo)));
  428. SetHTTPVariable(hvServerPort,IntToStr(ap_get_server_port(FRequest)));
  429. SetHTTPVariable(hvMethod,MaybeP(FRequest^.method));
  430. SetHTTPVariable(hvURL,FRequest^.unparsed_uri);
  431. SetHTTPVariable(hvQuery,MaybeP(FRequest^.args));
  432. SetHeader(hhHost,MaybeP(FRequest^.HostName));
  433. ReadContent;
  434. end;
  435. constructor TApacheRequest.CreateReq(App: TApacheHandler; ARequest: PRequest_rec
  436. );
  437. begin
  438. FApache:=App;
  439. FRequest:=Arequest;
  440. ReturnedPathInfo:=App.BaseLocation;
  441. Inherited Create;
  442. InitFromRequest;
  443. end;
  444. function TApacheRequest.GetCustomHeader(const Name: String): String;
  445. begin
  446. Result:=inherited GetCustomHeader(Name);
  447. if Result='' then
  448. Result:=MaybeP(apr_table_get(FRequest^.headers_in,pchar(Name)));
  449. end;
  450. { TApacheResponse }
  451. procedure TApacheResponse.DoSendHeaders(Headers: TStrings);
  452. Var
  453. I,P : Integer;
  454. N,V : String;
  455. begin
  456. For I:=0 to Headers.Count-1 do
  457. begin
  458. V:=Headers[i];
  459. P:=Pos(':',V);
  460. If (P<>0) and (P<Length(V)) then
  461. begin
  462. N:=Copy(V,1,P-1);
  463. System.Delete(V,1,P);
  464. V := Trim(V);//no need space before the value, apache puts it there
  465. apr_table_set(FRequest^.headers_out,Pchar(N),Pchar(V));
  466. end;
  467. end;
  468. end;
  469. procedure TApacheResponse.DoSendContent;
  470. Var
  471. S : String;
  472. I : Integer;
  473. begin
  474. S:=ContentType;
  475. If (S<>'') then
  476. FRequest^.content_type:=apr_pstrdup(FRequest^.pool,Pchar(S));
  477. S:=ContentEncoding;
  478. If (S<>'') then
  479. FRequest^.content_encoding:=apr_pstrdup(FRequest^.pool,Pchar(S));
  480. If Code <> 200 then
  481. FRequest^.status := Code;
  482. If assigned(ContentStream) then
  483. SendStream(Contentstream)
  484. else
  485. for I:=0 to Contents.Count-1 do
  486. begin
  487. S:=Contents[i]+LineEnding;
  488. // If there is a null, it's written also with ap_rwrite
  489. ap_rwrite(PChar(S),Length(S),FRequest);
  490. end;
  491. end;
  492. Procedure TApacheResponse.SendStream(S : TStream);
  493. Var
  494. Buf : Array[0..(10*1024)-1] of Byte;
  495. Count : Integer;
  496. begin
  497. S.Seek(0,soBeginning);
  498. Repeat
  499. Count:=S.Read(Buf,SizeOf(Buf));
  500. If Count>0 then
  501. ap_rwrite(@Buf,Count,FRequest);
  502. Until (Count=0);
  503. end;
  504. Constructor TApacheResponse.CreateApache(Req : TApacheRequest);
  505. begin
  506. FApache:=Req.ApacheApp;
  507. Frequest:=Req.ApacheRequest;
  508. Inherited Create(Req);
  509. end;
  510. function __dummythread(p: pointer): ptrint;
  511. begin
  512. sleep(1000);
  513. Result:=0;
  514. end;
  515. { TCustomApacheApplication }
  516. function TCustomApacheApplication.GetAfterModules: TStrings;
  517. begin
  518. result := TApacheHandler(WebHandler).AfterModules;
  519. end;
  520. function TCustomApacheApplication.GetBaseLocation: String;
  521. begin
  522. result := TApacheHandler(WebHandler).BaseLocation;
  523. end;
  524. function TCustomApacheApplication.GetBeforeModules: TStrings;
  525. begin
  526. result := TApacheHandler(WebHandler).BeforeModules;
  527. end;
  528. function TCustomApacheApplication.GetBeforeRequest: TBeforeRequestEvent;
  529. begin
  530. result := TApacheHandler(WebHandler).BeforeRequest;
  531. end;
  532. function TCustomApacheApplication.GetHandlerName: String;
  533. begin
  534. result := TApacheHandler(WebHandler).HandlerName;
  535. end;
  536. function TCustomApacheApplication.GetIdleModuleCount: Integer;
  537. begin
  538. result := TApacheHandler(WebHandler).IdleWebModuleCount;
  539. end;
  540. function TCustomApacheApplication.GetMaxRequests: Integer;
  541. begin
  542. result := TApacheHandler(WebHandler).MaxRequests;
  543. end;
  544. function TCustomApacheApplication.GetModuleName: String;
  545. begin
  546. result := TApacheHandler(WebHandler).ModuleName;
  547. end;
  548. function TCustomApacheApplication.GetPriority: THandlerPriority;
  549. begin
  550. result := TApacheHandler(WebHandler).HandlerPriority;
  551. end;
  552. function TCustomApacheApplication.GetWorkingModuleCount: Integer;
  553. begin
  554. result := TApacheHandler(WebHandler).WorkingWebModuleCount;
  555. end;
  556. procedure TCustomApacheApplication.SetAfterModules(const AValue: TStrings);
  557. begin
  558. TApacheHandler(WebHandler).AfterModules := AValue;
  559. end;
  560. procedure TCustomApacheApplication.SetBaseLocation(const AValue: String);
  561. begin
  562. TApacheHandler(WebHandler).BaseLocation := AValue;
  563. end;
  564. procedure TCustomApacheApplication.SetBeforeModules(const AValue: TStrings);
  565. begin
  566. TApacheHandler(WebHandler).BeforeModules := AValue;
  567. end;
  568. procedure TCustomApacheApplication.SetBeforeRequest(const AValue: TBeforeRequestEvent);
  569. begin
  570. TApacheHandler(WebHandler).BeforeRequest := AValue;
  571. end;
  572. procedure TCustomApacheApplication.SetHandlerName(const AValue: String);
  573. begin
  574. TApacheHandler(WebHandler).HandlerName := AValue;
  575. end;
  576. procedure TCustomApacheApplication.SetMaxRequests(const AValue: Integer);
  577. begin
  578. TApacheHandler(WebHandler).MaxRequests := AValue;
  579. end;
  580. procedure TCustomApacheApplication.SetModuleName(const AValue: String);
  581. begin
  582. TApacheHandler(WebHandler).ModuleName := AValue;
  583. end;
  584. procedure TCustomApacheApplication.SetPriority(const AValue: THandlerPriority);
  585. begin
  586. TApacheHandler(WebHandler).HandlerPriority := AValue;
  587. end;
  588. function TCustomApacheApplication.InitializeWebHandler: TWebHandler;
  589. begin
  590. Result:=TApacheHandler.Create(self);
  591. end;
  592. procedure TCustomApacheApplication.Initialize;
  593. begin
  594. Inherited;
  595. TApacheHandler(WebHandler).Initialize;
  596. end;
  597. procedure TCustomApacheApplication.ShowException(E: Exception);
  598. begin
  599. ap_log_error(pchar(TApacheHandler(WebHandler).ModuleName),0,APLOG_ERR,0,Nil,'module: %s',[Pchar(E.Message)]);
  600. end;
  601. function TCustomApacheApplication.ProcessRequest(P: PRequest_Rec): Integer;
  602. begin
  603. result := TApacheHandler(WebHandler).ProcessRequest(p);
  604. end;
  605. function TCustomApacheApplication.AllowRequest(P: PRequest_Rec): Boolean;
  606. begin
  607. result := TApacheHandler(WebHandler).AllowRequest(p);
  608. end;
  609. procedure TCustomApacheApplication.SetModuleRecord(var ModuleRecord: Module);
  610. begin
  611. TApacheHandler(WebHandler).SetModuleRecord(ModuleRecord);
  612. end;
  613. Initialization
  614. BeginThread(@__dummythread);//crash prevention for simultaneous requests
  615. end.