You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Andrew Ford <an...@icarus.demon.co.uk> on 1999/12/05 17:54:14 UTC

[PATCH] absolute expiry times

A client asked me how to specify expiry times absolutely so I patched
mod_expires.c (from Apache 1.3.9) to do that.  The patch is a bit
rough and ready but works for us.  The format for specifying the date
and time is fixed as "YYYY/MM/DD hh:mm:ss" so as to avoid having to
deal with ambiguities.  Also the time must be specified in GMT,
although code to decode a timezone specifier could be added.  The "/"
and ":" characters are optional.

Andrew
-- 
Andrew Ford,  Director       Ford & Mason Ltd           +44 1531 829900 (tel)
A.Ford@ford-mason.co.uk      South Wing, Compton House  +44 1531 829901 (fax)
http://www.ford-mason.co.uk  Compton Green, Redmarley   +44 385 258278 (mobile)
http://www.refcards.com      Gloucester, GL19 3JB, UK   


*** mod_expires.c.orig	Fri Jan  1 19:05:09 1999
--- mod_expires.c	Sat Nov 13 16:34:53 1999
***************
*** 156,164 ****
--- 156,174 ----
   *      ExpiresByType text/html "access plus 1 month 15 days 2 hours"
   *      ExpiresByType image/gif "modification plus 5 hours 3 minutes"
   *
+  * A further alternative is to give an absolute expiry time:
+  *
+  *     ExpiresDefault "on YYYY/MM/DD [[at] HH:MM:SS]*"
+  *     ExpiresByType type/encoding "on YYYY/MM/DD [[at] HH:MM[:SS]]*"
+  *
+  * for example 
+  *
+  *     ExpiresDefault "on 1999/12/31 at 12:59:59"
+  *
   * ---
   *
   * Change-log:
+  * 05.Dec.99    Added absolute date and time syntax
   * 29.Jan.96    Hardened the add_* functions.  Server will now bail out
   *              if bad directives are given in the conf files.
   * 02.Feb.96    Returns DECLINED if not 'ExpiresActive on', giving other
***************
*** 246,251 ****
--- 256,263 ----
      int modifier = 0;
      int num = 0;
      int factor = 0;
+     struct tm tm;
+     int len, dd, mm, ss;
  
      /* 0.0.4 compatibility?
       */
***************
*** 260,265 ****
--- 272,350 ----
      /* <base>
       */
      word = ap_getword_conf(p, &code);
+     if (!strncasecmp(word, "at", 2) ||
+ 	!strncasecmp(word, "on", 1)) {
+         word = ap_getword_conf(p, &code);
+ 	len = strlen(word);
+ 	mm = 4; 
+ 	dd = 6;
+ 	if (len > 8 && (word[mm] == '/' || word[mm] == '-')) {
+ 	    mm++; 
+ 	    dd++;
+ 	}
+ 	if (len > 8 && (word[dd] == '/' || word[dd] == '-')) {
+  	    dd++;
+ 	}
+ 	if (len != dd + 2 ||
+ 	    !isdigit(word[0]) ||
+ 	    !isdigit(word[1]) ||
+ 	    !isdigit(word[2]) ||
+ 	    !isdigit(word[3]) ||
+ 	    !isdigit(word[mm]) ||
+ 	    !isdigit(word[mm+1]) ||
+ 	    !isdigit(word[mm]) ||
+ 	    !isdigit(word[mm+1])) {
+ 	    return ap_pstrcat(p, "bad expires date, '", word, "'", NULL);
+ 	}
+ 	tm.tm_year = (word[0] - '0') * 1000 + (word[1] - '0') * 100
+ 	  + (word[2] - '0') * 10 + (word[3] - '0') - 1900;
+ 	tm.tm_mon  = (word[mm] - '0') * 10 + (word[mm+1] - '0') - 1;
+ 	tm.tm_mday = (word[mm] - '0') * 10 + (word[mm+1] - '0');
+ 
+ 
+ 	/* Check whether a time was specified */
+ 
+ 	word = ap_getword_conf(p, &code);
+ 	if (!strncasecmp(word, "at", 1)) {
+ 	    word = ap_getword_conf(p, &code);
+ 	};
+ 
+ 	if (word[0]) {
+ 	    tm.tm_sec  = 59;
+ 	    len = strlen(word);
+ 	    mm = 2; 
+ 	    ss = 4;
+ 	    if (len > 2 && (word[mm] == ':')) {
+ 	        mm++; 
+ 	        ss++;
+ 	    }
+ 	    if (len > ss && (word[ss] == ':')) {
+ 	        ss++;
+ 	    }
+ 	    if (len != ss + 2 ||
+ 		!isdigit(word[0]) ||
+ 		!isdigit(word[1]) ||
+ 		!isdigit(word[mm]) ||
+ 		!isdigit(word[mm+1]) ||
+ 		!isdigit(word[ss]) ||
+ 		!isdigit(word[ss+1])) {
+ 	        return ap_pstrcat(p, "bad expires time, '", word, "'", NULL);
+ 	    }
+ 	    tm.tm_hour = (word[0]  - '0') * 10 + (word[1] - '0');
+ 	    tm.tm_min  = (word[mm] - '0') * 10 + (word[mm+1] - '0');
+ 	    tm.tm_sec  = (word[ss] - '0') * 10 + (word[ss+1] - '0');
+ 	}
+ 	else {
+ 	    tm.tm_hour = 23;
+ 	    tm.tm_min  = 59;
+ 	    tm.tm_sec  = 59;
+ 	}
+ 
+ 
+ 	*real_code = ap_psprintf(p, "@%d", ap_tm2sec(&tm));
+ 	return NULL;
+     }
+ 
      if (!strncasecmp(word, "now", 1) ||
          !strncasecmp(word, "access", 1)) {
          base = 'A';
***************
*** 467,472 ****
--- 552,563 ----
          base = r->request_time;
          additional = atoi(&code[1]);
          break;
+     case '@':
+         /* the expires time is absolute
+          */
+         base = 0;
+ 	additional = atoi(&code[1]);
+ 	break;
      default:
          /* expecting the add_* routines to be case-hardened this 
           * is just a reminder that module is beta