]> granicus.if.org Git - apache/commitdiff
Add CookieDomain directive to allow setting of the Domain=
authorKen Coar <coar@apache.org>
Thu, 16 Aug 2001 01:46:50 +0000 (01:46 +0000)
committerKen Coar <coar@apache.org>
Thu, 16 Aug 2001 01:46:50 +0000 (01:46 +0000)
cookie attribute; add CookieStyle to allow specification of
cookie syntax: Netscape (default), Cookie or RFC2109, or
Cookie2 or RFC2965.  We have historically supported only the
obsolete Netscape syntax.

PR: several against 1.3
Obtained from: brought forward from 1.3

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90180 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/metadata/mod_usertrack.c

diff --git a/CHANGES b/CHANGES
index 04822bf35bc1af28bb2e592c1bb0da24f1d73361..8ba44329a84a947d1ddeb31abb0387703aa8116a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,11 @@
 Changes with Apache 2.0.24-dev
 
+  *) We have always used the obsolete/deprecated Netscape syntax
+     for our tracking cookies; now the CookieStyle directive
+     allows the Webmaster to choose the Netscape, RFC2109, or
+     RFC2965 format.  The new CookieDomain directive allows the
+     setting of the cookie's Domain= attribute, too.
+
   *) Tweak server/Makefile so that the rules for generating exports.c
      are compatible with make utilities which don't expand wildcards
      in a dependency list (e.g., OS/390 make, certain levels of GNU
index dfe39f08754db27b67056b53294b3537350cca4a..b23a80b87dd82861df03aec453c512b7aa9d7225 100644 (file)
@@ -120,9 +120,18 @@ typedef struct {
     int expires;
 } cookie_log_state;
 
+typedef enum {
+    CT_UNSET,
+    CT_NETSCAPE,
+    CT_COOKIE,
+    CT_COOKIE2
+} cookie_type_e;
+
 typedef struct {
     int enabled;
+    cookie_type_e style;
     char *cookie_name;
+    char *cookie_domain;
 } cookie_dir_rec;
 
 /* Make Cookie: Now we have to generate something that is going to be
@@ -148,23 +157,50 @@ static void make_cookie(request_rec *r)
 
     if (cls->expires) {
        apr_exploded_time_t tms;
+        time_t when;
+
+        when = cls->expires;
+        if ((dcfg->style == CT_UNSET) || (dcfg->style == CT_NETSCAPE)) {
+            when += r->request_time;
+        }
 
-       apr_explode_gmt(&tms, r->request_time + cls->expires * APR_USEC_PER_SEC);
+       apr_explode_gmt(&tms,
+                        r->request_time + cls->expires * APR_USEC_PER_SEC);
 
         /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */
-        new_cookie = apr_psprintf(r->pool,
-                "%s=%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT",
-                    dcfg->cookie_name, cookiebuf, apr_day_snames[tms.tm_wday],
-                    tms.tm_mday, apr_month_snames[tms.tm_mon],
-                    tms.tm_year % 100,
-                    tms.tm_hour, tms.tm_min, tms.tm_sec);
+        new_cookie = apr_psprintf(r->pool, "%s=%s; path=/",
+                                  dcfg->cookie_name, cookiebuf);
+        if ((dcfg->style == CT_UNSET) || (dcfg->style == CT_NETSCAPE)) {
+            new_cookie = apr_psprintf(r->pool,
+                                       "%s; expires=%s, "
+                                       "%.2d-%s-%.2d %.2d:%.2d:%.2d GMT",
+                                       new_cookie, apr_day_snames[tms.tm_wday],
+                                       tms.tm_mday,
+                                       apr_month_snames[tms.tm_mon],
+                                       tms.tm_year % 100,
+                                       tms.tm_hour, tms.tm_min, tms.tm_sec);
+        }
+        else {
+            new_cookie = apr_psprintf(r->pool, "%s; max-age=%d",
+                                      new_cookie, (int) when);
+        }
     }
     else {
-       new_cookie = apr_psprintf(r->pool, "%s=%s; path=/",
-                                dcfg->cookie_name, cookiebuf);
+        new_cookie = apr_psprintf(r->pool, "%s=%s; path=/",
+                                  dcfg->cookie_name, cookiebuf);
+    }
+    if (dcfg->cookie_domain != NULL) {
+        new_cookie = apr_pstrcat(r->pool, new_cookie, "; domain=",
+                                 dcfg->cookie_domain,
+                                 (dcfg->style == CT_COOKIE2
+                                  ? "; version=1"
+                                  : ""),
+                                 NULL);
     }
 
-    apr_table_setn(r->headers_out, "Set-Cookie", new_cookie);
+    apr_table_setn(r->headers_out,
+                   (dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"),
+                   new_cookie);
     apr_table_setn(r->notes, "cookie", apr_pstrdup(r->pool, cookiebuf));   /* log first time */
     return;
 }
@@ -180,7 +216,10 @@ static int spot_cookie(request_rec *r)
         return DECLINED;
     }
 
-    if ((cookie = apr_table_get(r->headers_in, "Cookie")))
+    if ((cookie = apr_table_get(r->headers_in,
+                                (dcfg->style == CT_COOKIE2
+                                 ? "Cookie2"
+                                 : "Cookie"))))
         if ((value = ap_strstr_c(cookie, dcfg->cookie_name))) {
             char *cookiebuf, *cookieend;
 
@@ -215,6 +254,8 @@ static void *make_cookie_dir(apr_pool_t *p, char *d)
 
     dcfg = (cookie_dir_rec *) apr_pcalloc(p, sizeof(cookie_dir_rec));
     dcfg->cookie_name = COOKIE_NAME;
+    dcfg->cookie_domain = NULL;
+    dcfg->style = CT_UNSET;
     dcfg->enabled = 0;
     return dcfg;
 }
@@ -227,14 +268,16 @@ static const char *set_cookie_enable(cmd_parms *cmd, void *mconfig, int arg)
     return NULL;
 }
 
-static const char *set_cookie_exp(cmd_parms *parms, void *dummy, const char *arg)
+static const char *set_cookie_exp(cmd_parms *parms, void *dummy,
+                                  const char *arg)
 {
-    cookie_log_state *cls = ap_get_module_config(parms->server->module_config,
-                                              &usertrack_module);
+    cookie_log_state *cls;
     time_t factor, modifier = 0;
     time_t num = 0;
     char *word;
 
+    cls  = ap_get_module_config(parms->server->module_config,
+                                &usertrack_module);
     /* The simple case first - all numbers (we assume) */
     if (apr_isdigit(arg[0]) && apr_isdigit(arg[strlen(arg) - 1])) {
         cls->expires = atol(arg);
@@ -294,7 +337,8 @@ static const char *set_cookie_exp(cmd_parms *parms, void *dummy, const char *arg
     return NULL;
 }
 
-static const char *set_cookie_name(cmd_parms *cmd, void *mconfig, const char *name)
+static const char *set_cookie_name(cmd_parms *cmd, void *mconfig,
+                                   const char *name)
 {
     cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig;
 
@@ -302,9 +346,69 @@ static const char *set_cookie_name(cmd_parms *cmd, void *mconfig, const char *na
     return NULL;
 }
 
+/*
+ * Set the value for the 'Domain=' attribute.
+ */
+static const char *set_cookie_domain(cmd_parms *cmd, void *mconfig,
+                                     const char *name)
+{
+    cookie_dir_rec *dcfg;
+
+    dcfg = (cookie_dir_rec *) mconfig;
+
+    /*
+     * Apply the restrictions on cookie domain attributes.
+     */
+    if (strlen(name) == 0) {
+        return "CookieDomain values may not be null";
+    }
+    if (name[0] != '.') {
+        return "CookieDomain values must begin with a dot";
+    }
+    if (strchr(&name[1], '.') == NULL) {
+        return "CookieDomain values must contain at least one embedded dot";
+    }
+
+    dcfg->cookie_domain = apr_pstrdup(cmd->pool, name);
+    return NULL;
+}
+
+/*
+ * Make a note of the cookie style we should use.
+ */
+static const char *set_cookie_style(cmd_parms *cmd, void *mconfig,
+                                    const char *name)
+{
+    cookie_dir_rec *dcfg;
+
+    dcfg = (cookie_dir_rec *) mconfig;
+
+    if (strcasecmp(name, "Netscape") == 0) {
+        dcfg->style = CT_NETSCAPE;
+    }
+    else if ((strcasecmp(name, "Cookie") == 0)
+             || (strcasecmp(name, "RFC2109") == 0)) {
+        dcfg->style = CT_COOKIE;
+    }
+    else if ((strcasecmp(name, "Cookie2") == 0)
+             || (strcasecmp(name, "RFC2965") == 0)) {
+        dcfg->style = CT_COOKIE2;
+    }
+    else {
+        return apr_psprintf(cmd->pool, "Invalid %s keyword: '%s'",
+                            cmd->cmd->name, name);
+    }
+
+    return NULL;
+}
+
 static const command_rec cookie_log_cmds[] = {
-    AP_INIT_TAKE1("CookieExpires", set_cookie_exp, NULL, RSRC_CONF,
+    AP_INIT_TAKE1("CookieExpires", set_cookie_exp, NULL, OR_FILEINFO,
                   "an expiry date code"),
+    AP_INIT_TAKE1("CookieDomain", set_cookie_domain, NULL, OR_FILEINFO,
+                  "domain to which this cookie applies"),
+    AP_INIT_TAKE1("CookieStyle", set_cookie_style, NULL, OR_FILEINFO,
+                  "'Netscape', 'Cookie' (RFC2109), or 'Cookie2' (RFC2965)"),
     AP_INIT_FLAG("CookieTracking", set_cookie_enable, NULL, OR_FILEINFO,
                  "whether or not to enable cookies"),
     AP_INIT_TAKE1("CookieName", set_cookie_name, NULL, OR_FILEINFO,