Attached is an updated version of the patch that should apply to Apache 1.3.12 cleanly. I don't know if anyone's ported the patch to 2.0. I'm not sure how significantly, if at all, mod_usertrack has changed for 2.0. (This has an additional feature, CookieDomainEnv, which is less documented and probably not as completely useful as it could be.) Jim On Jun 24, Greg Cope wrote: > Jim Winstead wrote: > > > > On Jun 23, Jim Sproull wrote: > > > This all works fine. However, the get_sessionid and set_sessionid are > > > using a dbm file, which is locked and unlocked during each request. (I > > > know, I know). Obviously, this is a lot more load that is necessary. I > > > tried using a simple global variable (defined before the handler), but this > > > was unreliable as it was set differently for each request. No doubt due to > > > different processes handling each request. Can anyone suggest a better way > > > of handling this globablly accessed data? Thanks. > > > > If you search the new-httpd list, you should be able to find a > > patch I posted to mod_usertrack (quite some time ago) that in > > addition to adding a configuration option (to set the cookie's > > domain or something like that), makes mod_usertrack create two > > additional notes -- "out-cookie" and "in-cookie" which are set to > > the value of its session cookie depending on whether it is outgoing > > (being set) or incoming (subsequent requests). > > This is just what I've been after (the domain and cookie set checking) - > thanks. > > Has anyone an issues with using this apache module with mod_perl. I > need to track users via cookies on a site that is 1/2 html and half > mod_perl - hence this offers an ideal solution for cookie tracking HTML > pages via an UID. > > Jim , all the patches that I've found from you in archives appear to be > incomplete, I've tried fixing one but to little avail (my C is very very > basic). > > Could you post or send me the patch - would be very much appreciated! > > Also does anyone know if anyone is working on an Apache 2.0 version ? > > Greg Cope > > > > > With that, it is very easy to know when the cookie is new, and if > > you log the two fields seperately, you can easily calculate the > > number of your visitors who have cookies disabled (or only make > > a single request to the webserver). > > > > Jim >
diff -ur apache_1.3.12-orig/htdocs/manual/mod/mod_usertrack.html apache_1.3.12/htdocs/manual/mod/mod_usertrack.html --- apache_1.3.12-orig/htdocs/manual/mod/mod_usertrack.html Wed Feb 23 15:11:39 2000 +++ apache_1.3.12/htdocs/manual/mod/mod_usertrack.html Sat Jun 24 13:14:14 2000 @@ -45,6 +45,13 @@ CustomLog logs/clickstream "%{cookie}n %r %t" </PRE> ++<P> +In Apache 1.3.13 or later, the cookie can also be logged whether +it is outgoing (being set for the first time) or incoming, with +<TT>%{out-cookie}n</TT> and <TT>%{in-cookie}n</TT>, respectively, +in the log format. +</P> + For backward compatibility the configurable log module implements the old <TT>CookieLog</TT> directive, but this should be upgraded to the above <TT>CustomLog</TT> directive. @@ -52,12 +59,90 @@ <H2>Directives</H2> <UL> +<LI><A HREF="#cookiedomain">CookieDomain</A> +<LI><A HREF="#cookiedomainenv">CookieDomainEnv</A> <LI><A HREF="#cookieexpires">CookieExpires</A> <LI><A HREF="#cookiename">CookieName</A> <LI><A HREF="#cookietracking">CookieTracking</A> </UL> <HR> + +<H2><A NAME="cookiedomain">CookieDomain</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CookieDomain <EM>token</EM><BR> +<BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM> +<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, directory, .htaccess<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> optional<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_usertrack<P> + +<P> +This directive allows you to change the domain of the cookie this module +uses for its tracking purposes. By default the cookie is sent with +no domain, which tells the browser to only return the cookie to the +hostname from which it received the cookie. +</P> + +<P> +For example, by setting the domain to ".apache.org", the same cookie +will be used to track users across http://www.apache.org, dev.apache.org, +and all of the other subdomains within the apache.org domain. +</P> + +<P> +The domain you specify must be the same as the host used +by the client for the request, or at least within the same +domain if using the leading-dot notation, otherwise the cookie +will not be set. The domain must also include at least two +periods, so you can't set a cookie for top-level domains. See <A +HREF="http://www.netscape.com/newsref/std/cookie_spec.html">Netscape's +cookie specification</A> for more details. +</P> + +<H2><A NAME="cookiedomainenv">CookieDomainEnv</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CookieDomainEnv <EM>token</EM><BR> +<BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM> +<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, directory, .htaccess<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> optional<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_usertrack<P> + +<P> +This directive allows you to set the domain of the cookie this module uses +for its tracking purposes based on an environment variable. +</P> <H2><A NAME="cookieexpires">CookieExpires</A></H2> <A diff -ur apache_1.3.12-orig/src/modules/standard/mod_usertrack.c apache_1.3.12/src/modules/standard/mod_usertrack.c --- apache_1.3.12-orig/src/modules/standard/mod_usertrack.c Fri Oct 29 14:29:53 1999 +++ apache_1.3.12/src/modules/standard/mod_usertrack.c Sat Jun 24 13:16:34 2000 @@ -116,6 +116,8 @@ typedef struct { int enabled; char *cookie_name; + char *cookie_domain; + char *cookie_domain_env; } cookie_dir_rec; /* Define this to allow post-2000 cookies. Cookies use two-digit dates, @@ -148,6 +150,7 @@ char *new_cookie; const char *rname = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME); + const char *cookie_domain = NULL; cookie_dir_rec *dcfg; dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module); @@ -184,6 +187,13 @@ (long) tv.tv_sec, (int) tv.tv_usec / 1000); #endif + if (dcfg->cookie_domain) { + cookie_domain = dcfg->cookie_domain; + } + else if (dcfg->cookie_domain_env) { + cookie_domain = ap_table_get(r->subprocess_env, dcfg->cookie_domain_env); + } + if (cls->expires) { struct tm *tms; time_t when = r->request_time + cls->expires; @@ -202,19 +212,25 @@ /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */ new_cookie = ap_psprintf(r->pool, - "%s=%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", - dcfg->cookie_name, cookiebuf, ap_day_snames[tms->tm_wday], + "%s=%s; path=/%s%s; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", + dcfg->cookie_name, cookiebuf, + cookie_domain ? "; domain=" : "", + cookie_domain ? cookie_domain : "", + ap_day_snames[tms->tm_wday], tms->tm_mday, ap_month_snames[tms->tm_mon], - tms->tm_year % 100, + tms->tm_year % 100, tms->tm_hour, tms->tm_min, tms->tm_sec); } else { - new_cookie = ap_psprintf(r->pool, "%s=%s; path=/", - dcfg->cookie_name, cookiebuf); + new_cookie = ap_psprintf(r->pool, "%s=%s; path=/%s%s", + dcfg->cookie_name, cookiebuf, + cookie_domain ? "; domain=" : "", + cookie_domain ? cookie_domain : ""); } ap_table_setn(r->headers_out, "Set-Cookie", new_cookie); ap_table_setn(r->notes, "cookie", ap_pstrdup(r->pool, cookiebuf)); /* log first time */ + ap_table_setn(r->notes, "out-cookie", ap_pstrdup(r->pool, cookiebuf)); /* log +first time */ return; } @@ -241,6 +257,7 @@ /* Set the cookie in a note, for logging */ ap_table_setn(r->notes, "cookie", cookiebuf); + ap_table_setn(r->notes, "in-cookie", cookiebuf); return DECLINED; /* There's already a cookie, no new one */ } @@ -264,6 +281,8 @@ dcfg = (cookie_dir_rec *) ap_pcalloc(p, sizeof(cookie_dir_rec)); dcfg->cookie_name = COOKIE_NAME; + dcfg->cookie_domain = NULL; + dcfg->cookie_domain_env = NULL; dcfg->enabled = 0; return dcfg; } @@ -351,6 +370,22 @@ return NULL; } +static const char *set_cookie_domain(cmd_parms *cmd, void *mconfig, char *name) +{ + cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig; + + dcfg->cookie_domain = ap_pstrdup(cmd->pool, name); + return NULL; +} + +static const char *set_cookie_domain_env(cmd_parms *cmd, void *mconfig, char *name) +{ + cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig; + + dcfg->cookie_domain_env = ap_pstrdup(cmd->pool, name); + return NULL; +} + static const command_rec cookie_log_cmds[] = { {"CookieExpires", set_cookie_exp, NULL, RSRC_CONF, TAKE1, "an expiry date code"}, @@ -358,6 +393,10 @@ "whether or not to enable cookies"}, {"CookieName", set_cookie_name, NULL, OR_FILEINFO, TAKE1, "name of the tracking cookie"}, + {"CookieDomain", set_cookie_domain, NULL, OR_FILEINFO, TAKE1, + "domain for the tracking cookie"}, + {"CookieDomainEnv", set_cookie_domain_env, NULL, OR_FILEINFO, TAKE1, + "environment variable containing the domain for the tracking cookie"}, {NULL} };