cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: HTTP authentication negotiation

From: Raf Nulens <raf.nulens_at_androme.com>
Date: Thu, 05 Jun 2008 15:06:37 +0200

Daniel Stenberg wrote:
> On Wed, 4 Jun 2008, Raf Nulens wrote:
>
>> PUT /pres-rules/users/test04_at_androme.com/pres-rules HTTP/1.1
>
>> Expect: 100-continue
>>
>> HTTP/1.1 100 Continue
>>
>> [full body]
>>
>> HTTP/1.1 401 Unauthorized
>
> Welcome to a world full of brain-dead HTTP servers that act like this.
> The 100-continue is designed to allow the server to reject the data
> before the client sends it, but far too many servers just blindly send
> 100 first only to reject it once the data has been sent...
>

This particular HTTP server is twisted.web2

>> Is there any option we can set so that libcurl resends the PUT request
>> (with authentication) after the 401 unauthorized response, or is this
>> logic implemented outside libcurl?
>
> CURLOPT_SOCKOPTFUNCTION is the option you're looking for. You need to
> provide the seek/rewind function to allow libcurl to seek back to the
> beginning.
>

Ok, we'll try that option

>> Second question: we know that the server where we send the PUT request
>> to needs authentication (either digest or basic), so we expect to get
>> a 401 response after the first PUT. When we set CURLOPT_HTTPAUTH to
>> CURLAUTH_DIGEST, we see that the first PUT is sent with
>> content-length: 0 and without "Expect: 100-continue". However when we
>> set CURLOPT_HTTPAUTH to CURLAUTH_BASIC | CURLAUTH_DIGEST, the first
>> PUT is sent with content-length: 279 and Expect: 100-continue (as seen
>> in the trace).
>>
>> Shouldnt libcurl make a difference between CURLAUTH_BASIC |
>> CURLAUTH_DIGEST and CURLAUTH_NONE | CURLAUTH_BASIC | CURLAUTH_DIGEST?
>
> Possibly, but as I recall things the logic is like this:
>
> If you set multiple HTTP auth methods allowed, libcurl enables "auth
> probe mode" that is pretty much indepdendent on what protocols you
> allow, and then it sends the first request to allow none as well. In
> fact, the CURLAUTH_NONE define is 0 so libcurl can't even detect when
> you explictly allow it (or not).
>
> Then, when the response comes back saying it didn't accept "no auth",
> libcurl will use your set preference and the server's response headers
> to pick the suitable method to proceed with.
>
> I could imagine allowing a more strict use of NONE to enable no auth
> like you say, but that would take some poking of libcurl internals.
>

We have been tweaking a bit in libcurl to see if the http authentication
negotiation can be used when both CURLAUTH_BASIC and CURLAUTH_DIGEST are
set.

We set conn->bits.authneg = TRUE; in CURLcode Curl_http(struct
connectdata *conn, bool *done) when we've set a user/pass and
CURLAUTH_BASIC | CURLAUTH_DIGEST.

In that case Content-length: 0 is sent (without an expect header), and
the correct expected authentication type is returned by the server in
the 401 message.

Related question: in the release notes for libcurl 7.18.2 we see
"libcurl sometimes sent body twice when using CURLAUTH_ANY". Is that
fix related to this 100-continue header issue?

Tnx for your help,

Raf Nulens
Received on 2008-06-05