You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Alexei Kosut <ak...@organic.com> on 1996/07/22 20:23:31 UTC
cookies patch
Included is a patch that we're using here at Organic, and that might be
want to be included in the Apache distribution. It adds two new directives
to mod_cookies: "CookieExpires", which allows you to tack expiry times
onto cookies (using similar syntax to mod_expires, e.g. `CookieExpires
"plus ten months three days"'), and "CookieEnable", which lets you turn
off cookies in specific virtualhosts or directories by putting
"CookieEnable Off" in them.
Anyhow, here's the patch:
Index: mod_cookies.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_cookies.c,v
retrieving revision 1.10
diff -c -r1.10 mod_cookies.c
*** mod_cookies.c 1996/07/04 13:01:59 1.10
--- mod_cookies.c 1996/07/19 22:12:10
***************
*** 96,101 ****
--- 96,102 ----
* code from mod_log_agent.c.
* 24.5.96 MJC Improved documentation after receiving comments from users
* 4.7.96 MJC Bug, "else" missing since February caused logging twice
+ * 19.7.96 AEK Added CookieExpires and CookieEnable directives
*/
#include "httpd.h"
***************
*** 109,116 ****
--- 110,123 ----
char *fname;
int log_fd;
int always;
+ time_t expires;
} cookie_log_state;
+ /* Define this to allow post-2000 cookies. Cookies use two-digit dates,
+ * so it might be dicey. (Netscape does it correctly, but others may not)
+ */
+ #define MILLENIAL_COOKIES
+
/* Make Cookie: Now we have to generate something that is going to be
* pretty unique. We can base it on the pid, time, hostip */
***************
*** 118,138 ****
void make_cookie(request_rec *r)
{
struct timeval tv;
char new_cookie[100]; /* blurgh */
char *dot;
const char *rname = pstrdup(r->pool,
! get_remote_host(r->connection, r->per_dir_config,
REMOTE_NAME));
struct timezone tz = { 0 , 0 };
if ((dot = strchr(rname,'.'))) *dot='\0'; /* First bit of hostname */
gettimeofday(&tv, &tz);
! sprintf(new_cookie,"%s%s%d%ld%d; path=/",
! COOKIE_NAME, rname,
! (int)getpid(),
! (long)tv.tv_sec, (int)tv.tv_usec/1000 );
table_set(r->headers_out,"Set-Cookie",new_cookie);
return;
--- 125,177 ----
void make_cookie(request_rec *r)
{
+ cookie_log_state *cls = get_module_config (r->server->module_config,
+ &cookies_module);
struct timeval tv;
char new_cookie[100]; /* blurgh */
char *dot;
const char *rname = pstrdup(r->pool,
! get_remote_host(r->connection, r->per_dir_config,
REMOTE_NAME));
struct timezone tz = { 0 , 0 };
if ((dot = strchr(rname,'.'))) *dot='\0'; /* First bit of hostname */
gettimeofday(&tv, &tz);
!
! if (cls->expires) {
! static const char *const days[7]=
! {"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
! struct tm *tms;
! time_t when = time(NULL) + cls->expires;
!
! #ifndef MILLENIAL_COOKIES
! /* Only two-digit date string, so we can't trust "00" or more.
! * Therefore, we knock it all back to just before midnight on
! * 1/1/2000 (which is 946684799)
! */
!
! if (when > 946684799)
! when = 946684799;
! #endif
! tms = gmtime(&when);
!
!
!
! /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */
! sprintf(new_cookie,
! "%s%s%d%ld%d; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT",
! COOKIE_NAME, rname, (int)getpid(),
! (long)tv.tv_sec, (int)tv.tv_usec/1000, days[tms->tm_wday],
! tms->tm_mday, month_snames[tms->tm_mon],
! (tms->tm_year >= 100) ? tms->tm_year - 100 : tms->tm_year,
! tms->tm_hour, tms->tm_min, tms->tm_sec);
! }
! else
! sprintf(new_cookie,"%s%s%d%ld%d; path=/",
! COOKIE_NAME, rname,
! (int)getpid(),
! (long)tv.tv_sec, (int)tv.tv_usec/1000 );
table_set(r->headers_out,"Set-Cookie",new_cookie);
return;
***************
*** 140,147 ****
--- 179,190 ----
int spot_cookie(request_rec *r)
{
+ int *disable = (int *)get_module_config(r->per_dir_config,
+ &cookies_module);
char *cookie;
+ if (*disable) return DECLINED;
+
if ((cookie = table_get (r->headers_in, "Cookie")))
if (strstr(cookie,COOKIE_NAME))
return DECLINED; /* Theres already a cookie, no new one */
***************
*** 165,174 ****
--- 208,228 ----
cls->fname = "";
cls->log_fd = -1;
+ cls->expires = 0;
return (void *)cls;
}
+ void *make_cookie_dir (pool *p, char *d) {
+ return (void *)pcalloc(p, sizeof(int));
+ }
+
+ char *set_cookie_disable (cmd_parms *cmd, int *c, int arg)
+ {
+ *c = !arg;
+ return NULL;
+ }
+
char *set_cookie_log (cmd_parms *parms, void *dummy, char *arg)
{
cookie_log_state *cls = get_module_config (parms->server->module_config,
***************
*** 177,185 ****
--- 231,308 ----
return NULL;
}
+ char *set_cookie_exp (cmd_parms *parms, void *dummy, char *arg)
+ {
+ cookie_log_state *cls = get_module_config (parms->server->module_config,
+ &cookies_module);
+ time_t factor, modifier = 0;
+ time_t num = 0;
+ char *word;
+
+ /* The simple case first - all numbers (we assume) */
+ if (isdigit(arg[0]) && isdigit(arg[strlen(arg)-1])) {
+ cls->expires = atol(arg);
+ return NULL;
+ }
+
+ /* The harder case - stolen from mod_expires
+ * CookieExpires "[plus] {<num> <type>}*"
+ */
+
+ word = getword_conf( parms->pool, &arg );
+ if ( !strncasecmp( word, "plus", 1 ) ) {
+ word = getword_conf( parms->pool, &arg );
+ };
+
+ /* {<num> <type>}* */
+ while ( word[0] ) {
+ /* <num> */
+ if ( index("0123456789", word[0]) != NULL )
+ num = atoi( word );
+ else
+ return "bad expires code, numeric value expected.";
+
+ /* <type> */
+ word = getword_conf( parms->pool, &arg );
+ if (!word[0] )
+ return "bad expires code, missing <type>";
+
+ factor = 0;
+ if ( !strncasecmp( word, "years", 1 ) )
+ factor = 60*60*24*365;
+ else if ( !strncasecmp( word, "months", 2 ) )
+ factor = 60*60*24*30;
+ else if ( !strncasecmp( word, "weeks", 1 ) )
+ factor = 60*60*24*7;
+ else if ( !strncasecmp( word, "days", 1 ) )
+ factor = 60*60*24;
+ else if ( !strncasecmp( word, "hours", 1 ) )
+ factor = 60*60;
+ else if ( !strncasecmp( word, "minutes", 2 ) )
+ factor = 60;
+ else if ( !strncasecmp( word, "seconds", 1 ) )
+ factor = 1;
+ else
+ return "bad expires code, unrecognized type";
+
+ modifier = modifier + factor * num;
+
+ /* next <num> */
+ word = getword_conf( parms->pool, &arg );
+ }
+
+ cls->expires = modifier;
+
+ return NULL;
+ }
+
command_rec cookie_log_cmds[] = {
{ "CookieLog", set_cookie_log, NULL, RSRC_CONF, TAKE1,
"the filename of the cookie log" },
+ { "CookieExpires", set_cookie_exp, NULL, RSRC_CONF, TAKE1,
+ "an expiry date code" },
+ { "CookieEnable", set_cookie_disable, NULL, OR_FILEINFO, FLAG,
+ "whether or not to enable cookies" },
{ NULL }
};
***************
*** 282,289 ****
module cookies_module = {
STANDARD_MODULE_STUFF,
init_cookie_log, /* initializer */
! NULL, /* dir config creater */
! NULL, /* dir merger --- default is to override */
make_cookie_log_state, /* server config */
NULL, /* merge server configs */
cookie_log_cmds, /* command table */
--- 405,412 ----
module cookies_module = {
STANDARD_MODULE_STUFF,
init_cookie_log, /* initializer */
! make_cookie_dir, /* dir config creater */
! NULL, /* dir merger --- default is to override */
make_cookie_log_state, /* server config */
NULL, /* merge server configs */
cookie_log_cmds, /* command table */
-- Alexei Kosut <ak...@organic.com> The Apache HTTP Server
http://www.nueva.pvt.k12.ca.us/~akosut/ http://www.apache.org/
Re: cookies patch
Posted by Brian Behlendorf <br...@organic.com>.
+1, by the way. :) We've found these highly demanded by clients.
Brian
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
brian@organic.com www.apache.org hyperreal.com http://www.organic.com/JOBS