[nginx] Headers filter: variables support in expires (ticket #113).
Maxim Dounin
mdounin at mdounin.ru
Thu Dec 11 20:43:02 UTC 2014
details: http://hg.nginx.org/nginx/rev/4983f7d18fe3
branches:
changeset: 5942:4983f7d18fe3
user: Maxim Dounin <mdounin at mdounin.ru>
date: Thu Dec 11 23:42:11 2014 +0300
description:
Headers filter: variables support in expires (ticket #113).
diffstat:
src/http/modules/ngx_http_headers_filter_module.c | 180 +++++++++++++++------
1 files changed, 127 insertions(+), 53 deletions(-)
diffs (259 lines):
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -44,14 +44,17 @@ typedef enum {
typedef struct {
- ngx_http_expires_t expires;
- time_t expires_time;
- ngx_array_t *headers;
+ ngx_http_expires_t expires;
+ time_t expires_time;
+ ngx_http_complex_value_t *expires_value;
+ ngx_array_t *headers;
} ngx_http_headers_conf_t;
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_parse_expires(ngx_str_t *value,
+ ngx_http_expires_t *expires, time_t *expires_time, char **err);
static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r,
ngx_http_header_val_t *hv, ngx_str_t *value);
static ngx_int_t ngx_http_add_header(ngx_http_request_t *r,
@@ -209,8 +212,11 @@ ngx_http_headers_filter(ngx_http_request
static ngx_int_t
ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
{
+ char *err;
size_t len;
time_t now, expires_time, max_age;
+ ngx_str_t value;
+ ngx_int_t rc;
ngx_uint_t i;
ngx_table_elt_t *e, *cc, **ccp;
ngx_http_expires_t expires;
@@ -218,6 +224,23 @@ ngx_http_set_expires(ngx_http_request_t
expires = conf->expires;
expires_time = conf->expires_time;
+ if (conf->expires_value != NULL) {
+
+ if (ngx_http_complex_value(r, conf->expires_value, &value) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ rc = ngx_http_parse_expires(&value, &expires, &expires_time, &err);
+
+ if (rc != NGX_OK) {
+ return NGX_OK;
+ }
+
+ if (expires == NGX_HTTP_EXPIRES_OFF) {
+ return NGX_OK;
+ }
+ }
+
e = r->headers_out.expires;
if (e == NULL) {
@@ -332,6 +355,78 @@ ngx_http_set_expires(ngx_http_request_t
static ngx_int_t
+ngx_http_parse_expires(ngx_str_t *value, ngx_http_expires_t *expires,
+ time_t *expires_time, char **err)
+{
+ ngx_uint_t minus;
+
+ if (*expires != NGX_HTTP_EXPIRES_MODIFIED) {
+
+ if (value->len == 5 && ngx_strncmp(value->data, "epoch", 5) == 0) {
+ *expires = NGX_HTTP_EXPIRES_EPOCH;
+ return NGX_OK;
+ }
+
+ if (value->len == 3 && ngx_strncmp(value->data, "max", 3) == 0) {
+ *expires = NGX_HTTP_EXPIRES_MAX;
+ return NGX_OK;
+ }
+
+ if (value->len == 3 && ngx_strncmp(value->data, "off", 3) == 0) {
+ *expires = NGX_HTTP_EXPIRES_OFF;
+ return NGX_OK;
+ }
+ }
+
+ if (value->data[0] == '@') {
+ value->data++;
+ value->len--;
+ minus = 0;
+
+ if (*expires == NGX_HTTP_EXPIRES_MODIFIED) {
+ *err = "daily time cannot be used with \"modified\" parameter";
+ return NGX_ERROR;
+ }
+
+ *expires = NGX_HTTP_EXPIRES_DAILY;
+
+ } else if (value->data[0] == '+') {
+ value->data++;
+ value->len--;
+ minus = 0;
+
+ } else if (value->data[0] == '-') {
+ value->data++;
+ value->len--;
+ minus = 1;
+
+ } else {
+ minus = 0;
+ }
+
+ *expires_time = ngx_parse_time(value, 1);
+
+ if (*expires_time == (time_t) NGX_ERROR) {
+ *err = "invalid value";
+ return NGX_ERROR;
+ }
+
+ if (*expires == NGX_HTTP_EXPIRES_DAILY
+ && *expires_time > 24 * 60 * 60)
+ {
+ *err = "daily time value must be less than 24 hours";
+ return NGX_ERROR;
+ }
+
+ if (minus) {
+ *expires_time = - *expires_time;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
ngx_str_t *value)
{
@@ -461,6 +556,7 @@ ngx_http_headers_create_conf(ngx_conf_t
*
* conf->headers = NULL;
* conf->expires_time = 0;
+ * conf->expires_value = NULL;
*/
conf->expires = NGX_HTTP_EXPIRES_UNSET;
@@ -478,6 +574,7 @@ ngx_http_headers_merge_conf(ngx_conf_t *
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
conf->expires = prev->expires;
conf->expires_time = prev->expires_time;
+ conf->expires_value = prev->expires_value;
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
conf->expires = NGX_HTTP_EXPIRES_OFF;
@@ -507,8 +604,12 @@ ngx_http_headers_expires(ngx_conf_t *cf,
{
ngx_http_headers_conf_t *hcf = conf;
- ngx_uint_t minus, n;
- ngx_str_t *value;
+ char *err;
+ ngx_str_t *value;
+ ngx_int_t rc;
+ ngx_uint_t n;
+ ngx_http_complex_value_t cv;
+ ngx_http_compile_complex_value_t ccv;
if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) {
return "is duplicate";
@@ -518,21 +619,6 @@ ngx_http_headers_expires(ngx_conf_t *cf,
if (cf->args->nelts == 2) {
- if (ngx_strcmp(value[1].data, "epoch") == 0) {
- hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
- 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;
@@ -548,45 +634,33 @@ ngx_http_headers_expires(ngx_conf_t *cf,
n = 2;
}
- if (value[n].data[0] == '@') {
- value[n].data++;
- value[n].len--;
- minus = 0;
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- if (hcf->expires == NGX_HTTP_EXPIRES_MODIFIED) {
- return "daily time cannot be used with \"modified\" parameter";
+ ccv.cf = cf;
+ ccv.value = &value[n];
+ ccv.complex_value = &cv;
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths != NULL) {
+
+ hcf->expires_value = ngx_palloc(cf->pool,
+ sizeof(ngx_http_complex_value_t));
+ if (hcf->expires_value == NULL) {
+ return NGX_CONF_ERROR;
}
- hcf->expires = NGX_HTTP_EXPIRES_DAILY;
+ *hcf->expires_value = cv;
- } else if (value[n].data[0] == '+') {
- value[n].data++;
- value[n].len--;
- minus = 0;
-
- } else if (value[n].data[0] == '-') {
- value[n].data++;
- value[n].len--;
- minus = 1;
-
- } else {
- minus = 0;
+ return NGX_CONF_OK;
}
- hcf->expires_time = ngx_parse_time(&value[n], 1);
-
- if (hcf->expires_time == (time_t) NGX_ERROR) {
- return "invalid value";
- }
-
- if (hcf->expires == NGX_HTTP_EXPIRES_DAILY
- && hcf->expires_time > 24 * 60 * 60)
- {
- return "daily time value must be less than 24 hours";
- }
-
- if (minus) {
- hcf->expires_time = - hcf->expires_time;
+ rc = ngx_http_parse_expires(&value[n], &hcf->expires, &hcf->expires_time,
+ &err);
+ if (rc != NGX_OK) {
+ return err;
}
return NGX_CONF_OK;
More information about the nginx-devel
mailing list