source: trunk/Packages/synapse/source/demo/httpserv/http.pas

Last change on this file was 2, checked in by chronos, 12 years ago
  • Přidáno: Základní kostra projektu.
  • Přidáno: Knihovna synapse.
File size: 4.8 KB
Line 
1unit http;
2
3interface
4
5uses
6 Classes, blcksock, winsock, Synautil, SysUtils;
7
8type
9 TTCPHttpDaemon = class(TThread)
10 private
11 Sock:TTCPBlockSocket;
12 public
13 Constructor Create;
14 Destructor Destroy; override;
15 procedure Execute; override;
16 end;
17
18 TTCPHttpThrd = class(TThread)
19 private
20 Sock:TTCPBlockSocket;
21 public
22 Headers: TStringList;
23 InputData, OutputData: TMemoryStream;
24 Constructor Create (hsock:tSocket);
25 Destructor Destroy; override;
26 procedure Execute; override;
27 function ProcessHttpRequest(Request, URI: string): integer;
28 end;
29
30implementation
31
32{ TTCPHttpDaemon }
33
34Constructor TTCPHttpDaemon.Create;
35begin
36 inherited create(false);
37 sock:=TTCPBlockSocket.create;
38 FreeOnTerminate:=true;
39end;
40
41Destructor TTCPHttpDaemon.Destroy;
42begin
43 Sock.free;
44 inherited Destroy;
45end;
46
47procedure TTCPHttpDaemon.Execute;
48var
49 ClientSock:TSocket;
50begin
51 with sock do
52 begin
53 CreateSocket;
54 setLinger(true,10000);
55 bind('0.0.0.0','80');
56 listen;
57 repeat
58 if terminated then break;
59 if canread(1000) then
60 begin
61 ClientSock:=accept;
62 if lastError=0 then TTCPHttpThrd.create(ClientSock);
63 end;
64 until false;
65 end;
66end;
67
68{ TTCPHttpThrd }
69
70Constructor TTCPHttpThrd.Create(Hsock:TSocket);
71begin
72 sock:=TTCPBlockSocket.create;
73 Headers := TStringList.Create;
74 InputData := TMemoryStream.Create;
75 OutputData := TMemoryStream.Create;
76 Sock.socket:=HSock;
77 FreeOnTerminate:=true;
78 Priority:=tpNormal;
79 inherited create(false);
80end;
81
82Destructor TTCPHttpThrd.Destroy;
83begin
84 Sock.free;
85 Headers.Free;
86 InputData.Free;
87 OutputData.Free;
88 inherited Destroy;
89end;
90
91procedure TTCPHttpThrd.Execute;
92var
93 timeout: integer;
94 s: string;
95 method, uri, protocol: string;
96 size: integer;
97 x, n: integer;
98 resultcode: integer;
99 close: boolean;
100begin
101 timeout := 120000;
102 repeat
103 //read request line
104 s := sock.RecvString(timeout);
105 if sock.lasterror <> 0 then
106 Exit;
107 if s = '' then
108 Exit;
109 method := fetch(s, ' ');
110 if (s = '') or (method = '') then
111 Exit;
112 uri := fetch(s, ' ');
113 if uri = '' then
114 Exit;
115 protocol := fetch(s, ' ');
116 headers.Clear;
117 size := -1;
118 close := false;
119 //read request headers
120 if protocol <> '' then
121 begin
122 if pos('HTTP/', protocol) <> 1 then
123 Exit;
124 if pos('HTTP/1.1', protocol) <> 1 then
125 close := true;
126 repeat
127 s := sock.RecvString(Timeout);
128 if sock.lasterror <> 0 then
129 Exit;
130 if s <> '' then
131 Headers.add(s);
132 if Pos('CONTENT-LENGTH:', Uppercase(s)) = 1 then
133 Size := StrToIntDef(SeparateRight(s, ' '), -1);
134 if Pos('CONNECTION: CLOSE', Uppercase(s)) = 1 then
135 close := true;
136 until s = '';
137 end;
138 //recv document...
139 InputData.Clear;
140 if size >= 0 then
141 begin
142 InputData.SetSize(Size);
143 x := Sock.RecvBufferEx(InputData.Memory, Size, Timeout);
144 InputData.SetSize(x);
145 if sock.lasterror <> 0 then
146 Exit;
147 end;
148 OutputData.Clear;
149 ResultCode := ProcessHttpRequest(method, uri);
150 sock.SendString(protocol + ' ' + IntTostr(ResultCode) + CRLF);
151 if protocol <> '' then
152 begin
153 headers.Add('Content-length: ' + IntTostr(OutputData.Size));
154 if close then
155 headers.Add('Connection: close');
156 headers.Add('Date: ' + Rfc822DateTime(now));
157 headers.Add('Server: Synapse HTTP server demo');
158 headers.Add('');
159 for n := 0 to headers.count - 1 do
160 sock.sendstring(headers[n] + CRLF);
161 end;
162 if sock.lasterror <> 0 then
163 Exit;
164 Sock.SendBuffer(OutputData.Memory, OutputData.Size);
165 if close then
166 Break;
167 until Sock.LastError <> 0;
168end;
169
170function TTCPHttpThrd.ProcessHttpRequest(Request, URI: string): integer;
171var
172 l: TStringlist;
173begin
174//sample of precessing HTTP request:
175// InputData is uploaded document, headers is stringlist with request headers.
176// Request is type of request and URI is URI of request
177// OutputData is document with reply, headers is stringlist with reply headers.
178// Result is result code
179 result := 504;
180 if request = 'GET' then
181 begin
182 headers.Clear;
183 headers.Add('Content-type: Text/Html');
184 l := TStringList.Create;
185 try
186 l.Add('<html>');
187 l.Add('<head></head>');
188 l.Add('<body>');
189 l.Add('Request Uri: ' + uri);
190 l.Add('<br>');
191 l.Add('This document is generated by Synapse HTTP server demo!');
192 l.Add('</body>');
193 l.Add('</html>');
194 l.SaveToStream(OutputData);
195 finally
196 l.free;
197 end;
198 Result := 200;
199 end;
200end;
201
202end.
Note: See TracBrowser for help on using the repository browser.