file, but you are not obligated to do so. If you do not wish to do
so, delete this exception statement from your version. */
-/* Written by Hrvoje Niksic. Parts are loosely inspired by cookie
- code submitted by Tomasz Wegrzanowski.
+/* Written by Hrvoje Niksic. Parts are loosely inspired by the
+ cookie patch submitted by Tomasz Wegrzanowski.
- Ideas for future work:
+ This implements the client-side cookie support, as specified
+ (loosely) by Netscape's "preliminary specification", currently
+ available at:
- * Implement limits on cookie-related sizes, such as max. cookie
- size, max. number of cookies, etc.
+ http://wp.netscape.com/newsref/std/cookie_spec.html
- * Add more "cookie jar" methods, such as methods to iterate over
- stored cookies, to clear temporary cookies, to perform
- intelligent auto-saving, etc.
-
- * Support `Set-Cookie2' and `Cookie2' headers? Does anyone really
- use them? */
+ rfc2109 is not supported because of its incompatibilities with the
+ above widely-used specification. rfc2965 is entirely ignored,
+ since popular client software doesn't implement it, and even the
+ sites that do send Set-Cookie2 also emit Set-Cookie for
+ compatibility. */
#include <config.h>
#include <stdio.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
+#include <time.h>
#include "wget.h"
#include "utils.h"
#include "cookies.h"
/* This should *really* be in a .h file! */
-time_t http_atotm PARAMS ((const char *));
+time_t http_atotm (const char *);
\f
/* Declarations of `struct cookie' and the most basic functions. */
#ifdef ENABLE_DEBUG
if (opt.debug)
{
- time_t exptime = (time_t) cookie->expiry_time;
+ time_t exptime = cookie->expiry_time;
DEBUGP (("\nStored cookie %s %d%s %s <%s> <%s> [expiry %s] %s %s\n",
cookie->domain, cookie->port,
cookie->port == PORT_ANY ? " (ANY)" : "",
BOUNDED_TO_ALLOCA (value_b, value_e, value_copy);
expires = http_atotm (value_copy);
- if (expires != -1)
+ if (expires != (time_t) -1)
{
cookie->permanent = 1;
- cookie->expiry_time = (time_t)expires;
+ cookie->expiry_time = expires;
}
else
/* Error in expiration spec. Assume default (cookie doesn't
char *name;
BOUNDED_TO_ALLOCA (name_b, name_e, name);
logprintf (LOG_NOTQUIET,
- _("Error in Set-Cookie, field `%s'"), name);
+ _("Error in Set-Cookie, field `%s'"),
+ escnonprint (name));
}
state = S_ERROR;
break;
if (!silent)
logprintf (LOG_NOTQUIET,
_("Syntax error in Set-Cookie: %s at position %d.\n"),
- sc, p - sc);
+ escnonprint (sc), p - sc);
return NULL;
}
\f
{
int i;
int known_toplevel = 0;
- static char *known_toplevel_domains[] = {
+ static const char *known_toplevel_domains[] = {
".com", ".edu", ".net", ".org", ".gov", ".mil", ".int"
};
for (i = 0; i < countof (known_toplevel_domains); i++)
return 1;
}
-static int path_matches PARAMS ((const char *, const char *));
+static int path_matches (const char *, const char *);
/* Check whether PATH begins with COOKIE_PATH. */
if (!check_domain_match (cookie->domain, host))
{
logprintf (LOG_NOTQUIET,
- "Cookie coming from %s attempted to set domain to %s\n",
- host, cookie->domain);
+ _("Cookie coming from %s attempted to set domain to %s\n"),
+ escnonprint (host), escnonprint (cookie->domain));
xfree (cookie->domain);
goto copy_domain;
}
}
if (!cookie->path)
- cookie->path = xstrdup (path);
+ {
+ /* The cookie doesn't set path: set it to the URL path, sans the
+ file part ("/dir/file" truncated to "/dir/"). */
+ char *trailing_slash = strrchr (path, '/');
+ if (trailing_slash)
+ cookie->path = strdupdelim (path, trailing_slash + 1);
+ else
+ /* no slash in the string -- can this even happen? */
+ cookie->path = xstrdup (path);
+ }
else
{
+ /* The cookie sets its own path; verify that it is legal. */
if (!check_path_match (cookie->path, path))
{
DEBUGP (("Attempt to fake the path: %s, %s\n",
}
}
+ /* Now store the cookie, or discard an existing cookie, if
+ discarding was requested. */
+
if (cookie->discard_requested)
{
discard_matching_cookie (jar, cookie);
/* Support for sending out cookies in HTTP requests, based on
previously stored cookies. Entry point is
`build_cookies_request'. */
+
+/* Return a count of how many times CHR occurs in STRING. */
+
+static int
+count_char (const char *string, char chr)
+{
+ const char *p;
+ int count = 0;
+ for (p = string; *p; p++)
+ if (*p == chr)
+ ++count;
+ return count;
+}
/* Find the cookie chains whose domains match HOST and store them to
DEST.
FILE *fp = fopen (file, "r");
if (!fp)
{
- logprintf (LOG_NOTQUIET, "Cannot open cookies file `%s': %s\n",
+ logprintf (LOG_NOTQUIET, _("Cannot open cookies file `%s': %s\n"),
file, strerror (errno));
return;
}
else
{
if (expiry < cookies_now)
- goto abort; /* ignore stale cookie. */
+ goto abort_cookie; /* ignore stale cookie. */
cookie->expiry_time = expiry;
cookie->permanent = 1;
}
next:
continue;
- abort:
+ abort_cookie:
delete_cookie (cookie);
}
fclose (fp);