mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Minor cookie fixes. Published in <sxsheyu9yp6.fsf@florida.arsdigita.de>.
This commit is contained in:
parent
105627124e
commit
43ef870bd3
@ -1,3 +1,13 @@
|
||||
2001-05-09 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||
|
||||
* cookies.c (eliminate_dups): New function.
|
||||
(build_cookies_request): Use it.
|
||||
(build_cookies_request): Set chain_store_size after reallocating
|
||||
all_chains.
|
||||
(check_domain_match): Annotated for easier future debugging.
|
||||
(store_cookie): In the debug message, print whether the cookie is
|
||||
permanent.
|
||||
|
||||
2001-05-08 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||
|
||||
* http.c (http_loop): Reset no_truncate before deciding whether to
|
||||
|
103
src/cookies.c
103
src/cookies.c
@ -274,8 +274,10 @@ store_cookie (struct cookie *cookie)
|
||||
|
||||
hash_table_put (cookies_hash_table, chain_key, cookie);
|
||||
|
||||
DEBUGP (("\nStored cookie %s %d %s %d %s %s %s\n",
|
||||
cookie->domain, cookie->port, cookie->path, cookie->secure,
|
||||
DEBUGP (("\nStored cookie %s %d %s %s %d %s %s %s\n",
|
||||
cookie->domain, cookie->port, cookie->path,
|
||||
cookie->permanent ? "permanent" : "nonpermanent",
|
||||
cookie->secure,
|
||||
asctime (localtime ((time_t *)&cookie->expiry_time)),
|
||||
cookie->attr, cookie->value));
|
||||
}
|
||||
@ -706,6 +708,8 @@ check_domain_match (const char *cookie_domain, const char *host)
|
||||
int headlen;
|
||||
const char *tail;
|
||||
|
||||
DEBUGP (("cdm: 1"));
|
||||
|
||||
/* Numeric address requires exact match. It also requires HOST to
|
||||
be an IP address. I suppose we *could* resolve HOST with
|
||||
store_hostaddress (it would hit the hash table), but rfc2109
|
||||
@ -714,6 +718,8 @@ check_domain_match (const char *cookie_domain, const char *host)
|
||||
if (numeric_address_p (cookie_domain))
|
||||
return !strcmp (cookie_domain, host);
|
||||
|
||||
DEBUGP ((" 2"));
|
||||
|
||||
/* The domain must contain at least one embedded dot. */
|
||||
{
|
||||
const char *rest = cookie_domain;
|
||||
@ -730,16 +736,22 @@ check_domain_match (const char *cookie_domain, const char *host)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGP ((" 3"));
|
||||
|
||||
/* For the sake of efficiency, check for exact match first. */
|
||||
if (!strcasecmp (cookie_domain, host))
|
||||
return 1;
|
||||
|
||||
DEBUGP ((" 4"));
|
||||
|
||||
/* In rfc2109 terminology, HOST needs domain-match COOKIE_DOMAIN.
|
||||
This means that COOKIE_DOMAIN needs to start with `.' and be an
|
||||
FQDN, and that HOST must end with COOKIE_DOMAIN. */
|
||||
if (*cookie_domain != '.')
|
||||
return 0;
|
||||
|
||||
DEBUGP ((" 5"));
|
||||
|
||||
/* Two proceed, we need to examine two parts of HOST: its head and
|
||||
its tail. Head and tail are defined in terms of the length of
|
||||
the domain, like this:
|
||||
@ -762,10 +774,14 @@ check_domain_match (const char *cookie_domain, const char *host)
|
||||
return 0;
|
||||
tail = host + headlen;
|
||||
|
||||
DEBUGP ((" 6"));
|
||||
|
||||
/* (1) */
|
||||
if (strcasecmp (tail, cookie_domain))
|
||||
return 0;
|
||||
|
||||
DEBUGP ((" 7"));
|
||||
|
||||
/* Test (2) is not part of the "domain-match" itself, but is
|
||||
recommended by rfc2109 for reasons of privacy. */
|
||||
|
||||
@ -773,6 +789,8 @@ check_domain_match (const char *cookie_domain, const char *host)
|
||||
if (memchr (host, '.', headlen))
|
||||
return 0;
|
||||
|
||||
DEBUGP ((" 8"));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -978,6 +996,43 @@ equality_comparator (const void *p1, const void *p2)
|
||||
return namecmp ? namecmp : valuecmp;
|
||||
}
|
||||
|
||||
/* Eliminate duplicate cookies. "Duplicate cookies" are any two
|
||||
cookies whose name and value are the same. Whenever a duplicate
|
||||
pair is found, one of the cookies is removed. */
|
||||
|
||||
static int
|
||||
eliminate_dups (struct weighed_cookie *outgoing, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* We deploy a simple uniquify algorithm: first sort the array
|
||||
according to our sort criterion, then uniquify it by comparing
|
||||
each cookie with its neighbor. */
|
||||
|
||||
qsort (outgoing, count, sizeof (struct weighed_cookie), equality_comparator);
|
||||
|
||||
for (i = 0; i < count - 1; i++)
|
||||
{
|
||||
struct cookie *c1 = outgoing[i].cookie;
|
||||
struct cookie *c2 = outgoing[i + 1].cookie;
|
||||
if (!strcmp (c1->attr, c2->attr) && !strcmp (c1->value, c2->value))
|
||||
{
|
||||
/* c1 and c2 are the same; get rid of c2. */
|
||||
if (count > i + 1)
|
||||
/* move all ptrs from positions [i + 1, count) to i. */
|
||||
memmove (outgoing + i, outgoing + i + 1,
|
||||
(count - (i + 1)) * sizeof (struct weighed_cookie));
|
||||
/* We decrement i to counter the ++i above. Remember that
|
||||
we've just removed the element in front of us; we need to
|
||||
remain in place to check whether outgoing[i] matches what
|
||||
used to be outgoing[i + 2]. */
|
||||
--i;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Comparator used for sorting by quality. */
|
||||
|
||||
static int
|
||||
@ -997,11 +1052,11 @@ goodness_comparator (const void *p1, const void *p2)
|
||||
return dgdiff ? dgdiff : pgdiff;
|
||||
}
|
||||
|
||||
/* Build a `Cookies' header for a request that goes to HOST:PORT and
|
||||
requests PATH from the server. Memory is allocated by `malloc',
|
||||
and the caller is responsible for freeing it. If no cookies
|
||||
pertain to this request, i.e. no cookie header should be generated,
|
||||
NULL is returned. */
|
||||
/* Build a `Cookie' header for a request that goes to HOST:PORT and
|
||||
requests PATH from the server. The resulting string is allocated
|
||||
with `malloc', and the caller is responsible for freeing it. If no
|
||||
cookies pertain to this request, i.e. no cookie header should be
|
||||
generated, NULL is returned. */
|
||||
|
||||
char *
|
||||
build_cookies_request (const char *host, int port, const char *path,
|
||||
@ -1023,9 +1078,11 @@ build_cookies_request (const char *host, int port, const char *path,
|
||||
if (chain_count > chain_store_size)
|
||||
{
|
||||
/* It's extremely unlikely that more than 20 chains will ever
|
||||
match. But in this case it's easy to not have the
|
||||
limitation, so we don't. */
|
||||
match. But since find_matching_chains reports the exact size
|
||||
it needs, it's easy to not have the limitation, so we
|
||||
don't. */
|
||||
all_chains = alloca (chain_count * sizeof (struct cookie *));
|
||||
chain_store_size = chain_count;
|
||||
goto again;
|
||||
}
|
||||
|
||||
@ -1047,6 +1104,8 @@ build_cookies_request (const char *host, int port, const char *path,
|
||||
/* Allocate the array. */
|
||||
outgoing = alloca (count * sizeof (struct weighed_cookie));
|
||||
|
||||
/* Fill the array with all the matching cookies from all the
|
||||
matching chains. */
|
||||
ocnt = 0;
|
||||
for (i = 0; i < chain_count; i++)
|
||||
for (cookie = all_chains[i]; cookie; cookie = cookie->next)
|
||||
@ -1062,28 +1121,8 @@ build_cookies_request (const char *host, int port, const char *path,
|
||||
assert (ocnt == count);
|
||||
|
||||
/* Eliminate duplicate cookies; that is, those whose name and value
|
||||
are the same. We do it by first sorting the array, and then
|
||||
uniq'ing it. */
|
||||
qsort (outgoing, count, sizeof (struct weighed_cookie), equality_comparator);
|
||||
for (i = 0; i < count - 1; i++)
|
||||
{
|
||||
struct cookie *c1 = outgoing[i].cookie;
|
||||
struct cookie *c2 = outgoing[i + 1].cookie;
|
||||
if (!strcmp (c1->attr, c2->attr) && !strcmp (c1->value, c2->value))
|
||||
{
|
||||
/* c1 and c2 are the same; get rid of c2. */
|
||||
if (count > i + 1)
|
||||
/* move all ptrs from positions [i + 1, count) to i. */
|
||||
memmove (outgoing + i, outgoing + i + 1,
|
||||
(count - (i + 1)) * sizeof (struct weighed_cookie));
|
||||
/* We decrement i to counter the ++i above. Remember that
|
||||
we've just removed the element in front of us; we need to
|
||||
remain in place to check whether outgoing[i] what used to
|
||||
be outgoing[i + 2]. */
|
||||
--i;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
are the same. */
|
||||
count = eliminate_dups (outgoing, count);
|
||||
|
||||
/* Sort the array so that best-matching domains come first, and
|
||||
that, within one domain, best-matching paths come first. */
|
||||
@ -1192,7 +1231,7 @@ domain_port (const char *domain_b, const char *domain_e,
|
||||
++p; \
|
||||
} while (0)
|
||||
|
||||
#define SET_WORD_BOUNDARIES(p, b, e) do { \
|
||||
#define SET_WORD_BOUNDARIES(p, b, e) do { \
|
||||
SKIP_WS (p); \
|
||||
b = p; \
|
||||
/* skip non-ws */ \
|
||||
|
Loading…
Reference in New Issue
Block a user