У меня есть приложение, написанное на Delphi 6, которое использует компонент THttpCli, клиент, который действует как HTTP-клиент и использует ICS TWSocket для управления запросом.У меня странная проблема с его использованием, которая, кажется, связана с проблемой синхронизации.Я включил соответствующий блок кода из компонента ниже, код, в котором после выполнения запроса веб-документа (запрос HTTP POST) базовый элемент управления TWSocket зацикливается во время ожидания ответа от сервера.
Если я позволю этому коду работать непрерывно, я всегда получаю код состояния HTTP 0, возвращаемый операцией с пустым документом результата.Однако, если я перехожу через цикл ожидания, то после 3 итераций я всегда получаю успешный ответ.Следующее - просто спекуляция с моей стороны, но похоже, что код слишком быстро реагирует на входящий ответ от веб-сервера и делает преждевременное суждение относительно того, когда он действительно получил ответ.Следовательно, неправильное суждение, которое не произойдет, если я пошагово выполню цикл, тем самым введя период ожидания между проверками сокета уровня O / S с помощью кода TWSocket.
Веб-сервер, с которым я взаимодействую, являетсяфактически устройство, подключенное к WiFi, на моем локальном маршрутизаторе, другими словами, сетевой узел.Мне интересно, возможно, код TWSocket был написан так, что не ожидал быстрого ответа?Что противоречит этому, так это то, что я использовал этот самый компонент с другими одноранговыми программами, действующими в качестве веб-сервера на том же ПК, и у меня не возникло проблем.Возможно, веб-сервер в этом неудачном случае возвращает вещи неожиданным прогрессивным способом?Я попытался выполнить веб-запрос с помощью Chrome и других браузеров в моей системе, и они обрабатывают запрос без каких-либо проблем.
Если у кого-то есть какие-либо идеи о том, что может быть основной причиной и как ее исправить,пожалуйста, дай мне знать.Я пытаюсь избежать массового поиска ошибок на страницах кода, связанного с сокетами.
procedure THttpCli.DoRequestSync(Rq : THttpRequest);
var
DummyHandle : THandle;
begin
DoRequestAsync(Rq);
{$IFDEF DELPHI1}
{ Delphi 1 has no support for multi-threading }
while FState <> httpReady do
Application.ProcessMessages;
{$ELSE}
if FMultiThreaded then begin
while FState <> httpReady do begin
FCtrlSocket.ProcessMessages;
Sleep(0);
end;
end
else begin
while FState <> httpReady do begin
{ Do not use 100% CPU }
DummyHandle := INVALID_HANDLE_VALUE;
MsgWaitForMultipleObjects(0, DummyHandle, FALSE, 1000,
QS_ALLINPUT + QS_ALLEVENTS +
QS_KEY + QS_MOUSE);
{$IFNDEF NOFORMS}
Application.ProcessMessages;
if Application.Terminated then begin
Abort;
break;
end;
{$ELSE}
FCtrlSocket.ProcessMessages;
{$ENDIF}
end;
end;
{$ENDIF}
{* Jul 12, 2004
WARNING: The component now doesn't consider 401 status
as a fatal error (no exception is triggered). This required a
change in the application code if it was using the exception that
is no more triggered for status 401 and 407.
*}
{* if FStatusCode > 401 then Dec 14, 2004 *}
if (FStatusCode >= 400) and (FStatusCode <> 401) and (FStatusCode <> 407) then
raise EHttpEx
end;
UPDATE : Похоже, проблема связана с тем, что THttpCli пытается выполнить автоматический вход в систему.У THttpCli есть пара свойств «имя пользователя и пароль», которые вы можете использовать, если я не ошибаюсь, чтобы он автоматически пытался войти в систему, если сервер возвращает ошибку 401 (ошибка авторизации).Я обнаружил это, проследив через код компонента.Я обнаружил, что возвращался ответ 401, который был проглочен (не сообщен) компонентом.Похоже, что код состояния 0 происходит при попытке повторения с данными входа в систему и маскирует ответ 401.
Я обошел проблему, добавив необходимую строку аутентификации вручную в заголовки запроса, используя OnBeforeHeaderSend ()событие, запущенное THttpCli.Это событие вызывается непосредственно перед отправкой веб-запроса и предназначено специально для этой цели (чтобы вы могли изменить заголовки запроса).Это короткое замыкание требует от компонента автоматического входа в систему, так что это обходной путь, но не прямое решение проблемы.Если кто-нибудь знает прямое решение, пожалуйста, дайте мне знать.