cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: libcurl failed to create/upload file with digest authentication when header "If-None-Match: *" is added

From: Dan Fandrich <dan_at_coneharvesters.com>
Date: Sat, 26 Jan 2013 21:23:15 +0100

On Sat, Jan 26, 2013 at 05:24:41PM +0000, Yingping Lu wrote:
> Thanks for your reply. Here is the upload test I run with curl utility:
>
> # curl -v --digest -u testuser:password -H "If-None-Match: *" -T test.txt http://10.65.166.94:8080/bucket/test_backup2/test1.txt
>
> * About to connect() to 10.65.166.94 port 8080 (#0)
> * Trying 10.65.166.94...
> * connected
> * Connected to 10.65.166.94 (10.65.166.94) port 8080 (#0)
> * Server auth using Digest with user 'testuser'
> > PUT /bucket/test_backup2/test1.txt HTTP/1.1
> > User-Agent: curl/7.25.0 (x86_64-redhat-linux-gnu) libcurl/7.25.0 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> > Host: 10.65.166.94:8080
> > Accept: */*
> > If-None-Match: *
> > Content-Length: 0
> > Expect: 100-continue

So, this is one of those legitimate cases where libcurl does more than one
request for a single operation. The 100-continue allows it to avoid an
unnecessary round-trip including uploading the entire file, when it's likely
that the request needs authentication to be negotiated. Since you've explicitly
selected Digest authentication, that's what's happening here. However, I think
libcurl ought to be setting the correct Content-Length in the
request--that looks to me like a libcurl bug.

> < HTTP/1.1 100 Continue
> < HTTP/1.1 201 Created
> < DAV: 1,3
> < Date: Tue, 22 Jan 2013 04:19:52 GMT
> < Server: xxxxxx-ba79602e871550668391a673fa57589cf531497e
> < Content-Type: text/html;charset=UTF-8
> < Content-Length: 2194
> < Last-Modified: Tue, 22 Jan 2013 04:19:52 GMT
> < ETag: "e023775a2245bac2787232779ab953d5"

This appears to show that the server has just created a zero-length file
without authenticating the client. If the server should be authenticating PUTs
(and, it would be very odd if it didn't) it looks to me like a server bug.

> * Ignoring the response-body
> * Connection #0 to host 10.65.166.94 left intact
> * Issue another request to this URL: 'http://10.65.166.94:8080/bucket/test_backup2/test1.txt'
> * Re-using existing connection! (#0) with host (nil)
> * Connected to (nil) (10.65.166.94) port 8080 (#0)
> > PUT /bucket/test_backup2/test1.txt HTTP/1.1
> > User-Agent: curl/7.25.0 (x86_64-redhat-linux-gnu) libcurl/7.25.0 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> > Host: 10.65.166.94:8080
> > Accept: */*
> > If-None-Match: *
> > Content-Length: 28
> > Expect: 100-continue

This is libcurl resending the request with the correct Content-Length. I'm not
sure what's happening here without looking at the code. I can't think of a
legitimate reason for it to do so. It might be that it's expecting to negotiate
digest authentication the first time around, and now that it sees that the
server doesn't want authentication, it's doing the actual transmission. But, I
don't see why it should be doing that. The first PUT ought to be prepared to
send the full content-length for just such a case, where authentication isn't
actually needed. And why it's trying again, even after receiving a 2xx code
from the server, I don't know.

This is obviously the way libcurl has worked for a while, based on the test
suite. Compare test10, which does a PUT without authentication and gives the
full Content-Length, with test88, which starts out similarly to your case, in
that it sends Content-Length: 0 at the start since it expects digest
authentication and eventually sends the correct length when it decides that
authentication is complete.

> < HTTP/1.1 412 Precondition Failed
> < DAV: 1,3
> < Date: Tue, 22 Jan 2013 04:19:52 GMT
> < Server: XXXXX-ba79602e871550668391a673fa57589cf531497e
> * no chunk, no close, no size. Assume close to signal end
> <
> * Closing connection #0

In the short term, you could try two things to work around the problem:
remove the --digest (since it isn't needed anyway), and add the -0
option (to avoid the 100-continue step).

>>> Dan

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-01-26