75 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
 | 
						|
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.
 | 
						|
 | 
						|
   NOTE: if the size of the POST data is less than MAX_INITIAL_POST_SIZE (when
 | 
						|
   CURLOPT_POSTFIELDS is used), libcurl will send everything in one single
 | 
						|
   write() (all request-headers and request-body) and thus it will
 | 
						|
   unconditionally send the full post data here.
 | 
						|
 | 
						|
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_FAILRESTART 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.
 |