[nginx] Upstream: using the "Age" header when caching responses.
Maxim Dounin
mdounin at mdounin.ru
Thu Jul 18 20:43:59 UTC 2024
details: http://freenginx.org/hg/nginx/rev/8cdab3d89c44
branches:
changeset: 9305:8cdab3d89c44
user: Maxim Dounin <mdounin at mdounin.ru>
date: Thu Jul 18 19:39:39 2024 +0300
description:
Upstream: using the "Age" header when caching responses.
As long as the "Age" header is present and not ignored, it is now
respected when caching responses per "Cache-Control: max-age", reducing
cache validity time.
diffstat:
src/http/ngx_http_upstream.c | 69 ++++++++++++++++++++++++++++++++++++++++++-
src/http/ngx_http_upstream.h | 4 ++
2 files changed, 71 insertions(+), 2 deletions(-)
diffs (155 lines):
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -136,6 +136,8 @@ static ngx_int_t
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_process_vary(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_upstream_process_age(ngx_http_request_t *r,
+ ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t
@@ -293,6 +295,10 @@ static ngx_http_upstream_header_t ngx_h
ngx_http_upstream_copy_multi_header_lines,
offsetof(ngx_http_headers_out_t, link), 0 },
+ { ngx_string("Age"),
+ ngx_http_upstream_process_age, 0,
+ ngx_http_upstream_copy_header_line, 0, 0 },
+
{ ngx_string("X-Accel-Expires"),
ngx_http_upstream_process_accel_expires, 0,
ngx_http_upstream_copy_header_line, 0, 0 },
@@ -475,6 +481,7 @@ ngx_conf_bitmask_t ngx_http_upstream_ig
{ ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
{ ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
{ ngx_string("Vary"), NGX_HTTP_UPSTREAM_IGN_VARY },
+ { ngx_string("Age"), NGX_HTTP_UPSTREAM_IGN_AGE },
{ ngx_null_string, 0 }
};
@@ -4939,13 +4946,14 @@ ngx_http_upstream_process_cache_control(
return NGX_OK;
}
- if (n == 0) {
+ if (n <= u->headers_in.age_n) {
u->headers_in.no_cache = 1;
return NGX_OK;
}
- r->cache->valid_sec = ngx_time() + n;
+ r->cache->valid_sec = ngx_time() + n - u->headers_in.age_n;
u->headers_in.expired = 0;
+ u->headers_in.max_age = 1;
}
extensions:
@@ -5109,6 +5117,7 @@ ngx_http_upstream_process_accel_expires(
r->cache->valid_sec = ngx_time() + n;
u->headers_in.no_cache = 0;
u->headers_in.expired = 0;
+ u->headers_in.max_age = 0;
return NGX_OK;
}
}
@@ -5122,6 +5131,7 @@ ngx_http_upstream_process_accel_expires(
r->cache->valid_sec = n;
u->headers_in.no_cache = 0;
u->headers_in.expired = 0;
+ u->headers_in.max_age = 0;
}
}
#endif
@@ -5373,6 +5383,61 @@ ngx_http_upstream_process_vary(ngx_http_
static ngx_int_t
+ngx_http_upstream_process_age(ngx_http_request_t *r,
+ ngx_table_elt_t *h, ngx_uint_t offset)
+{
+ ngx_http_upstream_t *u;
+
+ u = r->upstream;
+
+ if (u->headers_in.age) {
+ ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
+ "upstream sent duplicate header line: \"%V: %V\", "
+ "previous value: \"%V: %V\", ignored",
+ &h->key, &h->value,
+ &u->headers_in.age->key,
+ &u->headers_in.age->value);
+ h->hash = 0;
+ return NGX_OK;
+ }
+
+ u->headers_in.age = h;
+ h->next = NULL;
+
+#if (NGX_HTTP_CACHE)
+ {
+ ngx_int_t n;
+
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_AGE) {
+ return NGX_OK;
+ }
+
+ if (r->cache == NULL || !u->cacheable) {
+ return NGX_OK;
+ }
+
+ n = ngx_atoi(h->value.data, h->value.len);
+
+ if (n != NGX_ERROR) {
+ u->headers_in.age_n = n;
+
+ if (u->headers_in.max_age) {
+ if (n >= r->cache->valid_sec - ngx_time()) {
+ u->headers_in.no_cache = 1;
+ return NGX_OK;
+ }
+
+ r->cache->valid_sec -= n;
+ }
+ }
+ }
+#endif
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -54,6 +54,7 @@
#define NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING 0x00000080
#define NGX_HTTP_UPSTREAM_IGN_XA_CHARSET 0x00000100
#define NGX_HTTP_UPSTREAM_IGN_VARY 0x00000200
+#define NGX_HTTP_UPSTREAM_IGN_AGE 0x00000400
typedef struct {
@@ -287,14 +288,17 @@ typedef struct {
ngx_table_elt_t *cache_control;
ngx_table_elt_t *set_cookie;
+ ngx_table_elt_t *age;
off_t content_length_n;
time_t last_modified_time;
+ time_t age_n;
unsigned connection_close:1;
unsigned chunked:1;
unsigned no_cache:1;
unsigned expired:1;
+ unsigned max_age:1;
} ngx_http_upstream_headers_in_t;
More information about the nginx-devel
mailing list