NetData
是 的属性TIdMappedPortContext
,例如:
TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(AddHeader(BytesToString(TIdMappedPortContext(AContext).NetData), 'Connection: Keep-Alive'));
TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(StringReplace(BytesToString(TIdMappedPortContext(AContext).NetData), #13#10#13#10, #13#10 + 'Connection: Keep-Alive' + #13#10 + #13#10, [rfReplaceAll]));
在您展示的代码中,您使用netbyte()
andnetstring()
确实使您看起来像是在尝试解释NetData
现在是字节数组而不是String
. 但无论哪种方式,您通常都不能很好地处理这种情况。在 Indy 9 和 10 中,这种类型的代码都不是修改通过TIdMappedPortTCP
. TIdMappedPortTCP
是原始数据的直通,没有HTTP协议的概念。存储在其中的数据NetData
是任意的,它可能包含 HTTP 消息(或多条消息)的任何部分的字节,这些字节恰好在特定时刻位于套接字上。因此,您不能依赖每个NetData
.
如果要以TIdMappedPortTCP
这种方式使用,则需要维护从客户端接收到的所有数据的缓冲区,然后在每次向其中添加新数据时解析该缓冲区。您需要知道每条 HTTP 消息的结束位置和下一条 HTTP 消息的开始位置,以及每条 HTTP 消息中 HTTP 标头的结束位置和 HTTP 正文的开始位置。只有这样,您才能安全地将自定义 HTTP 标头注入到对话中。这比您在此处显示的逻辑要高级得多。
话虽如此,Indy 有一个TIdHTTPProxyServer
组件,您应该使用它而不是TIdMappedPortTCP
,例如:
印地9:
// OnHTTPHeaders event handler...
procedure TForm1.IdHTTPProxyServer1HTTPHeaders(ASender: TIdHTTPProxyServerThread; const ASource: TIdHTTPSource; const ADocument: string; AHeaders: TIdHeaderList);
begin
if ASource = httpBrowser then
AHeaders.Values['Connection'] := 'Keep-Alive';
end;
印地 10:
// OnHTTPBeforeCommand event handler...
procedure TForm1.IdHTTPProxyServer1HTTPBeforeCommand(AContext: TIdHTTPProxyServerContext);
begin
if AContext.TransferSource = tsClient then
AContext.Headers.Values['Connection'] := 'Keep-Alive';
end;
然后,您可以将 HTTP 客户端配置为TIdHTTPProxyServer
作为 HTTP 代理连接,而不是TIdMappedPortTCP
像实际的 HTTP 服务器一样连接。