От 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-сервер.

Другие вопросы по тегам