От Indy 9 до 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.
Может кто-нибудь здесь сказать мне, что правильный код 10 инди на основе вышеупомянутого кода 9 инди. Я пытался использовать это, но не работает вообще:
....
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])); )
1 ответ
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 этот тип кода не является надежным способом изменения заголовков HTTP, проходящих через TIdMappedPortTCP
, TIdMappedPortTCP
это прямой проход необработанных данных, он не имеет понятия протокола HTTP. Данные хранятся в NetData
является произвольным, он может содержать байты для любой части HTTP-сообщения (или нескольких сообщений), которые просто оказываются в сокете в данный конкретный момент. Таким образом, вы не можете полагаться на наличие действительных полных HTTP-сообщений в каждом NetData
,
Если вы собираетесь использовать TIdMappedPortTCP
таким образом, вам нужно поддерживать буфер всех данных, полученных от клиента, а затем анализировать этот буфер каждый раз, когда вы добавляете в него новые данные. Вам нужно знать, где заканчивается каждое HTTP-сообщение и начинается следующее HTTP-сообщение, а также где заканчиваются HTTP-заголовки и тело HTTP внутри каждого HTTP-сообщения. Только тогда вы можете безопасно вводить пользовательские заголовки HTTP в диалог. Это гораздо более продвинутая логика, чем то, что вы показали здесь.
С учетом сказанного, у Инди есть TIdHTTPProxyServer
компонент, вы должны использовать это вместо TIdMappedPortTCP
Например:
Indy 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;
Indy 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-сервер.