1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Use the extract_param function for parsing the www-authenticate header.

This commit is contained in:
hniksic 2006-02-28 14:32:56 -08:00
parent 6d2dc0a1b3
commit 65cc42ee09
3 changed files with 27 additions and 97 deletions

View File

@ -347,14 +347,14 @@ parse_set_cookie (const char *set_cookie, bool silent)
struct cookie *cookie = cookie_new (); struct cookie *cookie = cookie_new ();
param_token name, value; param_token name, value;
if (!extract_param (&ptr, &name, &value)) if (!extract_param (&ptr, &name, &value, ';'))
goto error; goto error;
if (!value.b) if (!value.b)
goto error; goto error;
cookie->attr = strdupdelim (name.b, name.e); cookie->attr = strdupdelim (name.b, name.e);
cookie->value = strdupdelim (value.b, value.e); cookie->value = strdupdelim (value.b, value.e);
while (extract_param (&ptr, &name, &value)) while (extract_param (&ptr, &name, &value, ';'))
{ {
if (TOKEN_IS (name, "domain")) if (TOKEN_IS (name, "domain"))
{ {
@ -1370,7 +1370,7 @@ test_cookies (void)
param_token name, value; param_token name, value;
const char *ptr = data; const char *ptr = data;
int j = 0; int j = 0;
while (extract_param (&ptr, &name, &value)) while (extract_param (&ptr, &name, &value, ';'))
{ {
char *n = strdupdelim (name.b, name.e); char *n = strdupdelim (name.b, name.e);
char *v = strdupdelim (value.b, value.e); char *v = strdupdelim (value.b, value.e);

View File

@ -855,11 +855,11 @@ skip_short_body (int fd, wgint contlen)
return true; return true;
} }
/* Extract a parameter from the HTTP header at *SOURCE and advance /* Extract a parameter from the string (typically an HTTP header) at
*SOURCE to the next parameter. Return false when there are no more **SOURCE and advance SOURCE to the next parameter. Return false
parameters to extract. The name of the parameter is returned in when there are no more parameters to extract. The name of the
NAME, and the value in VALUE. If the parameter has no value, the parameter is returned in NAME, and the value in VALUE. If the
token's value is zeroed out. parameter has no value, the token's value is zeroed out.
For example, if *SOURCE points to the string "attachment; For example, if *SOURCE points to the string "attachment;
filename=\"foo bar\"", the first call to this function will return filename=\"foo bar\"", the first call to this function will return
@ -868,7 +868,8 @@ skip_short_body (int fd, wgint contlen)
call will return false, indicating no more valid tokens. */ call will return false, indicating no more valid tokens. */
bool bool
extract_param (const char **source, param_token *name, param_token *value) extract_param (const char **source, param_token *name, param_token *value,
char separator)
{ {
const char *p = *source; const char *p = *source;
@ -881,15 +882,15 @@ extract_param (const char **source, param_token *name, param_token *value)
/* Extract name. */ /* Extract name. */
name->b = p; name->b = p;
while (*p && !ISSPACE (*p) && *p != '=' && *p != ';') ++p; while (*p && !ISSPACE (*p) && *p != '=' && *p != separator) ++p;
name->e = p; name->e = p;
if (name->b == name->e) if (name->b == name->e)
return false; /* empty name: error */ return false; /* empty name: error */
while (ISSPACE (*p)) ++p; while (ISSPACE (*p)) ++p;
if (*p == ';' || !*p) /* no value */ if (*p == separator || !*p) /* no value */
{ {
xzero (*value); xzero (*value);
if (*p == ';') ++p; if (*p == separator) ++p;
*source = p; *source = p;
return true; return true;
} }
@ -908,8 +909,8 @@ extract_param (const char **source, param_token *name, param_token *value)
value->e = p++; value->e = p++;
/* Currently at closing quote; find the end of param. */ /* Currently at closing quote; find the end of param. */
while (ISSPACE (*p)) ++p; while (ISSPACE (*p)) ++p;
while (*p && *p != ';') ++p; while (*p && *p != separator) ++p;
if (*p == ';') if (*p == separator)
++p; ++p;
else if (*p) else if (*p)
/* garbage after closed quote, e.g. foo="bar"baz */ /* garbage after closed quote, e.g. foo="bar"baz */
@ -918,11 +919,11 @@ extract_param (const char **source, param_token *name, param_token *value)
else /* unquoted */ else /* unquoted */
{ {
value->b = p; value->b = p;
while (*p && *p != ';') ++p; while (*p && *p != separator) ++p;
value->e = p; value->e = p;
while (value->e != value->b && ISSPACE (value->e[-1])) while (value->e != value->b && ISSPACE (value->e[-1]))
--value->e; --value->e;
if (*p == ';') ++p; if (*p == separator) ++p;
} }
*source = p; *source = p;
return true; return true;
@ -935,7 +936,7 @@ static bool
parse_content_disposition (const char *hdr, char **filename) parse_content_disposition (const char *hdr, char **filename)
{ {
param_token name, value; param_token name, value;
while (extract_param (&hdr, &name, &value)) while (extract_param (&hdr, &name, &value, ';'))
if (BOUNDED_EQUAL_NO_CASE (name.b, name.e, "filename") && value.b != NULL) if (BOUNDED_EQUAL_NO_CASE (name.b, name.e, "filename") && value.b != NULL)
{ {
/* Make the file name begin at the last slash or backslash. */ /* Make the file name begin at the last slash or backslash. */
@ -2715,45 +2716,6 @@ basic_authentication_encode (const char *user, const char *passwd)
} while (0) } while (0)
#ifdef ENABLE_DIGEST #ifdef ENABLE_DIGEST
/* Parse HTTP `WWW-Authenticate:' header. AU points to the beginning
of a field in such a header. If the field is the one specified by
ATTR_NAME ("realm", "opaque", and "nonce" are used by the current
digest authorization code), extract its value in the (char*)
variable pointed by RET. Returns negative on a malformed header,
or number of bytes that have been parsed by this call. */
static int
extract_header_attr (const char *au, const char *attr_name, char **ret)
{
const char *ep;
const char *cp = au;
if (strncmp (cp, attr_name, strlen (attr_name)) == 0)
{
cp += strlen (attr_name);
if (!*cp)
return -1;
SKIP_WS (cp);
if (*cp != '=')
return -1;
if (!*++cp)
return -1;
SKIP_WS (cp);
if (*cp != '\"')
return -1;
if (!*++cp)
return -1;
for (ep = cp; *ep && *ep != '\"'; ep++)
;
if (!*ep)
return -1;
xfree_null (*ret);
*ret = strdupdelim (cp, ep);
return ep - au + 1;
}
else
return 0;
}
/* Dump the hexadecimal representation of HASH to BUF. HASH should be /* Dump the hexadecimal representation of HASH to BUF. HASH should be
an array of 16 bytes containing the hash keys, and BUF should be a an array of 16 bytes containing the hash keys, and BUF should be a
buffer of 33 writable characters (32 for hex digits plus one for buffer of 33 writable characters (32 for hex digits plus one for
@ -2788,53 +2750,21 @@ digest_authentication_encode (const char *au, const char *user,
{ "nonce", &nonce } { "nonce", &nonce }
}; };
char *res; char *res;
param_token name, value;
realm = opaque = nonce = NULL; realm = opaque = nonce = NULL;
au += 6; /* skip over `Digest' */ au += 6; /* skip over `Digest' */
while (*au) while (extract_param (&au, &name, &value, ','))
{ {
int i; int i;
SKIP_WS (au);
for (i = 0; i < countof (options); i++) for (i = 0; i < countof (options); i++)
{ if (name.e - name.b == strlen (options[i].name)
int skip = extract_header_attr (au, options[i].name, && 0 == strncmp (name.b, options[i].name, name.e - name.b))
options[i].variable); {
if (skip < 0) *options[i].variable = strdupdelim (value.b, value.e);
{ break;
xfree_null (realm); }
xfree_null (opaque);
xfree_null (nonce);
return NULL;
}
else if (skip)
{
au += skip;
break;
}
}
if (i == countof (options))
{
while (*au && *au != '=')
au++;
if (*au && *++au)
{
SKIP_WS (au);
if (*au == '\"')
{
au++;
while (*au && *au != '\"')
au++;
if (*au)
au++;
}
}
}
while (*au && *au != ',')
au++;
if (*au)
au++;
} }
if (!realm || !nonce || !user || !passwd || !path || !method) if (!realm || !nonce || !user || !passwd || !path || !method)
{ {

View File

@ -42,7 +42,7 @@ typedef struct {
/* A token consists of characters in the [b, e) range. */ /* A token consists of characters in the [b, e) range. */
const char *b, *e; const char *b, *e;
} param_token; } param_token;
bool extract_param (const char **, param_token *, param_token *); bool extract_param (const char **, param_token *, param_token *, char);
#endif /* HTTP_H */ #endif /* HTTP_H */