📄 webserv1.pas
字号:
{ We just count the request, display a message and let HTTP server }
{ component handle everything. }
{ We should trap every URI we handle internally... }
procedure TWebServForm.HttpServer1HeadDocument(
Sender : TObject; { HTTP server component }
Client : TObject; { Client connection issuing command }
var Flags : THttpGetFlag); { Tells what HTTP server has to do next }
var
ClientCnx : TMyHttpConnection;
begin
{ It's easyer to do the cast one time. Could use with clause... }
ClientCnx := TMyHttpConnection(Client);
Inc(FCountRequests);
Display('[' + FormatDateTime('HH:NN:SS', Now) + ' ' +
ClientCnx.GetPeerAddr + '] ' + IntToStr(FCountRequests) +
': ' + ClientCnx.Version + ' HEAD ' + ClientCnx.Path);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function IsDirectory(const Path : String) : Boolean;
var
SR : TSearchRec;
begin
if FindFirst(Path, faDirectory or faAnyFile, SR) = 0 then
Result := ((SR.Attr and faDirectory) <> 0)
else
Result := FALSE;
FindClose(SR);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ This event handler is triggered when HTTP server component receive a GET }
{ command from any client. }
{ We count the request, display a message and trap '/time.htm' path for }
{ special handling. }
{ There is no document time.htm on disk, we will create it on the fly. With }
{ a classic webserver we would have used a CGI or ISAPI/NSAPI to achieve }
{ the same goal. It is much easier here since we can use Delphi code }
{ directly to generate whatever we wants. Here for the demo we generate a }
{ page with server data and time displayed. }
procedure TWebServForm.HttpServer1GetDocument(
Sender : TObject; { HTTP server component }
Client : TObject; { Client connection issuing command }
var Flags : THttpGetFlag); { Tells what HTTP server has to do next }
var
ClientCnx : TMyHttpConnection;
begin
{ It's easyer to do the cast one time. Could use with clause... }
ClientCnx := TMyHttpConnection(Client);
{ Count request and display a message }
Inc(FCountRequests);
Display('[' + FormatDateTime('HH:NN:SS', Now) + ' ' +
ClientCnx.GetPeerAddr + '] ' + IntToStr(FCountRequests) +
': ' + ClientCnx.Version + ' GET ' + ClientCnx.Path);
DisplayHeader(ClientCnx);
{ Instead of the long if/then/else below, we could use a lookup table }
{ Trap '/demo.html' to dynamically generate a simple HTML document }
if CompareText(ClientCnx.Path, '/demo.html') = 0 then
CreateVirtualDocument_Demo(Sender, ClientCnx, Flags)
{ Trap '/time.html' path to dynamically generate a dynamic answer. }
else if CompareText(ClientCnx.Path, '/time.html') = 0 then
CreateVirtualDocument_Time(Sender, ClientCnx, Flags)
{ Trap '/myip.html' path to dynamically generate a dynamic answer. }
else if CompareText(ClientCnx.Path, '/myip.html') = 0 then
CreateVirtualDocument_MyIP(Sender, ClientCnx, Flags)
{ Trap '/HeaderBug.html' path to dynamically generate a dynamic answer. }
else if CompareText(ClientCnx.Path, '/HeaderBug.html') = 0 then
CreateVirtualDocument_HeaderBug(Sender, ClientCnx, Flags)
{ Trap '/redir.html' to dynamically generate a redirection answer }
else if CompareText(ClientCnx.Path, '/redir.html') = 0 then
CreateVirtualDocument_Redir(Sender, ClientCnx, Flags)
{ Trap '/formdata.html' to dynamically generate a HTML form answer }
else if CompareText(ClientCnx.Path, '/formdata.html') = 0 then
CreateVirtualDocument_ViewFormData{CreateVirtualDocument_formdata_htm}(Sender, ClientCnx, Flags)
else if CompareText(ClientCnx.Path, '/template.html') = 0 then
CreateVirtualDocument_template(Sender, ClientCnx, Flags);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ This procedure is use to generate /demo.html document }
procedure TWebServForm.CreateVirtualDocument_Demo(
Sender : TObject;
ClientCnx : TMyHttpConnection;
var Flags : THttpGetFlag);
begin
ClientCnx.AnswerString(Flags,
'', { Default Status '200 OK' }
'', { Default Content-Type: text/html }
'', { Default header }
'<HTML>' +
'<HEAD>' +
'<TITLE>ICS WebServer Demo - Menu</TITLE>' +
'</HEAD>' +
'<BODY>' +
'<H2>ICS WebServer Demo Menu</H2>' +
'<A HREF="/time.html">Server time</A><BR>' +
'<A HREF="/template.html">Template demo</A><BR>' +
'<A HREF="/form.html">Data entry</A><BR>' +
'<A HREF="/formdata.html">Show data file</A><BR>' +
'<A HREF="/redir.html">Redirection</A><BR>' +
'<A HREF="/myip.html">Show client IP</A><BR>' +
'<A HREF="/">Default document</A><BR>' +
'<A HREF="http://www.overbyte.be">ICS Home page</A><BR>' +
'</BODY>' +
'</HTML>');
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TWebServForm.CreateVirtualDocument_Template(
Sender : TObject;
ClientCnx : TMyHttpConnection;
var Flags : THttpGetFlag);
begin
ClientCnx.AnswerPage(
Flags,
'',
NO_CACHE,
'TemplateDemo.html',
nil,
['TIME', DateTimeToStr(Now),
'PROGVER', WebServVersion,
'SOURCE', TextToHtmlText(HttpServer1.TemplateDir +
'TemplateDemo.html')]);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ This procedure is use to generate /redir.html document }
procedure TWebServForm.CreateVirtualDocument_Redir(
Sender : TObject; { HTTP server component }
ClientCnx : TMyHttpConnection; { Client connection issuing command }
var Flags : THttpGetFlag); { Tells what HTTP server has to do next }
var
Location : String;
begin
Location := ClientCnx.Params;
if Location = '' then
Location := Trim(RedirUrlEdit.text);
ClientCnx.AnswerString(Flags,
'302 Moved', { Tell the browser about relocation }
'', { Default Content-Type: text/html }
'Location: ' + Location + #13#10, { Specify new location }
'<HTML>' +
'<HEAD>' +
'<TITLE>ICS WebServer Demo - Redir</TITLE>' +
'</HEAD>' + #13#10 +
'<BODY>' +
'You should be redirected automatically !<BR>' + #13#10 +
'<A HREF="' + Location + '">Click Here</A><BR>' + #13#10 +
'</BODY>' +
'</HTML>');
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ This procedure is use to generate /time.html document }
procedure TWebServForm.CreateVirtualDocument_Time(
Sender : TObject; { HTTP server component }
ClientCnx : TMyHttpConnection; { Client connection issuing command }
var Flags : THttpGetFlag); { Tells what HTTP server has to do next }
begin
ClientCnx.AnswerString(Flags,
'', { Default Status '200 OK' }
'', { Default Content-Type: text/html }
'Pragma: no-cache' + #13#10 + { No client caching please }
'Expires: -1' + #13#10, { I said: no caching ! }
'<HTML>' +
'<HEAD>' +
'<TITLE>ICS WebServer Demo</TITLE>' +
'</HEAD>' + #13#10 +
'<BODY>' +
'<H2>Time at server side:</H2>' + #13#10 +
'<P>' + DateTimeToStr(Now) +'</P>' + #13#10 +
'<A HREF="/demo.html">Demo menu</A>' + #13#10 +
'</BODY>' +
'</HTML>');
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ Produce a reply with a huge header line. Used to check client behaviour. }
procedure TWebServForm.CreateVirtualDocument_HeaderBug(
Sender : TObject;
ClientCnx : TMyHttpConnection;
var Flags : THttpGetFlag);
begin
ClientCnx.AnswerString(Flags,
'', { Default Status '200 OK' }
'', { Default Content-Type: text/html }
{$IFDEF DELPHI2_UP}
{ Sorry but Delphi doesn't support long strings }
'X-LongHeader: ' + DupeString('Hello ', 1500) + #13#10 +
{$ENDIF}
'Pragma: no-cache' + #13#10 + { No client caching please }
'Expires: -1' + #13#10, { I said: no caching ! }
'<HTML>' +
'<HEAD>' +
'<TITLE>ICS WebServer Demo</TITLE>' +
'</HEAD>' + #13#10 +
'<BODY>' +
'Congratulations !' + #13#10 +
'</BODY>' +
'</HTML>');
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TWebServForm.CreateVirtualDocument_MyIP(
Sender : TObject;
ClientCnx : TMyHttpConnection;
var Flags : THttpGetFlag);
begin
ClientCnx.AnswerString(Flags,
'', { Default Status '200 OK' }
'', { Default Content-Type: text/html }
'Pragma: no-cache' + #13#10 + { No client caching please }
'Expires: -1' + #13#10, { I said: no caching ! }
'<HTML>' +
'<HEAD>' +
'<TITLE>ICS WebServer Demo</TITLE>' +
'</HEAD>' + #13#10 +
'<BODY>' +
'Your IP is: ' +
ClientCnx.PeerAddr + #13#10 +
'</BODY>' +
'</HTML>');
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ FormDataGetRow is called by AnswerPage when in find <#TABLE_ROWS> tag. }
{ We have to read a line from the data file and call TagData.Add to seed }
{ the HTML table with row data. }
procedure TWebServForm.FormDataGetRow(
Sender : TObject;
const TableName : String;
Row : Integer;
TagData : TStringIndex;
var More : Boolean;
UserData : TObject);
var
Buf : String;
ClientCnx : TMyHttpConnection;
begin
{ Check if the table name. There could be several tables or table }
{ embedded in another table in the template file }
if TableName <> 'DATAFILE' then
Exit;
{ Get reference to the connection. It has our data private. }
ClientCnx := Sender as TMyHttpConnection;
{ Check if we have read all the data file }
More := not Eof(ClientCnx.FDataFile);
if not More then
Exit;
{ Read a line form data file }
ReadLn(ClientCnx.FDataFile, Buf);
{ Extract column data from the datafile line }
TagData.Add('DATE', Copy(Buf, 1, 8));
TagData.Add('TIME', Copy(Buf, 10, 6));
TagData.Add('DATA', TextToHtmlText(Copy(Buf, 17, High(Integer))));
{ Alternate style for even or odd table lines }
if (Row and 1) <> 0 then
TagData.Add('STYLE', 'stEven')
else
TagData.Add('STYLE', 'stOdd');
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ Build the dynamic page to show datafile. This page is based on a template }
{ with a table. }
procedure TWebServForm.CreateVirtualDocument_ViewFormData(
Sender : TObject; { HTTP server component }
ClientCnx : TMyHttpConnection; { Client connection issuing command }
var Flags : THttpGetFlag); { Tells what HTTP server has to do next }
begin
{ Open data file }
AssignFile(ClientCnx.FDataFile, 'FormHandler.txt');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -