从印地 9 到印地 10
From Indy 9 to Indy 10
我需要你的帮助:
一个。印地 9.
AThread.OutboundClient.Write(AddHeader(athread.netdata,'Connection: Keep-Alive'));
AThread.OutboundClient.Write(stringreplace(athread.netdata,#13#10#13#10,#13#10 + 'Connection: Keep-Alive' + #13#10 + #13#10,[rfreplaceall]));
乙。印地 10。
这里有人可以告诉我基于上述 Indy 9 代码的正确 Indy 10 代码是什么吗?我尝试使用它,但根本不起作用:
....
var Netdata:String;
....
TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(AddHeader(netbyte(netdata,'Connection: Keep-Alive')));
TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(netbyte(netdata,StringReplace(netstring(AContext,#13#10#13#10,#13#10 + 'Connection: Keep-Alive' + #13#10 + #13#10,[rfreplaceall])); )
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()
和 netstring()
的使用确实使您看起来像是在试图解释 NetData
现在是一个字节数组这一事实的 String
。但无论哪种方式,你一般都不能很好地处理这种情况。在 Indy 9 和 10 中,这种类型的代码都不是修改通过 TIdMappedPortTCP
的 HTTP headers 的可靠方法。 TIdMappedPortTCP
是直接的pass-through原始数据,没有HTTP协议的概念。 NetData
中存储的数据是任意的,它可以包含 HTTP 消息(或多条消息)的任何部分的字节,这些字节恰好在特定时刻位于套接字上。因此,您不能依赖每个 NetData
.
中存在有效的完整 HTTP 消息
如果您打算以这种方式使用 TIdMappedPortTCP
,您需要维护从客户端接收到的所有数据的缓冲区,然后在每次向其中添加新数据时解析该缓冲区。您需要知道每个 HTTP 消息的结束位置和下一个 HTTP 消息的开始位置,以及每个 HTTP 消息中的 HTTP headers 结束位置和 HTTP body 开始位置。只有这样,您才能安全地将自定义 HTTP headers 注入对话。这是比你在这里展示的更高级的逻辑。
话虽如此,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 服务器一样。
我需要你的帮助:
一个。印地 9.
AThread.OutboundClient.Write(AddHeader(athread.netdata,'Connection: Keep-Alive'));
AThread.OutboundClient.Write(stringreplace(athread.netdata,#13#10#13#10,#13#10 + 'Connection: Keep-Alive' + #13#10 + #13#10,[rfreplaceall]));
乙。印地 10。
这里有人可以告诉我基于上述 Indy 9 代码的正确 Indy 10 代码是什么吗?我尝试使用它,但根本不起作用:
....
var Netdata:String;
....
TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(AddHeader(netbyte(netdata,'Connection: Keep-Alive')));
TIdMappedPortContext(AContext).OutboundClient.IOHandler.Write(netbyte(netdata,StringReplace(netstring(AContext,#13#10#13#10,#13#10 + 'Connection: Keep-Alive' + #13#10 + #13#10,[rfreplaceall])); )
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()
和 netstring()
的使用确实使您看起来像是在试图解释 NetData
现在是一个字节数组这一事实的 String
。但无论哪种方式,你一般都不能很好地处理这种情况。在 Indy 9 和 10 中,这种类型的代码都不是修改通过 TIdMappedPortTCP
的 HTTP headers 的可靠方法。 TIdMappedPortTCP
是直接的pass-through原始数据,没有HTTP协议的概念。 NetData
中存储的数据是任意的,它可以包含 HTTP 消息(或多条消息)的任何部分的字节,这些字节恰好在特定时刻位于套接字上。因此,您不能依赖每个 NetData
.
如果您打算以这种方式使用 TIdMappedPortTCP
,您需要维护从客户端接收到的所有数据的缓冲区,然后在每次向其中添加新数据时解析该缓冲区。您需要知道每个 HTTP 消息的结束位置和下一个 HTTP 消息的开始位置,以及每个 HTTP 消息中的 HTTP headers 结束位置和 HTTP body 开始位置。只有这样,您才能安全地将自定义 HTTP headers 注入对话。这是比你在这里展示的更高级的逻辑。
话虽如此,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 服务器一样。