Как исправить получение HTTP-кода состояния 0 с компонентом TWSocket с использованием Delphi 6? - PullRequest
1 голос
/ 01 января 2012

У меня есть приложение, написанное на 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.Это событие вызывается непосредственно перед отправкой веб-запроса и предназначено специально для этой цели (чтобы вы могли изменить заголовки запроса).Это короткое замыкание требует от компонента автоматического входа в систему, так что это обходной путь, но не прямое решение проблемы.Если кто-нибудь знает прямое решение, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...