2012-10-23 26 views
5

我发现了一个“奇怪的”PHP CURL行为,是送我疯了。基本上我正在做的是使用curl进行摘要验证呼叫。这里是我的代码的摘录:php curl与摘要返回两个响应

curl_setopt($this->c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); 
curl_setopt($this->c, CURLOPT_USERPWD, $username . ":" . $password); 

它工作正常,并且服务器实际上是“YES,您所提供的权资格证书”之类的消息回来了。唯一的麻烦是,原始http响应有点奇怪,因为它实际上包含2个响应而不是1个响应。下面是curl_exec($这个 - > C)吐出:

HTTP/1.0 401 Unauthorized 
Date: Tue, 23 Oct 2012 08:41:18 GMT 
Server: Apache/2.2.20 (Ubuntu) 
X-Powered-By: PHP/5.3.6-13ubuntu3.9 
WWW-Authenticate: Digest realm="dynamikrest-testing",qop="auth",nonce="5086582e95104",opaque="4b24e95490812b28b3bf139f9fbc9a66" 
Vary: Accept-Encoding 
Content-Length: 9 
Connection: close 
Content-Type: text/html 

HTTP/1.1 200 OK 
Date: Tue, 23 Oct 2012 08:41:18 GMT 
Server: Apache/2.2.20 (Ubuntu) 
X-Powered-By: PHP/5.3.6-13ubuntu3.9 
Vary: Accept-Encoding 
Content-Length: 9 
Connection: close 
Content-Type: text/html 

"success" 

我不明白为什么它包括从服务器(它申明它需要身份验证的)的第一反应。

任何人都可以提出这个问题的一些亮点?我如何避免回复累计?

干杯

+0

输出我有完全*相同的问题项使用你的PHP。这个评论没有增加任何决议,但我想让人们知道这不是一个完全孤立的问题。 – Hezad

+0

我终于用PHP的exec()函数封装了命令行curl调用。它远非理想,但它适用于原型: exec('curl --digest -u the_login:the_password the_url',$ params); 仍在搜索并等待答案。 – Hezad

+0

我刚刚用wireshark和类似的设置进行了测试,看起来像使用摘要认证时的卷曲触发2个请求,而第一个请求没有任何验证。 现在的问题是,为什么curl命令行忽略这个响应,并且php_curl附加了它。 – gries

回答

2

它看起来像卷曲具有相同的行为,如果你使用的标题-I选项:

curl -I --digest -u root:somepassword http://localhost/digest-test/ 

回报:

HTTP/1.1 401 Authorization Required 
Date: Fri, 31 May 2013 13:48:35 GMT 
Server: Apache/2.2.22 (Ubuntu) 
WWW-Authenticate: Digest realm="Test Page", nonce="9RUL3wPeBAA=52ef6531dcdd1de61f239ed6dd234a3288d81701", algorithm=MD5, domain="/digest-test/ http://localhost", qop="auth" 
Vary: Accept-Encoding 
Content-Type: text/html; charset=iso-8859-1 

HTTP/1.1 200 OK 
Date: Fri, 31 May 2013 13:48:35 GMT 
Server: Apache/2.2.22 (Ubuntu) 
Authentication-Info: rspauth="4f5f8237e9760f777255f6618c21df4c", cnonce="MTQ3NDk1", nc=00000001, qop=auth 
Vary: Accept-Encoding 
Content-Type: text/html;charset=UTF-8 
X-Pad: avoid browser bug 

只得到第二集你可以试试这个(不是非常优化的解决方案):

<?php 

$ch = curl_init(); 
     // set url 
curl_setopt($ch, CURLOPT_URL, "http://localhost/digest-test/"); 
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); 
curl_setopt($ch, CURLOPT_USERPWD, "root:test"); 


// first authentication with a head request 
curl_setopt($ch, CURLOPT_NOBODY, 1); 
curl_exec($ch);   

// the get the real output 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_HTTPGET, 1); 
$output = curl_exec($ch); 
echo $output; 
0

我遇到了同样的问题,我认为这是PHP针对libcurl的一个古老版本(我的情况是7.11.0,现在已近10年)编译而引起的。在具有更新版本libcurl(7.29.0)的另一台机器上,相同的代码很好,我的主机在重新编译它们的PHP以使用它们可用的最新版本(7.30.0)后结束了我的问题。

此修补程序是由a thread on the curl-library mailing list from 2008建议的,其中用户发现了受影响的版本7.10.6而不是7.12.1的问题。我搜索了libcurl changelog around 7.12.0,但未能找到任何有关解决此问题的明确条目,但它可能包含在“常规HTTP身份验证改进”中。不过,我现在非常有信心,旧的libcurl是个问题。

可检查的libcurl版本从“卷曲信息”中的phpinfo();