ASF Bugzilla – Attachment 19824 Details for
Bug 41963
PATCH: Enhancement to mod_expires to allow "expire in X seconds if file is at least Y seconds old"
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to implement the mod_expires enhancement
d (text/plain), 6.18 KB, created by
Jeffrey Friedl
on 2007-03-27 23:56:38 UTC
(
hide
)
Description:
Patch to implement the mod_expires enhancement
Filename:
MIME Type:
Creator:
Jeffrey Friedl
Created:
2007-03-27 23:56:38 UTC
Size:
6.18 KB
patch
obsolete
>--- mod_expires.c.ORIG 2006-07-12 01:16:05.000000000 -0700 >+++ mod_expires.c 2007-03-27 23:39:37.000000000 -0700 >@@ -115,6 +115,23 @@ > * ExpiresByType text/html "access plus 1 month 15 days 2 hours" > * ExpiresByType image/gif "modification plus 5 hours 3 minutes" > * >+ * Finally, there is a special form for differing expiration times based >+ * on the age of the file, as in this example: >+ * >+ * ExpiresByType image/jpg "aged 2 days then 10 years else 1 hour" >+ * >+ * This means that JPG image files who last modification time was two days >+ * ago or more, are served with an expires time 10 years from the current >+ * access time, while those image files that are less than 2 days old are >+ * served with an expire time 1 hour from the current access time. >+ * >+ * The form is "aged <timespan> then <timespan> [else <timespan>]" >+ * >+ * The "else...." clause can be omitted, which means that files newer than >+ * the threshold time are not given an expires header. >+ * >+ * This form may also be used for ExpiresDefault. >+ * > * --- > * > * Change-log: >@@ -139,6 +156,7 @@ > * the table_get check and then looking for an ExpiresDefault. > * [Rob Hartill] > * 04.Nov.96 'const' definitions added. >+ * 27.Mar.07 added the 'aged' form > * > * TODO > * add support for Cache-Control: max-age=20 from the HTTP/1.1 >@@ -194,6 +212,9 @@ > return NULL; > } > >+static const char *parse_timespan(pool *p, char *word, const char **code, unsigned int *timespan, const char *end_at); >+ >+ > /* check_code() parse 'code' and return NULL or an error response > * string. If we return NULL then real_code contains code converted > * to the cnnnn format. >@@ -203,8 +224,10 @@ > char *word; > char base = 'X'; > int modifier = 0; >- int num = 0; >- int factor = 0; >+ const char *error; >+ unsigned age; >+ unsigned num1; >+ unsigned num2; > > /* 0.0.4 compatibility? > */ >@@ -213,12 +236,33 @@ > return NULL; > }; > >- /* <base> [plus] {<num> <type>}* >- */ >+ word = ap_getword_conf(p, &code); > >- /* <base> >+ /* aged {<num> <type>}+ then {<num> <type>}+ [else {<num> <type>}+ ] */ >+ if (!strncasecmp(word, "aged", 4)) { >+ error = parse_timespan(p, NULL, &code, &age, "then"); >+ if (error) >+ return error; >+ >+ error = parse_timespan(p, NULL, &code, &num1, "else"); >+ if (error) >+ return error; >+ >+ num2 = 0; >+ if (*code) { >+ error = parse_timespan(p, NULL, &code, &num2, NULL); >+ if (error) >+ return error; >+ } >+ *real_code = ap_psprintf(p, ">%010d %010d %010d", age, num1, num2); >+ >+ /* ap_log_error(APLOG_MARK, APLOG_NOERRNO, NULL, "result[%s]", *real_code); */ >+ return NULL; >+ } >+ >+ >+ /* <base> [plus] {<num> <type>}* > */ >- word = ap_getword_conf(p, &code); > if (!strncasecmp(word, "now", 1) || > !strncasecmp(word, "access", 1)) { > base = 'A'; >@@ -238,8 +282,25 @@ > word = ap_getword_conf(p, &code); > }; > >- /* {<num> <type>}* >- */ >+ error = parse_timespan(p, word, &code, &modifier, NULL); >+ if (error) >+ return error; >+ >+ *real_code = ap_psprintf(p, "%c%d", base, modifier); >+ >+ return NULL; >+} >+ >+static const char *parse_timespan(pool *p, char *word, const char **code, unsigned int *timespan, const char *end_at) >+{ >+ int num = 0; >+ int factor = 0; >+ >+ *timespan = 0; >+ >+ if (!word) >+ word = ap_getword_conf(p, code); >+ > while (word[0]) { > /* <num> > */ >@@ -247,19 +308,15 @@ > num = atoi(word); > } > else { >- return ap_pstrcat(p, "bad expires code, numeric value expected <num> '", >- word, "'", NULL); >+ return ap_pstrcat(p, "bad expires code, numeric value expected <num>, got '", >+ word, "'", NULL); > }; > > /* <type> > */ >- word = ap_getword_conf(p, &code); >- if (word[0]) { >- /* do nothing */ >- } >- else { >+ word = ap_getword_conf(p, code); >+ if (!word[0]) > return ap_pstrcat(p, "bad expires code, missing <type>", NULL); >- }; > > factor = 0; > if (!strncasecmp(word, "years", 1)) { >@@ -288,18 +345,19 @@ > "'", word, "'", NULL); > }; > >- modifier = modifier + factor * num; >+ *timespan += factor * num; > > /* next <num> > */ >- word = ap_getword_conf(p, &code); >- }; >+ word = ap_getword_conf(p, code); > >- *real_code = ap_psprintf(p, "%c%d", base, modifier); >- >- return NULL; >+ if (end_at && !strncasecmp(word, end_at, strlen(end_at))) >+ return(NULL); >+ }; >+ return(NULL); > } > >+ > static const char *set_expiresbytype(cmd_parms *cmd, expires_dir_config * dir_config, char *mime, char *code) > { > char *response, *real_code; >@@ -427,6 +485,35 @@ > base = r->request_time; > additional = atoi(&code[1]); > break; >+ case '>': >+ if (r->finfo.st_mode == 0) { >+ /* file doesn't exist on disk, so we can't do anything based on >+ * modification time. Note that this does _not_ log an error. >+ */ >+ return DECLINED; >+ } >+ >+ /* code is of the form ">0031536000 0031536000 0000003600", where >+ * all numbers are 10 digits long, the first number (starting at >+ * code[1]) is the age threashold. If the file is at least that >+ * many seconds old, the second number (starting at code[12]) is >+ * used as "additional", while if the file is newer than that >+ * threshold, the third number (starting at code[23]) is used as >+ * "additional". */ >+ >+ if (r->request_time - r->finfo.st_mtime >= atoi(&code[1])) >+ additional = atoi(&code[12]); >+ else >+ additional = atoi(&code[23]); >+ >+ /* ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r, "additional = %d", additional); */ >+ >+ if (additional == 0) >+ return DECLINED; >+ else >+ base = r->request_time; >+ break; >+ > default: > /* expecting the add_* routines to be case-hardened this > * is just a reminder that module is beta
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 41963
: 19824