httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Arnt Gulbrandsen <agul...@troll.no>
Subject Re: [STATUS] (apache-1.3) Wed Apr 1 23:45:32 EST 1998
Date Fri, 03 Apr 1998 19:28:17 GMT
Rodent of Unusual Size <Ken.Coar@Golux.Com>
> Apache 1.3 STATUS:
...
> Available Patches:
...

I (hi - you haven't seen me here before) recently submitted a trivial
patch to extend mod_usertrack.c a bit.  I would like to see it on the
list of available patches for 1.3, and either accepted or rejected.

The patch provides per-domain cookies (which I use to share user-ids
among the *.troll.no web servers) and configurable cookie names.  It
also marginally increases the efficiency of Apache when the server
runs with DNS lookups turned off.

I hope nobody minds my posting the patch again.

--Arnt

--- /tmp/apache_1.3b3/src/modules/standard/mod_usertrack.c	Wed Nov  5 12:23:23 1997
+++ mod_usertrack.c	Fri Mar 13 18:53:29 1998
@@ -107,6 +107,8 @@
 typedef struct {
     int always;
     time_t expires;
+    const char * name;
+    const char * domain;
 }      cookie_log_state;
 
 static const char month_names[12][4] = {
@@ -118,11 +120,15 @@
  */
 #define MILLENIAL_COOKIES
 
+/* Default cookie name.  The CookieName directive allows overrriding
+ * this.  Note that the trailing "=" is now gone.
+ */
+
+#define COOKIE_NAME "Apache"
+
 /* Make Cookie: Now we have to generate something that is going to be
  * pretty unique.  We can base it on the pid, time, hostip */
 
-#define COOKIE_NAME "Apache="
-
 void make_cookie(request_rec *r)
 {
     cookie_log_state *cls = get_module_config(r->server->module_config,
@@ -138,12 +144,6 @@
     char *new_cookie = palloc(r->pool, 1024);
     char *cookiebuf = palloc(r->pool, 1024);
     char *dot;
-    const char *rname = pstrdup(r->pool,
-                           get_remote_host(r->connection, r->per_dir_config,
-                                           REMOTE_NAME));
-
-    if ((dot = strchr(rname, '.')))
-        *dot = '\0';            /* First bit of hostname */
 
 #if defined(NO_GETTIMEOFDAY) && !defined(NO_TIMES)
 /* We lack gettimeofday(), so we must use time() to obtain the epoch
@@ -152,7 +152,7 @@
 
     mpe_times = times(&mpe_tms);
 
-    ap_snprintf(cookiebuf, 1024, "%s%d%ld%ld", rname, (int) getpid(),
+    ap_snprintf(cookiebuf, 1024, "%d-%ld-%ld", (int) getpid(),
                 (long) r->request_time, (long) mpe_tms.tms_utime);
 #elif defined(WIN32)
     /*
@@ -161,13 +161,13 @@
      * was started. It should be relatively unique.
      */
 
-    ap_snprintf(cookiebuf, 1024, "%s%d%ld%ld", rname, (int) getpid(),
+    ap_snprintf(cookiebuf, 1024, "%d-%ld-%ld", (int) getpid(),
                 (long) r->request_time, (long) GetTickCount());
 
 #else
     gettimeofday(&tv, &tz);
 
-    ap_snprintf(cookiebuf, 1024, "%s%d%ld%d", rname, (int) getpid(),
+    ap_snprintf(cookiebuf, 1024, "%d-%ld-%d", (int) getpid(),
                 (long) tv.tv_sec, (int) tv.tv_usec / 1000);
 #endif
 
@@ -191,14 +191,16 @@
 
         /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */
         ap_snprintf(new_cookie, 1024,
-                "%s%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT",
-                    COOKIE_NAME, cookiebuf, days[tms->tm_wday],
-                    tms->tm_mday, month_names[tms->tm_mon],
-		    tms->tm_year % 100,
+                "%s=%s; path=/%s; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT",
+                    cls->name ? cls->name : COOKIE_NAME, cookiebuf,
+		    cls->domain ? cls->domain : "", days[tms->tm_wday],
+		    tms->tm_mday, month_names[tms->tm_mon], tms->tm_year % 100,
                     tms->tm_hour, tms->tm_min, tms->tm_sec);
+    } else {
+        ap_snprintf(new_cookie, 1024, "%s=%s; path=/%s",
+		    cls->name ? cls->name : COOKIE_NAME, cookiebuf,
+		    cls->domain ? cls->domain : "");
     }
-    else
-        ap_snprintf(new_cookie, 1024, "%s%s; path=/", COOKIE_NAME, cookiebuf);
 
     table_set(r->headers_out, "Set-Cookie", new_cookie);
     table_set(r->notes, "cookie", cookiebuf);   /* log first time */
@@ -207,19 +209,21 @@
 
 int spot_cookie(request_rec *r)
 {
-    int *enable = (int *) get_module_config(r->per_dir_config,
-                                            &usertrack_module);
+    int * enable = (int*) get_module_config(r->per_dir_config,
+					    &usertrack_module);
+    cookie_log_state *cls = get_module_config(r->server->module_config,
+					      &usertrack_module);
     char *cookie;
     char *value;
 
-    if (!*enable)
+    if (! *enable )
         return DECLINED;
 
     if ((cookie = table_get(r->headers_in, "Cookie")))
-        if ((value = strstr(cookie, COOKIE_NAME))) {
+        if ((value = strstr(cookie, cls->name ? cls->name : COOKIE_NAME))) {
             char *cookiebuf, *cookieend;
 
-            value += strlen(COOKIE_NAME);
+            value += strlen(cls->name ? cls->name : COOKIE_NAME);
             cookiebuf = pstrdup(r->pool, value);
             cookieend = strchr(cookiebuf, ';');
             if (cookieend)
@@ -251,7 +255,7 @@
 
 const char *set_cookie_enable(cmd_parms *cmd, int *c, int arg)
 {
-    *c = arg;
+    *c = arg; /* referred to as cls->always in other places */
     return NULL;
 }
 
@@ -322,9 +326,86 @@
     return NULL;
 }
 
+
+/* Add domain cookie support to Apache.
+ *
+ * By settting "CookieDomain=your.domain.int" you can instruct the
+ * browsers to send this cookie to all servers in the "your.domain.int"
+ * domain.  Note that Apache prepends the necessary "." itself.
+ *
+ * Added by Arnt Gulbrandsen <agulbra@troll.no>, March 1998.  Comments
+ * are welcome: this is my first apache hack and without doubt could
+ * be improved on easily.
+ */
+
+const char *set_cookie_domain(cmd_parms *parms, void *dummy, const char *arg)
+{
+    int l;
+    const char * p;
+    int chars;
+    cookie_log_state *cls = get_module_config(parms->server->module_config,
+                                              &usertrack_module);
+
+    /* check that arg is a valid-looking domain name */
+
+    p = arg; /* current character */
+    chars = 0; /* characters seen since last dot */
+    while( *p ) {
+	if ( *p == '.' ) {
+	    if ( chars == 0 )
+		return "bad domain name; contains consecutive '.' characters";
+	    else
+		chars = 0;
+	} else if ( isalnum(*p) || *p == '/' || *p == '-' ) {
+	    chars++;
+	} else {
+	    return "bad domain name; contains illegal characters";
+	}
+	p++;
+    }
+
+    if ( chars < 2 || chars > 3 ) {
+	return "bad domain name; top-level domain must contain 2-3 characters";
+    }
+
+    /* at this point we know that arg looks kind of reasonable .
+       so we use it. */
+
+    l = strlen( "; domain=." ) + strlen( arg ) + 1;
+    cls->domain = palloc( parms->pool, l );
+    sprintf( (char *)(cls->domain), "; domain=.%s", arg );
+
+    return NULL;
+}
+
+
+const char *set_cookie_name(cmd_parms *parms, void *dummy, const char *arg)
+{
+    const char * p;
+    cookie_log_state *cls = get_module_config(parms->server->module_config,
+                                              &usertrack_module);
+
+    for( p=arg; *p; p++ )
+	if ( *p <= ' ' || *p >= (char)127 ||
+	     *p == '(' || *p == ')' || *p == '<' || *p == '>' ||
+	     *p == '@' || *p == ',' || *p == ';' || *p == ':' ||
+	     *p == '\\' || *p == '"' || *p == '/' || *p == '[' ||
+	     *p == ']' || *p == '?' || *p == '=' || *p == '{' )
+	    return "bad cookie name; contains illegal character";
+
+    cls->name = pstrdup( parms->pool, arg );
+
+    return NULL;
+}
+
+
 command_rec cookie_log_cmds[] = {
     {"CookieExpires", set_cookie_exp, NULL, RSRC_CONF, TAKE1,
     "an expiry date code"},
+    {"CookieDomain", set_cookie_domain, NULL, RSRC_CONF, TAKE1,
+    "what domain the cookie applies to"},
+    {"CookieName", set_cookie_name, NULL, RSRC_CONF, TAKE1,
+    "the name of Apache's built-in user-tracking cookie"},
     {"CookieTracking", set_cookie_enable, NULL, OR_FILEINFO, FLAG,
     "whether or not to enable cookies"},
     {NULL}


Mime
View raw message