PHP + Curl:协商验证时关闭连接(HTTP 1.0?)

PHP + Curl: Connection closure while negotiation auth (HTTP 1.0?)

我在 CURL 和 PHP 之间有问题。我尝试通过 EWS 连接到 Exchange 2010 服务器。与服务器的连接在使用 CURL 的命令行中工作正常,但不能使用 PHP Curl 扩展名。

我附上了一张带有调试信息的图片。在左侧您可以看到命令行输出,在右侧可以看到 PHP 详细输出。当 PHP Curl Extension 抛出错误 "Connection closure while negotiation auth (HTTP 1.0?)" 时,命令行继续执行第三个 HTTP 请求,结果为 HTTP/1.1 302 Found:

一些附加信息:

有人知道为什么 PHP Curl Extension 在第三次请求之前关闭连接吗?这是扩展的错误吗,我可以使用常量 PHP Curl 来避免这种情况,还是有其他解决方案?

连接已关闭,因为服务器这样说。查看您的屏幕截图,"What is the problem here?" 点上方的一行。

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) 开始的,但这是两次出现,而且它们彼此相邻。

有趣的事实:相同的函数仅 a lot later 检查是否存在 Connection: close header,因此设置神秘标志 conn->bits.close 可能意味着服务器已经断开连接并在 socket-level.

上检测到

旁注:比较的两侧显示出非常不同的相互作用。左边有一个几乎空的 GET 请求(提供了 HostAuthorizationUser-AgentAccept header),而在右侧有很多更复杂的 POST 请求(相同的 headers 加上 MethodSOAPAction、空内容 Expect 用于继续)。

我在使用 SoapClient 时遇到过这样的问题 和 Microsoft Exchange 2010 Server,诀窍是更改 header 数组选项 'Expect: 100-continue''Expect: 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(OK)状态码表示请求成功。成功的含义因 HTTP 方法而异。

你也可以看看这个HTTP status codes

我希望这能有所帮助