我创建了一个VCL应用程序,我需要创建一个在我的网络中运行的HTTP服务器.我创建了您可以在下面看到的代码:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
a: TStringList;
count, logN: integer;
begin
if ARequestInfo.Document = '/' then
begin
AResponseInfo.ResponseNo := 200;
AResponseInfo.ContentText := IndexMemo.Lines.Text;
Memo1.Lines.Add(' Client: ' + ARequestInfo.RemoteIP);
end
else
begin
AResponseInfo.ResponseNo := 200;
AResponseInfo.ContentText := '<html><body><b>404 NOT FOUND</b></body></html>';
end;
end;
Run Code Online (Sandbox Code Playgroud)
现在我只有一个测试案例,if ARequestInfo.Document = '/' then但后来我需要很多.我找到了这个解决方案:
ContextText我不认为这是非常有效的,因为我必须在我的表单中删除20个TMemo并且HTML将难以维护.我以为我可以加载html页面Deployment manager.
在Delphi项目的同一个文件夹中,我创建了一个名为的文件夹pages,它将包含html文件.我不确定如何使用indy HTTP服务器加载html页面,所以我的问题是:
注意:我想有一个exe(这是http服务器)而不是一个带有exe + html文件的文件夹.我发现的解决方案非常有效,因为我使用了很多TMemo来存储代码,但这并不容易维护.
首先,您显示的代码不是线程安全的. TIdHTTPServer是一个多线程组件,OnCommand...事件在工作线程的上下文中触发.您必须与主UI线程同步才能安全地访问UI控件,例如:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
s: string;
begin
if ARequestInfo.Document = '/' then
begin
TThread.Synchronize(nil,
procedure
begin
s := IndexMemo.Lines.Text;
Memo1.Lines.Add(' Client: ' + ARequestInfo.RemoteIP);
end
);
AResponseInfo.ResponseNo := 200;
AResponseInfo.ContentText := s;
AResponseInfo.ContentType := 'text/plain';
end
else
begin
AResponseInfo.ResponseNo := 404;
AResponseInfo.ContentText := '<html><body><b>404 NOT FOUND</b></body></html>';
AResponseInfo.ContentType := 'text/html';
end;
end;
Run Code Online (Sandbox Code Playgroud)
我是否必须将html页面存储在文件夹中的某个位置,然后使用indy加载它们?
我可以加载部署页面中包含的带有indy的html页面吗?
如果要从本地文件系统提供文件,则必须将ARequestInfo.Document属性值转换为本地文件路径,然后您可以:
将请求的文件加载到a TFileStream并将其分配给AResponseInfo.ContentStream属性:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
str, filename: string;
begin
str := ' Client: ' + ARequestInfo.RemoteIP + ' requesting: ' + ARequestInfo.Document;
TThread.Queue(nil,
procedure
begin
Memo1.Lines.Add(str);
end
);
if TextStartsWith(ARequestInfo.Document, '/') then
begin
filename := Copy(ARequestInfo.Document, 2, MaxInt);
if filename = '' then
filename := 'index.txt';
// determine local path to requested file
// (ProcessPath() is declared in the IdGlobalProtocols unit)...
filename := ProcessPath(YourDeploymentFolder, filename);
if FileExists(filename) then
begin
AResponseInfo.ResponseNo := 200;
AResponseInfo.ContentStream := TFileStream.Create(filename, fmOpenRead or fmShareDenyWrite);
AResponseInfo.ContentType := IdHTTPServer1.MIMETable.GetFileMIMEType(filename);
Exit;
end;
end;
AResponseInfo.ResponseNo := 404;
AResponseInfo.ContentText := '<html><body><b>404 NOT FOUND</b></body></html>';
AResponseInfo.ContentType := 'text/html';
end;
Run Code Online (Sandbox Code Playgroud)将文件路径传递给TIdHTTPResponseInfo.(Smart)ServeFile()方法,让它为您处理文件:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
str, filename: string;
begin
str := ' Client: ' + ARequestInfo.RemoteIP + ' requesting: ' + ARequestInfo.Document;
TThread.Queue(nil,
procedure
begin
Memo1.Lines.Add(str);
end
);
if TextStartsWith(ARequestInfo.Document, '/') then
begin
filename := Copy(ARequestInfo.Document, 2, MaxInt);
if filename = '' then
filename := 'index.txt';
// determine local path to requested file...
filename := ProcessPath(YourDeploymentFolder, filename);
AResponseInfo.SmartServeFile(AContext, ARequestInfo, filename);
Exit;
end;
AResponseInfo.ResponseNo := 404;
AResponseInfo.ContentText := '<html><body><b>404 NOT FOUND</b></body></html>';
AResponseInfo.ContentType := 'text/html';
end;
Run Code Online (Sandbox Code Playgroud)我想有一个exe(这是http服务器)而不是一个exe + html文件的文件夹.
在这种情况下,在编译时将HTML文件保存到EXE的资源中(使用.rc文件或IDE的资源和图像对话框.有关详细信息,请参阅资源文件支持),然后将其ARequestInfo.Document转换为资源ID /名称,您可以加载以TResourceStream用作AResponseInfo.ContentStream对象:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
str, resID: string;
strm: TResourceStream;
begin
str := ' Client: ' + ARequestInfo.RemoteIP + ' requesting: ' + ARequestInfo.Document;
TThread.Queue(nil,
procedure
begin
Memo1.Lines.Add(str);
end
);
if TextStartsWith(ARequestInfo.Document, '/') then
begin
// determine resource ID for requested file
// (you have to write this yourself)...
resID := TranslateIntoResourceID(Copy(ARequestInfo.Document, 2, MaxInt));
try
strm := TResourceStream.Create(HInstance, resID, RT_RCDATA);
except
on E: EResNotFound do
strm := nil;
end;
if strm <> nil then
begin
AResponseInfo.ResponseNo := 200;
AResponseInfo.ContentStream := strm;
AResponseInfo.ContentType := 'text/html';
Exit;
end;
end;
AResponseInfo.ResponseNo := 404;
AResponseInfo.ContentText := '<html><body><b>404 NOT FOUND</b></body></html>';
AResponseInfo.ContentType := 'text/html';
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1697 次 |
| 最近记录: |