source: trunk/Packages/synapse/source/demo/httpsserv/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: 5.6 KB
Line 
1unit http;
2
3{ Marked some code with !!!}
4
5interface
6
7uses
8 Classes, blcksock, winsock, Synautil, ssl_openssl, SysUtils, Dialogs;
9
10type
11 TTCPHttpDaemon = class(TThread)
12 private
13 Sock:TTCPBlockSocket;
14 public
15 Constructor Create;
16 Destructor Destroy; override;
17 procedure Execute; override;
18 end;
19
20 TTCPHttpThrd = class(TThread)
21 private
22 Sock:TTCPBlockSocket;
23 public
24 Headers: TStringList;
25 InputData, OutputData: TMemoryStream;
26 Constructor Create (hsock:tSocket);
27 Destructor Destroy; override;
28 procedure Execute; override;
29 function ProcessHttpRequest(Request, URI: string): integer;
30 end;
31
32implementation
33
34{ TTCPHttpDaemon }
35
36Constructor TTCPHttpDaemon.Create;
37begin
38 sock:=TTCPBlockSocket.create;
39 FreeOnTerminate:=true;
40 inherited create(false);
41end;
42
43Destructor TTCPHttpDaemon.Destroy;
44begin
45 Sock.free;
46 inherited Destroy;
47end;
48
49procedure TTCPHttpDaemon.Execute;
50var
51 ClientSock:TSocket;
52begin
53 with sock do
54 begin
55 CreateSocket;
56 setLinger(true,10000);
57 bind('0.0.0.0','443');
58 listen;
59 repeat
60 if terminated then break;
61 if canread(1000) then
62 begin
63 ClientSock:=accept;
64 if lastError=0 then TTCPHttpThrd.create(ClientSock);
65 end;
66 until false;
67 end;
68end;
69
70{ TTCPHttpThrd }
71
72Constructor TTCPHttpThrd.Create(Hsock:TSocket);
73begin
74 sock:=TTCPBlockSocket.create;
75 Headers := TStringList.Create;
76 InputData := TMemoryStream.Create;
77 OutputData := TMemoryStream.Create;
78 Sock.socket:=HSock;
79 FreeOnTerminate:=true;
80 inherited create(false);
81end;
82
83Destructor TTCPHttpThrd.Destroy;
84begin
85 Sock.free;
86 Headers.Free;
87 InputData.Free;
88 OutputData.Free;
89 inherited Destroy;
90end;
91
92procedure TTCPHttpThrd.Execute;
93var
94 timeout: integer;
95 s: string;
96 method, uri, protocol: string;
97 size: integer;
98 x, n: integer;
99 resultcode: integer;
100begin
101 timeout := 120000;
102
103 // Note: There's no need for installing a client certificate in the
104 // webbrowser. The server asks the webbrowser to send a certificate but
105 // if nothing is installed the software will work because the server
106 // doesn't check to see if a client certificate was supplied. If you
107 // want you can install:
108 //
109 // file: c_cacert.p12
110 // password: c_cakey
111 //
112 Sock.SSL.CertCAFile := ExtractFilePath(ParamStr(0)) + 's_cabundle.pem';
113 Sock.SSL.CertificateFile := ExtractFilePath(ParamStr(0)) + 's_cacert.pem';
114 Sock.SSL.PrivateKeyFile := ExtractFilePath(ParamStr(0)) + 's_cakey.pem';
115 Sock.SSL.KeyPassword := 's_cakey';
116 Sock.SSL.verifyCert := True;
117
118 try
119 if (not Sock.SSLAcceptConnection) or
120 (Sock.SSL.LastError <> 0) then
121 begin
122 MessageDlg('Error while accepting SSL connection: ' + Sock.SSL.LastErrorDesc, mtError, [mbAbort], 0);
123 Exit;
124 end;
125 except
126 MessageDlg('Exception while accepting SSL connection', mtError, [mbAbort], 0);
127 Exit;
128 end;
129
130
131 //read request line
132 s := sock.RecvString(timeout);
133 if sock.lasterror <> 0 then
134 Exit;
135 if s = '' then
136 Exit;
137 method := fetch(s, ' ');
138 if (s = '') or (method = '') then
139 Exit;
140 uri := fetch(s, ' ');
141 if uri = '' then
142 Exit;
143 protocol := fetch(s, ' ');
144 headers.Clear;
145 size := -1;
146 //read request headers
147 if protocol <> '' then
148 begin
149 if pos('HTTP/', protocol) <> 1 then
150 Exit;
151 repeat
152 s := sock.RecvString(Timeout);
153 if sock.lasterror <> 0 then
154 Exit;
155 if s <> '' then
156 Headers.add(s);
157 if Pos('CONTENT-LENGTH:', Uppercase(s)) = 1 then
158 Size := StrToIntDef(SeparateRight(s, ' '), -1);
159 until s = '';
160 end;
161 //recv document...
162 InputData.Clear;
163 if size >= 0 then
164 begin
165 InputData.SetSize(Size);
166 x := Sock.RecvBufferEx(InputData.Memory, Size, Timeout);
167 InputData.SetSize(x);
168 if sock.lasterror <> 0 then
169 Exit;
170 end;
171 OutputData.Clear;
172 ResultCode := ProcessHttpRequest(method, uri);
173 sock.SendString('HTTP/1.0 ' + IntTostr(ResultCode) + CRLF);
174 if protocol <> '' then
175 begin
176 headers.Add('Content-length: ' + IntTostr(OutputData.Size));
177 headers.Add('Connection: close');
178 headers.Add('Date: ' + Rfc822DateTime(now));
179 headers.Add('Server: Synapse HTTP server demo');
180 headers.Add('');
181 for n := 0 to headers.count - 1 do
182 sock.sendstring(headers[n] + CRLF);
183 end;
184 if sock.lasterror <> 0 then
185 Exit;
186 Sock.SendBuffer(OutputData.Memory, OutputData.Size);
187end;
188
189function TTCPHttpThrd.ProcessHttpRequest(Request, URI: string): integer;
190var
191 l: TStringlist;
192begin
193//sample of precessing HTTP request:
194// InputData is uploaded document, headers is stringlist with request headers.
195// Request is type of request and URI is URI of request
196// OutputData is document with reply, headers is stringlist with reply headers.
197// Result is result code
198 result := 504;
199 if request = 'GET' then
200 begin
201 headers.Clear;
202 headers.Add('Content-type: Text/Html');
203 l := TStringList.Create;
204 try
205 l.Add('<html>');
206 l.Add('<head></head>');
207 l.Add('<body>');
208 l.Add('Request Uri: ' + uri);
209 l.Add('<br>');
210 l.Add('This document is generated by Synapse HTTPS server demo!');
211 if Sock.SSL.GetPeerName = '' then
212 l.Add('No client certificate received')
213 else
214 l.Add('Client certificate received from ' + Sock.SSL.GetPeerName);
215 l.Add('</body>');
216 l.Add('</html>');
217 l.SaveToStream(OutputData);
218 finally
219 l.free;
220 end;
221 Result := 200;
222 end;
223end;
224
225end.
Note: See TracBrowser for help on using the repository browser.