Merge branch 'mc/credential-helper-www-authenticate'
Allow information carried on the WWW-AUthenticate header to be passed to the credential helpers. * mc/credential-helper-www-authenticate: credential: add WWW-Authenticate header to cred requests http: read HTTP WWW-Authenticate response headers t5563: add tests for basic and anoymous HTTP access
This commit is contained in:
111
http.c
111
http.c
@ -182,6 +182,115 @@ size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
/*
|
||||
* A folded header continuation line starts with any number of spaces or
|
||||
* horizontal tab characters (SP or HTAB) as per RFC 7230 section 3.2.
|
||||
* It is not a continuation line if the line starts with any other character.
|
||||
*/
|
||||
static inline int is_hdr_continuation(const char *ptr, const size_t size)
|
||||
{
|
||||
return size && (*ptr == ' ' || *ptr == '\t');
|
||||
}
|
||||
|
||||
static size_t fwrite_wwwauth(char *ptr, size_t eltsize, size_t nmemb, void *p)
|
||||
{
|
||||
size_t size = eltsize * nmemb;
|
||||
struct strvec *values = &http_auth.wwwauth_headers;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const char *val;
|
||||
size_t val_len;
|
||||
|
||||
/*
|
||||
* Header lines may not come NULL-terminated from libcurl so we must
|
||||
* limit all scans to the maximum length of the header line, or leverage
|
||||
* strbufs for all operations.
|
||||
*
|
||||
* In addition, it is possible that header values can be split over
|
||||
* multiple lines as per RFC 7230. 'Line folding' has been deprecated
|
||||
* but older servers may still emit them. A continuation header field
|
||||
* value is identified as starting with a space or horizontal tab.
|
||||
*
|
||||
* The formal definition of a header field as given in RFC 7230 is:
|
||||
*
|
||||
* header-field = field-name ":" OWS field-value OWS
|
||||
*
|
||||
* field-name = token
|
||||
* field-value = *( field-content / obs-fold )
|
||||
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
||||
* field-vchar = VCHAR / obs-text
|
||||
*
|
||||
* obs-fold = CRLF 1*( SP / HTAB )
|
||||
* ; obsolete line folding
|
||||
* ; see Section 3.2.4
|
||||
*/
|
||||
|
||||
/* Start of a new WWW-Authenticate header */
|
||||
if (skip_iprefix_mem(ptr, size, "www-authenticate:", &val, &val_len)) {
|
||||
strbuf_add(&buf, val, val_len);
|
||||
|
||||
/*
|
||||
* Strip the CRLF that should be present at the end of each
|
||||
* field as well as any trailing or leading whitespace from the
|
||||
* value.
|
||||
*/
|
||||
strbuf_trim(&buf);
|
||||
|
||||
strvec_push(values, buf.buf);
|
||||
http_auth.header_is_last_match = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* This line could be a continuation of the previously matched header
|
||||
* field. If this is the case then we should append this value to the
|
||||
* end of the previously consumed value.
|
||||
*/
|
||||
if (http_auth.header_is_last_match && is_hdr_continuation(ptr, size)) {
|
||||
/*
|
||||
* Trim the CRLF and any leading or trailing from this line.
|
||||
*/
|
||||
strbuf_add(&buf, ptr, size);
|
||||
strbuf_trim(&buf);
|
||||
|
||||
/*
|
||||
* At this point we should always have at least one existing
|
||||
* value, even if it is empty. Do not bother appending the new
|
||||
* value if this continuation header is itself empty.
|
||||
*/
|
||||
if (!values->nr) {
|
||||
BUG("should have at least one existing header value");
|
||||
} else if (buf.len) {
|
||||
char *prev = xstrdup(values->v[values->nr - 1]);
|
||||
|
||||
/* Join two non-empty values with a single space. */
|
||||
const char *const sp = *prev ? " " : "";
|
||||
|
||||
strvec_pop(values);
|
||||
strvec_pushf(values, "%s%s%s", prev, sp, buf.buf);
|
||||
free(prev);
|
||||
}
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Not a continuation of a previously matched auth header line. */
|
||||
http_auth.header_is_last_match = 0;
|
||||
|
||||
/*
|
||||
* If this is a HTTP status line and not a header field, this signals
|
||||
* a different HTTP response. libcurl writes all the output of all
|
||||
* response headers of all responses, including redirects.
|
||||
* We only care about the last HTTP request response's headers so clear
|
||||
* the existing array.
|
||||
*/
|
||||
if (skip_iprefix_mem(ptr, size, "http/", &val, &val_len))
|
||||
strvec_clear(values);
|
||||
|
||||
exit:
|
||||
strbuf_release(&buf);
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf)
|
||||
{
|
||||
return nmemb;
|
||||
@ -1896,6 +2005,8 @@ static int http_request(const char *url,
|
||||
fwrite_buffer);
|
||||
}
|
||||
|
||||
curl_easy_setopt(slot->curl, CURLOPT_HEADERFUNCTION, fwrite_wwwauth);
|
||||
|
||||
accept_language = http_get_accept_language_header();
|
||||
|
||||
if (accept_language)
|
||||
|
Reference in New Issue
Block a user