cURL / Mailing Lists / curl-library / Single Mail

curl-library

More PUT/POST Auth

From: Daniel Stenberg <daniel-curl_at_haxx.se>
Date: Mon, 15 Nov 2004 00:36:51 +0100 (CET)

Ok, here comes my next take at describing how libcurl should behave, and also
down there is my suggested API fix to make apps work with this.

   == I need your feedback, especially on the API part. ==

1. PUT/POST without a known auth to use (possibly no auth required):

    (When explicitly set to use a multi-pass auth when doing a POST/PUT,
    libcurl should immediately go the Content-Length: 0 bytes route to avoid
    the first send all data phase, step 2. If told to use a single-pass auth,
    goto step 3.)

    Issue the proper PUT/POST request immediately, with the correct
    Content-Length and Expect: headers.

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

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

    If we have "more than just a little" data left to send, close the
    connection. Exactly what "more than just a little" means will have to be
    determined. Possibly the current transfer speed should be taken into
    account as well.

2. PUT/POST with multi-pass auth but not yet completely negotiated:

    Send a PUT/POST request, we know that it will be rejected and thus we claim
    Content-Length zero to avoid having to send the request-body. (This seems
    to be what IE does.)

3. PUT/POST as the last step in the auth negotiation, that is when we have
    what we believe is a completed negotiation:

    Send 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 (or even third) 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. See below.

Data Rewind

    It will be troublesome for some apps to deal with a rewind like this in all
    circumstances. I'm thinking for example when using 'curl' to upload data
    from stdin. If libcurl ends up having to rewind the reading for a request
    to succeed, of course a lack of this callback or if it returns failure, will
    cause the request to fail completely.

    The new callback is set with CURLOPT_IOCTLFUNCTION (in an attempt to add a
    more generic function that might be used for other IO-related controls in
    the future):

      curlioerr curl_ioctl(CURL *handle, curliocmd cmd, void *clientp);

    And in the case where the read is to be rewinded, it would be called with a
    cmd named CURLIOCMD_RESTARTREAD. The callback would then return CURLIOE_OK,
    if things are fine, or CURLIOE_FAILRESTARTREAD if not.

Backwards Compatibility

    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
    (CURLOPT_HEADBEFOREAUTH or similar), since it seems to work fairly well for
    POST on most servers.

-- 
      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-15