cURL / Mailing Lists / curl-library / Single Mail

curl-library

PUT/POST with Auth Done Right(?)

From: Daniel Stenberg <daniel-curl_at_haxx.se>
Date: Mon, 8 Nov 2004 23:14:16 +0100 (CET)

Hi

I want to make libcurl behave correctly. Given the feedback and discussion
over the last couple of days, this is how I suggest we make libcurl work.

Please point out my obvious mistakes or fill in your own great additional
ideas!

I am really not happy with the way RFC2616 forces us to behave. But to adhere
to standards and to function properly with strict servers, I can't see any
other escape that to make libcurl work like this:

o No more HEAD use when it has no auth info to send. Issue the proper PUT/POST
   request immediately, with the correct Content-Length and Expect: headers.

o If a 100 response is received or the wait for one times out, start sending
   the request-body.

o If a 401 (or 407 when talking through a proxy) is received, then:

   if we provided credentials in our request (alas, this is the first pass in
   the auth phase) and this is NTLM, we continue sending the whole request-body

   if not, we close the connection at once (if we have more data to send that
   is, otherwise we keep it open)

o When sending a PUT/POST request (that hasn't a negotiated auth) after a
   401/407 response, we know that it will be rejected and thus we claim
   Content-Length zero. (This seems to be what IE does.)

o The last step in the auth phase (the second request in Digest and Negotiate,
   and the third in NTLM) then sends a full and proper PUT/POST request (again)
   with the proper Content-Length and a following request-body.

   NOTE: this may very well be the second time the whole or at least parts of
   the request body is sent to the server. Since the data may be provided to
   libcurl with a callback, we need a way to tell the app that the upload is
   to be restarted so that the callback will provide data from the start again.
   This requires an API method/mechanism that libcurl doesn't have today.

   It would probably make sense to somehow make this instruction using the read
   callback. It will be troublesome for some apps to deal with a rewind like
   this. I'm thinking for example when using 'curl' to upload data from
   stdin...

o The approach used until now, that issues a HEAD on the given URL to trigger
   the auth negotiation could still be supported and encouraged, but it would
   be up to the app to first fetch a URL with GET/HEAD to negotiate on, since
   then a following PUT/POST wouldn't need to negotiate authentication and
   thus avoid double-sending data.

   Optionally, we keep the current approach if some option is set, since it
   seems to work fairly well for POST on most servers.

o If told explicitly to use i.e NTLM when doing a POST/PUT, libcurl could
   immediately go the Content-Length: 0 bytes route to avoid the first send
   all data phase. (Unless it already passed the authentication phase.)

Good? Bad? Flaws?

-- 
     Daniel Stenberg -- http://curl.haxx.se -- http://daniel.haxx.se
       Dedicated custom curl help for hire: http://haxx.se/curl.html
Received on 2004-11-08