Hi there.
I was wondering why I was not able to get cURL use Digest Authentification. The
reason is the following:
In ext/curl/interface.c, there is (lines 834-836) :
#ifdef CURLOPT_HTTPAUTH
/* only in curl 7.10.6 */
case CURLOPT_HTTPAUTH:
#endif
However, CURLOPT_HTTAUTH can't be tested that way since it's inside a enum. See
curl.h, line 314 (in curl.h from curl-7.11.0 for instance):
typedef enum {
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
... etc .. until you have :
/* Set this to a bitmask value to enable the particular authentications
methods you like. Use this in combination with CURLOPT_USERPWD.
Note that setting multiple bits may cause extra network round-trips. */
CINIT(HTTPAUTH, LONG, 107),
So, if ever one wants to keep conditional compilation for this option, one
can use this ugly mess instead :-) :
#define CURL_HAS_HTTPAUTH
#if LIBCURL_VERSION_MAJOR <= 7
#if LIBCURL_VERSION_MAJOR < 7
#undef CURL_HAS_HTTPAUTH
#else
#if LIBCURL_VERSION_MINOR < 10
#undef CURL_HAS_HTTPAUTH
#else
#if LIBCURL_VERSION_MINOR == 10
#if LIBCURL_VERSION_PATCH < 6
#undef CURL_HAS_HTTPAUTH
#endif // LIBCURL_VERSION_PATCH < 6
#endif // LIBCURL_VERSION_MINOR == 10
#endif // LIBCURL_VERSION_MINOR < 10
#endif // LIBCURL_VERSION_MAJOR < 7
#endif // LIBCURL_VERSION_MAJOR <= 7
and then use, in interface.c, lines 834-836:
#ifdef CURLOPT_HAS_HTTPAUTH /* only in curl 7.10.6 */
case CURLOPT_HTTPAUTH:
#endif
However won't it be simpler to suppose that, with PHP5, cURL must be at least 7.11.0 and drop all that
tests?
Now, to end that matter, I would have spared hours if, still in interface.c, I would have found, starting
line 1089:
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option");
RETURN_FALSE;
Cheers,
Bernard
This is fixed in CVS. Thank you for letting us know about this.
See:
http://cvs.php.net/diff.php/php-src/ext/curl/interface.c?r1=1.30&r2=1.31&ty=u
--Jani
Hi there.
I was wondering why I was not able to get cURL use Digest Authentification. The
reason is the following:In ext/curl/interface.c, there is (lines 834-836) :
#ifdef
CURLOPT_HTTPAUTH
/* only in curl 7.10.6 */
case CURLOPT_HTTPAUTH:
#endifHowever, CURLOPT_HTTAUTH can't be tested that way since it's inside a enum. See
curl.h, line 314 (in curl.h from curl-7.11.0 for instance):
typedef enum {
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/... etc .. until you have :
/* Set this to a bitmask value to enable the particular authentications
methods you like. Use this in combination with CURLOPT_USERPWD.
Note that setting multiple bits may cause extra network round-trips. */
CINIT(HTTPAUTH, LONG, 107),So, if ever one wants to keep conditional compilation for this option, one
can use this ugly mess instead :-) :
#define CURL_HAS_HTTPAUTH
#if LIBCURL_VERSION_MAJOR <= 7
#if LIBCURL_VERSION_MAJOR < 7
#undef CURL_HAS_HTTPAUTH
#else
#if LIBCURL_VERSION_MINOR < 10
#undef CURL_HAS_HTTPAUTH
#else
#if LIBCURL_VERSION_MINOR == 10
#if LIBCURL_VERSION_PATCH < 6
#undef CURL_HAS_HTTPAUTH
#endif // LIBCURL_VERSION_PATCH < 6
#endif // LIBCURL_VERSION_MINOR == 10
#endif // LIBCURL_VERSION_MINOR < 10
#endif // LIBCURL_VERSION_MAJOR < 7
#endif // LIBCURL_VERSION_MAJOR <= 7and then use, in interface.c, lines 834-836:
#ifdef CURLOPT_HAS_HTTPAUTH /* only in curl 7.10.6 */
case CURLOPT_HTTPAUTH:
#endifHowever won't it be simpler to suppose that, with PHP5, cURL must be at least 7.11.0 and drop all that
tests?Now, to end that matter, I would have spared hours if, still in interface.c, I would have found, starting
line 1089:
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option");
RETURN_FALSE;Cheers,
Bernard
Hi Jani.
BTW Digest Auth still can't be used in cUrl because of a bug in
libcurl. I've reported the bug to the libcurl mailing list but this
mailing list is not working at the moment at sourceforge.net.
FYI the bug is the following:
Hi there.
I spent some time trying to figure out why such a program does not work:
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_HTTPAUTH,CURLAUTH_DIGEST);
curl_easy_setopt(curl, CURLOPT_USERPWD,"myusername:mypassword");
curl_easy_setopt(curl, CURLOPT_URL, "soap_server_url");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "soap_request");
res = curl_easy_perform(curl);
The problem is the following:
-
if
CURLAUTH_DIGEST
is used without CURLOPT_USERPWD, then a request
is made, but, of course, it fails because the user and password are unknown ;-) -
if
CURLAUTH_DIGEST
is used with CURLOPT_USERPWD, then the request
is broken: the body is empty, without the post data. So the server
does not even reply with the nounce field... -
I can have everything right if I force conn->user & conn->passwd in
http_digest.c, not using CURLOPT_USERPWD.
So there is something very strange going on when someone tries to set
user/passwd while using digest authentification.
I do not know libcurl enough to correctly locate the problem and offer
a nice fix, I'm afraid I could break something else.
I've just found that:
- In url.c, if I comment line 2009:
conn->bits.user_passwd = data->set.userpwd?1:0;
then I've everything okay.
OR:
-
In http.c, If I comment lines 212-213:
else if(conn->bits.user_passwd) Curl_http_auth_stage(data, 401);
then it's also okay.
I can test any fix on a server with digest authentification if needed,
however I can not provide credentials to someone else since the server
is not mine.
However it is very easy to test the problem with any URL, even one
that does not exist, since one can see that the request is really
broken when both options are activated.
Cheers,
Bernard