source: branches/DirectWeb/UCustomWebServer.pas

Last change on this file was 91, checked in by george, 14 years ago
  • Upraveno: Třída TWebServer oddělena do samostatné jednotky.
File size: 11.3 KB
Line 
1unit UCustomWebServer;
2
3{$mode Delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, UHTTPServer, UHTTPSessionFile,
9 UTCPServer, Contnrs,
10 UCommon, syncobjs,
11 UMemoryStreamEx,
12 UMIMEType, Synautil, UPool,
13 USqlDatabase, DOM, XMLRead, UHTMLControls, UWebServer;
14
15const
16 ConfigFileName = 'Config.xml';
17
18type
19 { TDatabasePool }
20
21 TDatabasePool = class(TThreadedPool)
22 private
23 FActive: Boolean;
24 procedure SetActive(const AValue: Boolean);
25 public
26 property Active: Boolean read FActive write SetActive;
27 public
28 HostName: string;
29 Schema: string;
30 UserName: string;
31 Password: string;
32 constructor Create;
33 destructor Destroy; override;
34 end;
35
36 { TCustomWebServer }
37
38 TCustomWebServer = class(TWebServer)
39 private
40 SessionStorage: TFileHTTPSessionStorage;
41 procedure ServerInfo(HandlerData: THTTPHandlerData);
42 public
43 DatabasePool: TDatabasePool;
44
45 procedure ViewList(HandlerData: THTTPHandlerData);
46 procedure ViewItem(HandlerData: THTTPHandlerData);
47 procedure SendIndex(HandlerData: THTTPHandlerData);
48 procedure WriteHeader(Stream: TMemoryStreamEx);
49 procedure WriteFooter(Stream: TMemoryStreamEx);
50 procedure WriteMainMenu(Stream: TMemoryStreamEx);
51 constructor Create;
52 destructor Destroy; override;
53 procedure LoadConfiguration;
54 procedure Run;
55 end;
56
57implementation
58
59procedure TCustomWebServer.LoadConfiguration;
60var
61 Config: TXMLDocument;
62 I1: Integer;
63 I2: Integer;
64 I3: Integer;
65begin
66 if FileExists(ConfigFileName) then begin
67 ReadXMLFile(Config, ConfigFileName);
68 for I1 := 0 to Config.ChildNodes.Count - 1 do
69 with Config.ChildNodes[I1] do begin
70 if NodeName = 'configuration' then
71 for I2 := 0 to ChildNodes.Count - 1 do
72 with ChildNodes[I2] do begin
73 if NodeName = 'database' then
74 for I3 := 0 to ChildNodes.Count - 1 do
75 with ChildNodes[I3] do begin
76 if NodeName = 'hostname' then
77 DatabasePool.HostName := TextContent;
78 if NodeName = 'schema' then
79 DatabasePool.Schema := TextContent;
80 if NodeName = 'username' then
81 DatabasePool.UserName := TextContent;
82 if NodeName = 'password' then
83 DatabasePool.Password := TextContent;
84 end;
85 if NodeName = 'server' then
86 for I3 := 0 to ChildNodes.Count - 1 do
87 with ChildNodes[I3] do begin
88 if NodeName = 'address' then
89 HTTPServer.Socket.Address := TextContent;
90 if NodeName = 'port' then
91 HTTPServer.Socket.Port := StrToInt(TextContent);
92 end;
93 end;
94 end;
95 Config.Destroy;
96 end;
97end;
98
99procedure TCustomWebServer.Run;
100var
101 Command: string;
102begin
103 LoadConfiguration;
104 DatabasePool.Active := True;
105 WriteLn('WoW hosting web server');
106 with HTTPServer do begin
107 Socket.Active := True;
108 WriteLn('Accepting connections.');
109 repeat
110 Write('Server command: ');
111 ReadLn(Command);
112 until Command = 'quit';
113 //WaitForFinish;
114 end;
115end;
116
117procedure TCustomWebServer.ViewList(HandlerData: THTTPHandlerData);
118var
119 SqlDatabase: TSqlDatabase;
120 DbRows: TDbRows;
121 I, II: integer;
122 OrderColumn: string;
123 OrderDirection: string;
124 Title: string;
125 LinkQuery: TQueryParameterList;
126 PageList: TPageList;
127begin
128 SqlDatabase := TSqlDatabase(DatabasePool.Acquire);
129 with HandlerData, Response, Stream, SqlDatabase do
130 begin
131 WriteHeader(Stream);
132
133 WriteString('<div class="Page">');
134
135 // Prepare table paging
136 DbRows := Query('SELECT COUNT(*) FROM ' + Request.Query.Values['Table']);
137 PageList := TPageList.Create;
138 PageList.HandlerData := HandlerData;
139 with PageList do begin
140 TotalCount := StrToInt(DbRows[0].ValuesAtIndex[0]);
141 ItemPerPage := 20;
142 NavigatorVisibleItems := 5;
143 Process;
144 end;
145 DbRows.Destroy;
146
147 //WriteString(Request.Query.Values['Table']);
148 OrderColumn := Request.Query.Values['OrderCol'];
149 OrderDirection := Request.Query.Values['OrderDir'];
150 if OrderDirection = '1' then
151 OrderDirection := 'ASC'
152 else
153 OrderDirection := 'DESC';
154 DbRows := Query('SELECT * FROM ' + Request.Query.Values['Table'] +
155 ' ORDER BY ' + OrderColumn + ' ' + OrderDirection + PageList.SQLLimit);
156
157 LinkQuery := TQueryParameterList.Create;
158 LinkQuery.Assign(Request.Query);
159
160 WriteString('<strong>Seznam typů karet</strong><br/>');
161 WriteString(PageList.Output);
162 WriteString('<table><tr>');
163 if DbRows.Count > 0 then
164 for I := 0 to DbRows[0].Count - 1 do
165 begin
166 Title := DbRows[0].Names[I];
167 LinkQuery.Values['OrderCol'] := Title;
168 if Title = OrderColumn then
169 LinkQuery.Values['OrderDir'] :=
170 IntToStr(1 - StrToInt(Request.Query.Values['OrderDir']))
171 else
172 LinkQuery.Values['OrderDir'] := Request.Query.Values['OrderDir'];
173 Title := '<a href="?' + LinkQuery.Syntetize + '">' + Title + '</a>';
174
175 WriteString('<th>' + Title + '</th>');
176 end;
177 WriteString('</tr>');
178
179 LinkQuery.Destroy;
180 for II := 0 to DbRows.Count - 1 do
181 begin
182 WriteString('<tr>');
183 for I := 0 to DbRows[II].Count - 1 do
184 WriteString('<td>' + DbRows[II].ValuesAtIndex[I] + '</td>');
185 WriteString('</tr>');
186 end;
187 WriteString('</table>');
188 WriteString(PageList.Output);
189 WriteString('</div>');
190
191 DbRows.Destroy;
192 WriteFooter(Stream);
193 end;
194 PageList.Destroy;
195 DatabasePool.Release(SqlDatabase);
196end;
197
198procedure TCustomWebServer.ViewItem(HandlerData: THTTPHandlerData);
199var
200 SqlDatabase: TSqlDatabase;
201 DbRows: TDbRows;
202 I, II: Integer;
203 OrderColumn: string;
204 OrderDirection: string;
205 Title: string;
206 LinkQuery: TQueryParameterList;
207begin
208 SqlDatabase := TSqlDatabase(DatabasePool.Acquire);
209 with HandlerData, Response, Stream, SqlDatabase do
210 begin
211 WriteHeader(Stream);
212 DbRows := Query('SELECT * FROM ' + Request.Query.Values['Table'] +
213 ' WHERE Id=' + Request.Query.Values['Id']);
214 if DbRows.Count > 0 then begin
215 WriteString('<strong>Zobrazení položky</strong>');
216 WriteString('<table><tr><th>Vlastnost</th><th>Hodnota</th></tr>');
217 for I := 0 to DbRows[0].Count - 1 do begin
218 WriteString('<tr><td>' + DbRows[0].Names[I] + '</td><td>' +
219 DbRows[0].ValuesAtIndex[I] + '</td></tr>');
220 end;
221 end else WriteString('Položka nenalezena.');
222 WriteString('</table>');
223 DbRows.Destroy;
224 WriteFooter(Stream);
225 end;
226 DatabasePool.Release(SqlDatabase);
227end;
228
229procedure TCustomWebServer.ServerInfo(HandlerData: THTTPHandlerData);
230var
231 I: Integer;
232begin
233 with HandlerData, Response.Stream do begin
234 //Response.Cookies.Values['Test'] := 'Halo';
235 //Response.Cookies.Values['Test2'] := 'Halo2';
236
237 //HTTPServer.SessionHandler.Variables.Values['Session1'] := 'Value1';
238 //HTTPServer.SessionHandler.Variables.Values['Session2'] := 'Value2';
239
240 WriteString('<a href="?ServerInfo">Refresh</a>');
241
242 WriteString('<h5>Request HTTP headers</h5>');
243 for I := 0 to Request.Headers.Count - 1 do begin;
244 WriteString(Request.Headers.Strings[I] + '<br/>');
245 end;
246
247 WriteString('<h5>Request HTTP cookies</h5>');
248 for I := 0 to Request.Cookies.Count - 1 do begin;
249 WriteString(Request.Cookies.Strings[I] + '<br/>');
250 end;
251
252 WriteString('<h5>Session variables</h5>');
253 for I := 0 to Session.Count - 1 do begin;
254 WriteString(Session.Strings[I] + '<br/>');
255 end;
256
257 WriteString('<h5>Response HTTP headers</h5>');
258 with Response.Stream do
259 for I := 0 to Response.Headers.Count - 1 do begin;
260 WriteString(Response.Headers.Strings[I] + '<br/>');
261 end;
262 end;
263end;
264
265procedure TCustomWebServer.SendIndex(HandlerData: THTTPHandlerData);
266begin
267 with HandlerData, Response, Stream do
268 begin
269 WriteHeader(Stream);
270 WriteString('Index');
271 WriteFooter(Stream);
272 end;
273end;
274
275procedure TCustomWebServer.WriteHeader(Stream: TMemoryStreamEx);
276begin
277 with Stream do
278 begin
279 WriteString('<?xml version="1.0" encoding="UTF-8"?>');
280 WriteString('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">');
281 WriteString('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs">');
282 WriteString('<head>');
283 WriteString('<title>');
284 WriteString('Dispečink výtahů');
285 WriteString('</title>');
286 WriteString('<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8"/>');
287 WriteString('<link rel="stylesheet" href="Style.css" type="text/css" media="all"/>');
288 WriteString('<script type="text/javascript" src="Application/Style/Custom/Global.js">');
289 WriteString('</script>');
290 WriteString('<script type="text/javascript" src="Base/Style/jquery.js">');
291 WriteString('</script>');
292 WriteString('</head>');
293 WriteString('<body>');
294 WriteMainMenu(Stream);
295 end;
296end;
297
298procedure TCustomWebServer.WriteFooter(Stream: TMemoryStreamEx);
299begin
300 with Stream do
301 begin
302 WriteString('</body>');
303 WriteString('</html>');
304 end;
305end;
306
307procedure TCustomWebServer.WriteMainMenu(Stream: TMemoryStreamEx);
308var
309 SqlDatabase: TSqlDatabase;
310 DbRows: TDbRows;
311 I, II: integer;
312begin
313 SqlDatabase := TSqlDatabase(DatabasePool.Acquire);
314 with SqlDatabase, Stream do begin
315 WriteString('<div class="MainMenu">');
316 DbRows := Query('SELECT Name FROM Object');
317 for I := 0 to DbRows.Count - 1 do begin
318 WriteString('<span><a href="?Table=' + DbRows[I].ValuesAtIndex[0] + '&OrderCol=Id&OrderDir=0">' +
319 DbRows[I].ValuesAtIndex[0] + '</span>');
320 end;
321 DbRows.Destroy;
322 WriteString('</div>');
323 end;
324 DatabasePool.Release(SqlDatabase);
325end;
326
327constructor TCustomWebServer.Create;
328begin
329 inherited Create;
330 DatabasePool := TDatabasePool.Create;
331 DatabasePool.TotalCount := 20;
332
333 SessionStorage := TFileHTTPSessionStorage.Create;
334 with HTTPServer, Socket do begin
335 SessionStorage := Self.SessionStorage;
336 DocumentRoot := 'Data';
337 with RequestHandlerList do begin
338 Add('/', SendIndex);
339 Add('/index.htm', SendIndex);
340 Add('/index.html', SendIndex);
341 Add('/logo.png', FileResponse);
342 Add('/Style.css', FileResponse);
343 Add('/ViewList', ViewList);
344 Add('/ViewItem', ViewItem);
345 Add('/ServerInfo', ServerInfo);
346 end;
347 end;
348end;
349
350destructor TCustomWebServer.Destroy;
351begin
352 DatabasePool.Destroy;
353 SessionStorage.Destroy;
354 inherited Destroy;
355end;
356
357{ TDatabasePool }
358
359procedure TDatabasePool.SetActive(const AValue: Boolean);
360var
361 I: Integer;
362begin
363 if not FActive and AValue then begin
364 for I := 0 to TotalCount - 1 do
365 with TThreadedPoolItem(Items[I]) do begin
366 Item := TSqlDatabase.Create;
367 with TSqlDatabase(Item) do begin
368 HostName := Self.HostName;
369 UserName := Self.UserName;
370 Password := Self.Password;
371 Database := Self.Schema;
372 Connect;
373 end;
374 end;
375 end else
376 if FActive and not AValue then begin
377
378 end;
379 FActive := AValue;
380end;
381
382constructor TDatabasePool.Create;
383begin
384 inherited;
385end;
386
387destructor TDatabasePool.Destroy;
388begin
389 inherited Destroy;
390end;
391
392end.
393
Note: See TracBrowser for help on using the repository browser.