PHP + Curl: закрытие соединения во время аутентификации переговоров (HTTP 1.0?)

У меня проблема между CURL и PHP. Я попытался подключиться к серверу Exchange 2010 через EWS. Соединение с сервером отлично работает в командной строке с использованием CURL, но не с расширением PHP Curl.

Я прикрепил изображение с отладочной информацией. Слева вы видите вывод командной строки, справа подробный вывод PHP. Когда расширение PHP Curl выдает ошибку «Закрытие соединения во время аутентификации согласования (HTTP 1.0?)», командная строка продолжает третий HTTP-запрос с результатом HTTP/1.1 302 Found:

информация журнала

Некоторая дополнительная информация:

  • Я использую эту библиотеку для CURL-запросов: https://github.com/jamesiarmes/php-ntlm/blob/master/src/SoapClient.php
  • у нас есть около 80 серверов обмена, где нет проблем. Только с этим сервером есть проблема. Наш клиент рассказал о программном обеспечении под названием «Sophos», используемом в качестве прокси для веб-сервера.
  • CURLOPT_HTTPAUTH — это CURLAUTH_NTLM
  • Версия PHP 7.3.1/7.3.9 также протестирована
  • Информация cURL 7.63.0 / 7.52.1 также протестирована

Кто-нибудь знает, почему расширение PHP Curl закрывает соединение перед третьим запросом? Является ли это ошибкой расширения, могу ли я использовать константу PHP Curl, чтобы избежать этого, или есть другое решение?


person Tobias Bambullis    schedule 08.10.2019    source источник
comment
Не могли бы вы предоставить команду cURL, которая выполняется? Также вывод запроса с одного из хостов работает?   -  person EternalHour    schedule 10.10.2019


Ответы (2)


Я столкнулся с такой проблемой, используя SoapClient и Microsoft Exchange 2010 Server, и хитрость заключалась в изменении параметра массива заголовков 'Ожидать: 100-продолжить' на 'Ожидать: 200-ok'

protected function buildHeaders($action)
{
    return array(
        'Method: POST',
        'Connection: Keep-Alive',
        'User-Agent: PHP-SOAP-CURL',
        'Content-Type: text/xml; charset=utf-8',
        "SOAPAction: \"$action\"",
        'Expect: 200-ok',
    );
}

Код состояния 100 (продолжение) указывает на то, что начальная часть запроса получена и еще не отклонена сервером.

Код состояния 200 (ОК) указывает на то, что запрос выполнен успешно. Значение успеха зависит от метода HTTP.

Вы также можете проверить это по кодам состояния HTTP.

Я хочу, чтобы это могло помочь

person Thaier Alkhateeb    schedule 11.10.2019
comment
получилось, вы правы! Я, наконец, полностью удалил строку Expect, и теперь office365.com также работает. Большое спасибо!! - person Tobias Bambullis; 11.10.2019

Соединение закрыто, потому что так говорит сервер. Посмотрите на свой скриншот, на одну строку выше, где «В чем проблема?» точки.

HTTP/1.1 401 Unauthorized
[...]
Connection: close
Content-Type: application/x-asmx

И, вероятно, после этого сервер закрывает соединение.

Так что это не действие, а результат. Сообщение выдается в Curl_http_readwrite_headers:

#if defined(USE_NTLM)
      if(conn->bits.close &&
         (((data->req.httpcode == 401) &&
           (conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
          ((data->req.httpcode == 407) &&
           (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
        infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
        data->state.authproblem = TRUE;
      }
#endif
#if defined(USE_SPNEGO)
      if(conn->bits.close &&
        (((data->req.httpcode == 401) &&
          (conn->http_negotiate_state == GSS_AUTHRECV)) ||
         ((data->req.httpcode == 407) &&
          (conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
        infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
        data->state.authproblem = TRUE;
      }

Предположительно из первого блока (NTLM), но это два вхождения, и они все равно рядом друг с другом.

Забавный факт: та же самая функция, только намного позже проверяет наличие заголовка Connection: close, поэтому установленный мистический флаг conn->bits.close, вероятно, означает, что сервер уже разорвал соединение и оно было обнаружено на уровне сокета.

Дополнительное замечание: две стороны сравнения показывают очень разные взаимодействия. Слева практически пустой GET запрос (предоставлены заголовки Host, Authorization, User-Agent и Accept), а справа - намного более сложный POST запрос (те же заголовки плюс Method, SOAPAction, пустой контент с Expect для продолжение).

person tevemadar    schedule 10.10.2019
comment
спасибо за Ваш ответ. Вы правы, сравнение не равное. Таким образом, вы не могли понять, что проблема была в разделе заголовка Soap Client (см. Ответ Тайера). - person Tobias Bambullis; 11.10.2019