source: trunk/Packages/CoolWeb/WebServer/WebApp.pas

Last change on this file was 151, checked in by chronos, 9 months ago
File size: 5.4 KB
Line 
1unit WebApp;
2
3interface
4
5uses
6 Classes, SysUtils, WebPage, HTTPSessionFile, HTTPServer, Forms, FileUtil,
7 Generics.Collections;
8
9type
10 THTTPServerType = (stCGI, stTCP, stTurboPower);
11
12 { TRegistredPage }
13
14 TRegistredPage = class
15 Name: string;
16 Page: TWebPage;
17 destructor Destroy; override;
18 end;
19
20 { TPageList }
21
22 TPageList = class(TObjectList<TRegistredPage>)
23 RootDir: string;
24 function FindByPage(Page: TWebPage): TRegistredPage;
25 function FindByName(Name: string): TRegistredPage;
26 procedure RegisterPage(Page: TWebPage; Path: string);
27 procedure UnregisterPage(Page: TWebPage);
28 function ProducePage(HandlerData: THTTPHandlerData): Boolean;
29 constructor Create(FreeObjects: Boolean = True);
30 end;
31
32 { TWebApp }
33
34 TWebApp = class(TComponent)
35 private
36 FOnPageProduce: TOnProduceEvent;
37 FOnInitialize: TNotifyEvent;
38 FServerType: THTTPServerType;
39 function DumpExceptionCallStack(E: Exception): string;
40 procedure HTTPServerRequest(HandlerData: THTTPHandlerData);
41 procedure SetServerType(AValue: THTTPServerType);
42 public
43 HTTPServer: THTTPServer;
44 HTTPSessionStorageFile: THTTPSessionStorageFile;
45 LogException: Boolean;
46 procedure ShowException(E: Exception);
47 constructor Create(AOwner: TComponent); override;
48 destructor Destroy; override;
49 procedure Run;
50 published
51 property OnPageProduce: TOnProduceEvent read FOnPageProduce write FOnPageProduce;
52 property OnInitialize: TNotifyEvent read FOnInitialize write FOnInitialize;
53 property ServerType: THTTPServerType read FServerType write SetServerType;
54 end;
55
56
57procedure Register;
58
59implementation
60
61uses
62 HTTPServerCGI, HTTPServerTCP, HTTPServerTurboPower;
63
64procedure Register;
65begin
66 RegisterComponents('CoolWeb', [TWebApp]);
67end;
68
69{ TRegistredPage }
70
71destructor TRegistredPage.Destroy;
72begin
73 if Assigned(Page) then FreeAndNil(Page);
74end;
75
76{ TPageList }
77
78function TPageList.FindByPage(Page: TWebPage): TRegistredPage;
79var
80 I: Integer;
81begin
82 I := 0;
83 while (I < Count) and (Items[I].Page <> Page) do Inc(I);
84 if I < Count then Result := Items[I]
85 else Result := nil;
86end;
87
88function TPageList.FindByName(Name: string): TRegistredPage;
89var
90 I: Integer;
91begin
92 I := 0;
93 while (I < Count) and (Items[I].Name <> Name) do Inc(I);
94 if I < Count then Result := Items[I]
95 else Result := nil;
96end;
97
98{ TWebApp }
99
100procedure TWebApp.Run;
101begin
102 if Assigned(FOnInitialize) then FOnInitialize(Self);
103 HTTPServer.Run;
104 if (ServerType = stCGI) or (ServerType = stTCP) then
105 Application.Terminate;
106end;
107
108function TWebApp.DumpExceptionCallStack(E: Exception): string;
109var
110 I: Integer;
111 Frames: PPointer;
112 Report: string;
113begin
114 Report := 'Program exception! ' + LineEnding +
115 'Stacktrace:' + LineEnding + LineEnding;
116 if E <> nil then begin
117 Report := Report + 'Exception class: ' + E.ClassName + LineEnding +
118 'Message: ' + E.Message + LineEnding;
119 end;
120 Report := Report + BackTraceStrFunc(ExceptAddr);
121 Frames := ExceptFrames;
122 for I := 0 to ExceptFrameCount - 1 do
123 Report := Report + LineEnding + BackTraceStrFunc(PointerArray(Frames)[I]);
124 Result := Report;
125end;
126
127procedure TPageList.RegisterPage(Page: TWebPage; Path: string);
128var
129 NewPage: TRegistredPage;
130begin
131 NewPage := TRegistredPage.Create;
132// NewPage.Page := PageClass.Create(Self);
133 NewPage.Page := Page;
134 NewPage.Name := Path;
135 Add(NewPage);
136end;
137
138procedure TPageList.UnregisterPage(Page: TWebPage);
139var
140 RegPage: TRegistredPage;
141begin
142 RegPage := FindByPage(Page);
143 Remove(RegPage);
144end;
145
146function TPageList.ProducePage(HandlerData: THTTPHandlerData): Boolean;
147var
148 Page: TRegistredPage;
149 PageName: string;
150begin
151 with HandlerData do begin
152 if Request.Path.Count > 0 then PageName := Request.Path[0]
153 else PageName := '';
154 Page := FindByName(PageName);
155 if Assigned(Page) then begin
156 Page.Page.OnProduce(HandlerData);
157 Result := True;
158 end else Result := False;
159 end;
160end;
161
162constructor TPageList.Create;
163begin
164 inherited;
165 FreeObjects := False;
166end;
167
168procedure TWebApp.HTTPServerRequest(HandlerData: THTTPHandlerData);
169begin
170 if Assigned(FOnPageProduce) then
171 FOnPageProduce(HandlerData);
172end;
173
174procedure TWebApp.SetServerType(AValue: THTTPServerType);
175begin
176 if FServerType = AValue then Exit;
177 FServerType := AValue;
178 HTTPServer.Free;
179 case FServerType of
180 stCGI: HTTPServer := THTTPServerCGI.Create(nil);
181 stTCP: HTTPServer := THTTPServerTCP.Create(nil);
182 stTurboPower: HTTPServer := THTTPServerTurboPower.Create(nil);
183 end;
184 HTTPServer.OnRequest := HTTPServerRequest;
185end;
186
187procedure TWebApp.ShowException(E: Exception);
188var
189 hstdout: ^Text;
190begin
191 if not LogException then begin
192 hstdout := @stdout;
193 WriteLn(hstdout^, 'Content-type: text/html');
194 WriteLn(hstdout^);
195 Writeln(hstdout^, 'An unhandled exception occurred: ' + E.Message + '<br>');
196 WriteLn(hstdout^, StringReplace(DumpExceptionCallStack(E), LineEnding, '<br>', [rfReplaceAll]));
197 end else begin
198 hstdout := @stdout;
199 WriteLn(hstdout^, 'Content-type: text/html');
200 WriteLn(hstdout^);
201 WriteLn(hstdout^, 'Error occured during page generation.');
202 hstdout := @stderr;
203 Writeln(hstdout^, 'An unhandled exception occurred: ' + E.Message + '<br>');
204 WriteLn(hstdout^, DumpExceptionCallStack(E));
205 end;
206end;
207
208constructor TWebApp.Create(AOwner: TComponent);
209begin
210 inherited;
211 HTTPServer := THTTPServerCGI.Create(nil);
212 HTTPServer.OnRequest := HTTPServerRequest;
213end;
214
215destructor TWebApp.Destroy;
216begin
217 FreeAndNil(HTTPServer);
218 inherited;
219end;
220
221end.
222
Note: See TracBrowser for help on using the repository browser.