TIdHTTPServer + TIdServerIOHandlerSSLOpenSSL = нестабильная работа - PullRequest
0 голосов
/ 19 марта 2020

Я поместил TIdHTTPServer и TIdServerIOHandlerSSLOpenSSL в форму, установил путь к файлу сертификата для TIdServerIOHandlerSSLOpenSSL
В событии TIdHTTServer onCommandGet я отправляю ответ следующим образом:

* 100 * Я пытаюсь * открыть 100 * * 1003 адрес "127.0.0.1:433" в Inte rnet Explorer, иногда он открывает страницу, иногда говорит "невозможно отобразить страницу"
В этом нет никакого шаблона или логики c, я просто refre sh страница в проводнике 10 раз, и, например, при попытках 1,2,4,6,7,9,10 открылась страница, а остальные закончились ошибкой
Дупм ответа в последнем ответе. txt всегда корректен и всегда одинаков
При возникновении ошибки IE в сетевой консоли показывает, что он получил 0 байт

Есть идеи, как это исправить?
Ошибки Indy?

Обновление
Решено, проблема была не в коде, а в приложении анализатора, используемом для управления трафиком c (

1 Ответ

0 голосов
/ 19 марта 2020

То, как вы реализовали событие OnCommandGet, не является правильным способом отправки ответа клиенту.

Во-первых, вы вообще не должны использовать TIdIOHandler.WriteDirect() напрямую. Но если вы это сделаете, вы должны передать ему TIdBytes, ie динамический c массив байтов, а не строку.

Но, что еще более важно, для отправки HTTP-ответа клиенту, правильный способ состоит в том, чтобы заполнить параметр AResponseInfo и позволить TIdHTTPServer обрабатывать фактическую запись в сокет для вас.

Например:

procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  ...
  AResponseInfo.ResponseCode := 200;
  AResponseInfo.ContentText := RespData;
  // set other AResponseInfo properties as needed, like ContentType, etc...
end;

При выходе из обработчика OnCommandGet TIdHTTPServer отправит содержимое AResponseInfo клиенту, если оно еще не было отправлено.

Кроме того, вы используете WriteFile() неправильно, если вы используете Delphi 2009+ и FullResponce - обычная строка (ie, UnicodeString). Вместо этого он должен выглядеть следующим образом:

WriteFile(FileHandle, PChar(FullResponce)^, Length(FullResponce) * SizeOf(Char), LongWord(ReadRes), nil);

Попробуйте вместо этого использовать TFile.WriteAllText():

TFile.WriteAllText('c:\lastresp.txt', FullResponce);

Тем не менее, есть еще один способ добавить запись в ваш * Код 1034 * вместо этого назначает компонент TIdLogFile свойству AContext.Connection.IOHandler.Intercept и позволяет самой Indy регистрировать именно то, что она отправляет клиенту, например:

uses
  ..., IdLogFile;

procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  Log: TIdLogFile;
begin
  Log := TIdLogFile.Create(nil);
  try
    Log.Filename := 'c:\lastresp.txt';
    Log.LogTime := False;
    Log.ReplaceCRLF := False;
    Log.Active := True;

    AContext.Connection.IOHandler.Intercept := Log;

    ...

    AResponseInfo.ResponseCode := 200;
    AResponseInfo.ContentText := RespData;
    // set other AResponse properties as needed, like ContentType, etc...
    ...

    AResponse.WriteContent;
  finally
    Log.Free;
  end;
end;
...