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

Last change on this file was 151, checked in by chronos, 5 months ago
File size: 4.9 KB
Line 
1unit HTTPServerTCP;
2
3interface
4
5uses
6 Classes, SysUtils, HTTPServer, TCPServer, SynaUtil, Generics.Collections,
7 Generics;
8
9type
10
11 { THTTPServerTCP }
12
13 THTTPServerTCP = class(THTTPServer)
14 private
15 FMaxConnection: Integer;
16 procedure HandleClient(Sender: TObject);
17 public
18 Socket: TTCPServer;
19 RequestHandlerList: TRequestHandlerList;
20 constructor Create(AOwner: TComponent); override;
21 destructor Destroy; override;
22 procedure Run; override;
23 published
24 property MaxConnection: Integer read FMaxConnection write FMaxConnection;
25 end;
26
27procedure Register;
28
29
30implementation
31
32procedure Register;
33begin
34 RegisterComponents('CoolWeb', [THTTPServerTCP]);
35end;
36
37procedure THTTPServerTCP.HandleClient(Sender: TObject);
38var
39 Line: string;
40 LineIndex: Integer;
41 LineParts: TListString;
42 HandlerData: THTTPHandlerData;
43 I: Integer;
44 ContentLength: Integer;
45 Value: string;
46 Item: TPair<string, string>;
47begin
48 with TTCPClientThread(Sender), Socket do begin
49 WriteLn('Thread ' + IntToStr(Id) + ' from ' + IntToStr(Parent.ThreadPool.UsedCount) + '. Client connected from ' + GetRemoteSinIP);
50
51 HandlerData := THTTPHandlerData.Create;
52 with HandlerData do try
53 Server := Self;
54
55 Response := THTTPResponse.Create;
56 Response.Headers.Add('Server', Name);
57 Request := THTTPRequest.Create;
58 LineIndex := 0;
59 try
60 LineParts := TListString.Create;
61 repeat
62 Line := RecvString(10000);
63 WriteLn(IntToStr(Id) + ' ' + Line);
64 if (LineIndex = 0) then begin
65 LineParts.Explode(' ', Line);
66 if (LineParts.Count >= 3) then begin
67 Request.Method := LineParts[0];
68 if Pos('?', LineParts[1]) > 0 then begin
69 Request.Query.Parse(Copy(LineParts[1], Pos('?', LineParts[1]) + 1, Length(LineParts[1])));
70 Request.Path.Explode('/', Copy(LineParts[1], 1, Pos('?', LineParts[1]) - 1));
71 end else begin
72 Request.Path.Explode('/', LineParts[1]);
73 Request.Query.Clear;
74 end;
75 // Clean empty path parts
76 for I := Request.Path.Count - 1 downto 0 do
77 if Request.Path[I] = '' then Request.Path.Delete(I);
78 end;
79 end else begin
80 LineParts.Explode(' ', Line, 2);
81 if (LineParts.Count = 2) and (LineParts[0][Length(LineParts[0])] = ':') then begin
82 LineParts[0] := Copy(LineParts[0], 1, Length(LineParts[0]) - 1);
83 Request.Headers.Add(LineParts[0], LineParts[1]);
84 end;
85 end;
86 Inc(LineIndex);
87 until Line = '';
88
89 if Request.Method = 'POST' then begin
90 if Request.Headers.TryGetValue('Content-Length', Value) then
91 ContentLength := StrToInt(Value);
92 SetLength(Line, ContentLength);
93 RecvBufferEx(PByte(Line), ContentLength, 1000);
94 Request.Post.Parse(Line);
95 end;
96 finally
97 LineParts.Free;
98 end;
99
100 // Process cookies
101 if Request.Headers.TryGetValue('Cookie', Value) then
102 Request.Cookies.Parse(Value);
103
104 // Load session variables
105 if Assigned(SessionStorage) then
106 SessionStorage.Load(HandlerData);
107
108 Response.Content.Clear;
109 Response.Headers.Add('Content-Type', 'text/html');
110
111 if Assigned(OnRequest) then OnRequest(HandlerData)
112 else raise EEmptyHTTPHandler.Create(SEmptyHTTPHandler);
113
114 // Store session variables
115 if Assigned(SessionStorage) then
116 SessionStorage.Save(HandlerData);
117
118 with Response do begin
119 SendString('HTTP/1.0 ' + StatusCode + #13#10);
120 Headers.Add('Content-Length', IntToStr(Content.Size));
121 Headers.Add('Connection', 'close');
122 Headers.Add('Date', RFC822DateTime(Now));
123
124 // Handle cookies
125 for Item in Cookies do
126 Headers.Add('Set-Cookie', Item.Key + '=' + Item.Value);
127 // + ';path=/;expires=' + RFC822DateTime(Now);
128
129 // Send headers
130 for Item in Headers do begin
131 //WriteLn(Headers.Keys[I] + ': ' + Headers.Items[I].Value + #13#10);
132 SendString(Item.Key + ': ' + Item.Value + #13#10);
133 end;
134 SendString(#13#10);
135 SendBuffer(Content.Memory, Content.Size);
136 SendString(#13#10);
137 end;
138 finally
139 Free;
140 end;
141 end;
142end;
143
144{ THTTPServerTCP }
145
146constructor THTTPServerTCP.Create(AOwner: TComponent);
147begin
148 inherited;
149 MaxConnection := 10000;
150 Socket := TTCPServer.Create;
151 Socket.OnClientConnect := HandleClient;
152 RequestHandlerList := TRequestHandlerList.Create;
153end;
154
155destructor THTTPServerTCP.Destroy;
156begin
157 FreeAndNil(Socket);
158 FreeAndNil(RequestHandlerList);
159 inherited;
160end;
161
162procedure THTTPServerTCP.Run;
163begin
164 inherited Run;
165 WriteLn('HTTP Server started in TCP mode.');
166 WriteLn('Listen on ' + Socket.Address + ':' + IntToStr(Socket.Port));
167 WriteLn('Press any key to terminate...');
168 Socket.ThreadPool.TotalCount := MaxConnection;
169 Socket.Active := True;
170 ReadLn;
171 WriteLn('Exiting');
172end;
173
174end.
175
Note: See TracBrowser for help on using the repository browser.