Expires: modified +1d?
Igor Sysoev
is at rambler-co.ru
Thu May 15 15:26:16 MSD 2008
On Thu, May 15, 2008 at 03:23:20PM +0400, Igor Sysoev wrote:
> On Thu, May 15, 2008 at 10:26:36AM +0100, Phillip B Oldham wrote:
>
> > Is it possible to set the expires header based on the modified time of a
> > file? I know you can do this in lighttpd and apache, but I can't find
> > any configuration examples for nginx.
>
> Try the attached patch.
>
> It allows
>
> expires modified +1d;
The patch itself.
--
Igor Sysoev
http://sysoev.ru/en/
-------------- next part --------------
Index: src/http/modules/ngx_http_headers_filter_module.c
===================================================================
--- src/http/modules/ngx_http_headers_filter_module.c (revision 1326)
+++ src/http/modules/ngx_http_headers_filter_module.c (working copy)
@@ -31,18 +31,20 @@
};
+#define NGX_HTTP_EXPIRES_OFF 0
+#define NGX_HTTP_EXPIRES_EPOCH 1
+#define NGX_HTTP_EXPIRES_MAX 2
+#define NGX_HTTP_EXPIRES_ACCESS 3
+#define NGX_HTTP_EXPIRES_MODIFIED 4
+
+
typedef struct {
- time_t expires;
+ ngx_uint_t expires;
+ time_t expires_time;
ngx_array_t *headers;
} ngx_http_headers_conf_t;
-#define NGX_HTTP_EXPIRES_UNSET -2147483647
-#define NGX_HTTP_EXPIRES_OFF -2147483646
-#define NGX_HTTP_EXPIRES_EPOCH -2147483645
-#define NGX_HTTP_EXPIRES_MAX -2147483644
-
-
static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r,
ngx_http_headers_conf_t *conf);
static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r,
@@ -76,7 +78,7 @@
{ ngx_string("expires"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE1,
+ |NGX_CONF_TAKE12,
ngx_http_headers_expires,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@@ -185,6 +187,7 @@
ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
{
size_t len;
+ time_t since;
ngx_uint_t i;
ngx_table_elt_t *expires, *cc, **ccp;
@@ -266,7 +269,7 @@
return NGX_ERROR;
}
- if (conf->expires == 0) {
+ if (conf->expires_time == 0) {
ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
ngx_cached_http_time.len + 1);
@@ -276,9 +279,20 @@
return NGX_OK;
}
- ngx_http_time(expires->value.data, ngx_time() + conf->expires);
+ if (conf->expires == NGX_HTTP_EXPIRES_MODIFIED) {
+ since = r->headers_out.last_modified_time;
- if (conf->expires < 0) {
+ if (since == -1) {
+ since = ngx_time();
+ }
+
+ } else {
+ since = ngx_time();
+ }
+
+ ngx_http_time(expires->value.data, since + conf->expires_time);
+
+ if (conf->expires_time < 0) {
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
@@ -291,7 +305,8 @@
return NGX_ERROR;
}
- cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", conf->expires)
+ cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T",
+ since + conf->expires_time - ngx_time())
- cc->value.data;
return NGX_OK;
@@ -413,9 +428,10 @@
* set by ngx_pcalloc():
*
* conf->headers = NULL;
+ * conf->expires_time = 0;
*/
- conf->expires = NGX_HTTP_EXPIRES_UNSET;
+ conf->expires = NGX_CONF_UNSET_UINT;
return conf;
}
@@ -427,9 +443,13 @@
ngx_http_headers_conf_t *prev = parent;
ngx_http_headers_conf_t *conf = child;
- if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
- conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ?
- NGX_HTTP_EXPIRES_OFF : prev->expires;
+ if (conf->expires == NGX_CONF_UNSET_UINT) {
+ conf->expires = prev->expires;
+ conf->expires_time = prev->expires_time;
+
+ if (conf->expires == NGX_CONF_UNSET_UINT) {
+ conf->expires = NGX_HTTP_EXPIRES_OFF;
+ }
}
if (conf->headers == NULL) {
@@ -455,56 +475,73 @@
{
ngx_http_headers_conf_t *hcf = conf;
- ngx_uint_t minus;
+ ngx_uint_t minus, n;
ngx_str_t *value;
- if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) {
+ if (hcf->expires != NGX_CONF_UNSET_UINT) {
return "is duplicate";
}
value = cf->args->elts;
- if (ngx_strcmp(value[1].data, "epoch") == 0) {
- hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
- return NGX_CONF_OK;
- }
+ if (cf->args->nelts == 2) {
- if (ngx_strcmp(value[1].data, "max") == 0) {
- hcf->expires = NGX_HTTP_EXPIRES_MAX;
- return NGX_CONF_OK;
- }
+ if (ngx_strcmp(value[1].data, "epoch") == 0) {
+ hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
+ return NGX_CONF_OK;
+ }
- if (ngx_strcmp(value[1].data, "off") == 0) {
- hcf->expires = NGX_HTTP_EXPIRES_OFF;
- return NGX_CONF_OK;
+ if (ngx_strcmp(value[1].data, "max") == 0) {
+ hcf->expires = NGX_HTTP_EXPIRES_MAX;
+ return NGX_CONF_OK;
+ }
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ hcf->expires = NGX_HTTP_EXPIRES_OFF;
+ return NGX_CONF_OK;
+ }
+
+ hcf->expires = NGX_HTTP_EXPIRES_ACCESS;
+
+ n = 1;
+
+ } else { /* cf->args->nelts == 3 */
+
+ if (ngx_strcmp(value[1].data, "modified") != 0) {
+ return "invalid value";
+ }
+
+ hcf->expires = NGX_HTTP_EXPIRES_MODIFIED;
+
+ n = 2;
}
- if (value[1].data[0] == '+') {
- value[1].data++;
- value[1].len--;
+ if (value[n].data[0] == '+') {
+ value[n].data++;
+ value[n].len--;
minus = 0;
- } else if (value[1].data[0] == '-') {
- value[1].data++;
- value[1].len--;
+ } else if (value[n].data[0] == '-') {
+ value[n].data++;
+ value[n].len--;
minus = 1;
} else {
minus = 0;
}
- hcf->expires = ngx_parse_time(&value[1], 1);
+ hcf->expires_time = ngx_parse_time(&value[n], 1);
- if (hcf->expires == NGX_ERROR) {
+ if (hcf->expires_time == NGX_ERROR) {
return "invalid value";
}
- if (hcf->expires == NGX_PARSE_LARGE_TIME) {
+ if (hcf->expires_time == NGX_PARSE_LARGE_TIME) {
return "value must be less than 68 years";
}
if (minus) {
- hcf->expires = - hcf->expires;
+ hcf->expires_time = - hcf->expires_time;
}
return NGX_CONF_OK;
More information about the nginx
mailing list