cURL / Mailing Lists / curl-library / Single Mail

curl-library

Design Change Proposal: Transparent Authentication Negotiation

From: Aaron Oneal <aaron.oneal_at_spicypixel.com>
Date: Fri, 5 Jun 2009 18:48:26 -0700

When a caller uses a networking API like libcurl to make an HTTP request,
the expectation is for a single response and for the response to correlate
with the request.

 

Given a call:

 

Response = Client.Request(url)

 

Typical flow would be:

 

1. Request: POST /resource, Content-Length: 500, body ...

2. Response: 200 OK

 

In the case of authentication negotiation, some networking libraries make
additional requests on the caller's behalf, but the expectation of the
caller doesn't change because the call is still made as:

 

Response = Client.Request(url)

 

Even though the wire flow is:

 

1. Request: POST /resource, Content-Length: 0

2. Response: 401 Authorization required

3. Request: POST / resource, Content-Length: 500, body .

4. Response: 200 OK

 

In this case, the request on line 3 is what the caller actually requested,
and the response on line 4 is the answer they're interested in. The exchange
on lines 1 and 2 are simply part of how a library implements negotiation and
the results of that exchange are of little interest to the caller unless
there is a failure (making 2 the final response, for example).

 

Unfortunately, libcurl today actually passes information back to the caller
from auth negotiation. Register CURLOPT_HEADERFUNCTION and you'll get all
the headers from the first response and the second one. This can cause
problems when from a caller perspective it made one request, is expecting to
get back one response, and instead gets two.

 

A problem example is when trying to determine the status code of the
response. Most client code would assume headers from only the final response
to be returned and would not be expecting to receive multiple status code
lines. If a client actually needed this information, it could certainly turn
off authentication, make separate requests, and handle the 401's itself.

 

I propose that libcurl should insulate the client from auth exchange and
that such headers should not be passed back to the caller. This convention
is consistent with other libraries that support HTTP such as WinInet,
WinHTTP, and System.Net.HttpWebRequest.

 

I understand the current behavior has been around from day one, however, I
do not believe that it is a desirable one. Please consider changing this
design to be more consistent with caller expectations and conventions from
other libraries. Thank you.
Received on 2009-06-06