cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: re-using connection with authentication

From: Sigrid Thijs <sigrid.thijs_at_androme.com>
Date: Wed, 07 Mar 2007 12:14:25 +0100

Hello,

I think I found the cause of this behavior.
We use the multi interface, and basically the following happens:

// For the first request, we create an easy handle:
CURL * pcURL = curl_easy_init ();

// the necessary options are set ...

// this handle is added to the multi session:
curl_multi_add_handle ( pMultiCURL, pcURL );

// Perform transfer
int busyHandleCount = 0;
CURLMcode code = curl_multi_perform ( pMultiCURL, &busyHandleCount );

if ( code == CURLM_CALL_MULTI_PERFORM )
   code = curl_multi_perform ( pMultiCURL, &busyHandleCount ); // Again

// Process results
int messageCount = 0;
CURLMsg *pmessage = NULL;
        
while ( ( pmessage = curl_multi_info_read ( pMultiCURL, &messageCount ) ) )
{
   if ( pmessage->msg == CURLMSG_DONE )
   {
     curl_multi_remove_handle ( pMultiCURL, pcURL );
     curl_easy_cleanup (pcURL );
   }
}

When the second request on the same connection is issued, a new easy
handle is created and performed.
I have been debugging this and the problem is located in libcurl url.c
line 3603:
<code snip>

struct connectdata *old_conn = conn;

if(old_conn->proxy.rawalloc)
   free(old_conn->proxy.rawalloc);

/* free the SSL config struct from this connection struct as this was
    allocated in vain and is targeted for destruction */
Curl_free_ssl_config(&conn->ssl_config);

conn = conn_temp; /* use this connection from now on */

conn->data = old_conn->data; /* **HERE** */

</code snip>

When reusing the connection, conn_temp contains the data of the
connection (a.o. the digest and nonce). The new connection will point to
this connection, BUT the data of this connection is overwritten! As a
result the digest and nonce information are gone.
As a result of this, when the 2nd request is posted, conn->bits.authneg
is set to TRUE in http.c line 1680. Because of this no body will be
added to the request. I'm not sure why and where the Authorization
header still is added to the request, this means the digest information
is still available somewhere.

The reason that this worked before is because in version 7.12.1, url.c
did not contains this line (3603):
conn->data = old_conn->data

I would like to have some feedback on this. Is it not allowed to use
multiple easy handles when using the same connection? Are we doing
something wrong? Should the same easy handle be used when reusing a
connection? Is it a bug in libcurl?

kind regards,

Sigrid

Sigrid Thijs wrote:
> Hi,
>
> we recently upgraded our client to libcurl version 7.16.0 (win32) and
> have now a problem while re-using a connection.
>
> We use HTTP Digest authentication, the following options are set:
> CURLOPT_WRITEFUNCTION, CURLOPT_FILE, CURLOPT_PRIVATE, CURLOPT_HTTPHEADER
> CURLOPT_URL, CURLOPT_HTTPAUTH, CURLOPT_USERPWD, CURLOPT_POSTFIELDS,
> CURLOPT_POSTFIELDSIZE, CURLOPT_CAPATH
>
> The following happens:
> 1. The client posts an initial HTTP request (without body)
>
> POST /mmas/wbe_302S/wbe.soap.osp HTTP/1.1
> Host: 193.166.131.188:8080
> Accept: */*
> Content-Type: text/xml; charset=utf-8
> SOAPaction: ""
> Content-Length: 0
>
> 2. The client receives a 401 response from the server
>
> HTTP/1.1 401 Authorization Required
> Date: Mon, 05 Mar 2007 09:36:43 GMT
> Server: Apache/1.3.31 (Unix) PHP/5.0.5 OSP FEPHTTP (mod_in)/1.0.008
> mod_ssl/2.8.17 OpenSSL/0.9.7d
> Set-cookie: INSessionID=;path=/;expires=Sun, 04-Mar-07 09:36:43 GMT
> WWW-Authenticate: Digest realm="WBERealm",
> nonce="c23a7595e96edc3df13270fe73f3f456", algorithm=MD5, domain="/",
> qop="auth"
> Transfer-Encoding: chunked
> Content-Type: text/html; charset=iso-8859-1
>
> ...
>
> 3. The client re-posts the HTTP request containing authorization and body
>
> POST /mmas/wbe_302S/wbe.soap.osp HTTP/1.1
> Authorization: Digest username="username_at_mmas.com", realm="WBERealm",
> nonce="c23a7595e96edc3df13270fe73f3f456",
> uri="/mmas/wbe_302S/wbe.soap.osp", cnonce="MDA0NzE3", nc=00000001,
> qop="auth", response="121f382f188f4d88550318893011f841", algorithm="MD5"
> Host: 193.166.131.188:8080
> Accept: */*
> Content-Type: text/xml; charset=utf-8
> SOAPaction: ""
> Content-Length: 497
>
> ...
>
> 4. A 200 OK response is received
>
> HTTP/1.1 200 OK
> Date: Mon, 05 Mar 2007 09:36:44 GMT
> Server: Apache/1.3.31 (Unix) PHP/5.0.5 OSP FEPHTTP (mod_in)/1.0.008
> mod_ssl/2.8.17 OpenSSL/0.9.7d
> Set-cookie: Sequence=1;path=/
> Set-cookie: INSessionID=MTY3ODAxMDJAMjMz;path=/
> Content-Type:
> Content-Length: 1063
>
> ...
>
> 5. The client posts a new HTTP request (reuses the connection), with
> authorization but without body
>
> POST /mmas/wbe_302S/wbe.soap.osp HTTP/1.1
> Authorization: Digest username="username_at_mmas.com", realm="WBERealm",
> nonce="c23a7595e96edc3df13270fe73f3f456",
> uri="/mmas/wbe_302S/wbe.soap.osp", cnonce="MDA0NzE3", nc=00000001,
> qop="auth", response="121f382f188f4d88550318893011f841", algorithm="MD5"
> Host: 193.166.131.188:8080
> Accept: */*
> Content-Type: text/xml; charset=utf-8
> SOAPaction: ""
> Content-Length: 0
>
> 6. As a result of this the server sends a 400 Bad Request response
>
> HTTP/1.1 400 Bad Request
> Set-cookie: INSessionID=MTY3ODAxMDJAMjM0;path=/
> Content-Type:
> Content-Length: 684
>
> ...
>
> Do you have any idea why the body is not included in the request sent in
> step 5? Because the request already contains the authorization it does
> not make any sense to not include the body.
>
> kind regards,
>
> Sigrid
>
>
Received on 2007-03-07