gpt4 book ai didi

德尔福 IdHTTPServer (Indy 10.6) : retrive some request/response info from TIdTCPConnection in OnWorkEnd event

转载 作者:行者123 更新时间:2023-12-01 16:12:10 25 4
gpt4 key购买 nike

当 TIdContext.Connection 触发 OnWorkEnd 事件时,可以从 TIdTCPConnection 检索一些信息(用于记录目的)吗?

我想要以下信息: - 用户ip地址(在Socket.Binding.PeerIP中找到我自己) - 浏览器/客户端用户代理 - 日期时间开始请求 - 请求的总大小 - 字节发送 - 发送文件的文件名

我的服务器非常简单,对每个请求,都使用文件流进行响应。

procedure TMyHttpServer.OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
AResponseInfo.ContentStream := TFileStream.Create('C:\server\file.exe', fmOpenRead or fmShareDenyNone);
AContext.Connection.OnWorkEnd := MyOnWorkEnd;
end;


procedure TMyHttpServer.MyOnWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
var
aConnection : TIdTCPConnection;
aIPAddress, aFileName, aDateStart, aByteSend, aFileSize, aUserAgent : string;
aDateEnd : TDateTime;
begin
aConnection := TIdTCPConnection(ASender);

aIPAddress := aConnection.Socket.Binding.PeerIP;

aFileName := ''; // Filename download
aDateStart := ''; // Date start download
aDateEnd := Now;
aByteSend := ''; // byte send
aFileSize := ''; // file size
aUserAgent := ''; // user agent

WriteLog(aFileName + ' ' + aDateStart +' '+aDateEnd +' etc.');

end;

最佳答案

无法在 OnWork... 事件中直接访问请求和响应信息。您必须手动传递信息。我建议:

  1. TFileStream 派生一个新类来存储所需的信息,然后在服务器响应后释放 ContentStream 时在该类的析构函数中处理该信息传输完成。

  2. TIdServerContext 派生一个新类,以保存指向 TIdHTTPRequestInfoTIdHTTPResponseInfo 对象的指针:

    type
    TMyContext = class(TIdServerContext)
    public
    Request: TIdHTTPRequestInfo;
    Response: TIdHTTPResponseInfo;
    end;

    然后,您可以在激活服务器之前将该​​类类型分配给服务器的 ContextClass 属性,并在 OnCommandGet 事件中对 AContext 参数进行类型转换到您的类类型,以便您可以分配其指针,并将 AContext 对象分配给 AContext.Connection.Tag 属性:

    MyHttpServer.ContextClass := TMyContext;

    ...

    procedure TMyHttpServer.OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    begin
    TMyContext(AContext).Request := ARequestInfo;
    TMyContext(AContext).Response := AResponseInfo;
    AContext.Connection.Tag := NativeInt(AContext);
    //...
    end;

    OnWork... 事件中,您可以对 Sender 参数进行类型转换以到达其 Tag,然后进行类型转换到您的自定义类以到达其存储的请求/响应指针:

    procedure TMyHttpServer.MyOnWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
    var
    aConnection : TIdTCPConnection;
    aContext: TMyContext;
    //...
    begin
    aConnection := TIdTCPConnection(ASender);
    aContext := TMyClass(aConnection.Tag);
    //...
    end;
  3. #2 的一个细微变化是操纵 OnWorkEnd 事件处理程序的 Self 指针来传递 Context 对象直接连接到处理程序,而不使用 Connection.Tag 属性:

    type
    TMyContext = class(TIdServerContext)
    public
    Request: TIdHTTPRequestInfo;
    Response: TIdHTTPResponseInfo;
    MyServer: TMyHttpServer;
    end;

    ...

    procedure TMyHttpServer.OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    var
    Handler: TWorkEndEvent;
    begin
    TMyContext(AContext).Request := ARequestInfo;
    TMyContext(AContext).Response := AResponseInfo;
    TMyContext(AContext).MyServer := Self;
    Handler := MyOnWorkEnd;
    TMethod(Handler).Data := TMyContext(AContext);
    AContext.Connection.OnWorkEnd := Handler
    //...
    end;

    procedure TMyHttpServer.MyOnWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
    var
    aConnection : TIdTCPConnection;
    aContext: TMyContext;
    aServer: TMyHttpServer;
    //...
    begin
    aConnection := TIdTCPConnection(ASender);
    aContext := TMyClass(Self);
    aServer := aContext. MyServer;
    //...
    end;

关于德尔福 IdHTTPServer (Indy 10.6) : retrive some request/response info from TIdTCPConnection in OnWorkEnd event,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35196637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com