comparison src/http/ngx_http_upstream.c @ 9305:8cdab3d89c44

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.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 18 Jul 2024 19:39:39 +0300
parents c5623963c29e
children e46e1ea89ccd
comparison
equal deleted inserted replaced
9304:f209bf590e84 9305:8cdab3d89c44
134 static ngx_int_t 134 static ngx_int_t
135 ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r, 135 ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r,
136 ngx_table_elt_t *h, ngx_uint_t offset); 136 ngx_table_elt_t *h, ngx_uint_t offset);
137 static ngx_int_t ngx_http_upstream_process_vary(ngx_http_request_t *r, 137 static ngx_int_t ngx_http_upstream_process_vary(ngx_http_request_t *r,
138 ngx_table_elt_t *h, ngx_uint_t offset); 138 ngx_table_elt_t *h, ngx_uint_t offset);
139 static ngx_int_t ngx_http_upstream_process_age(ngx_http_request_t *r,
140 ngx_table_elt_t *h, ngx_uint_t offset);
139 static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, 141 static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r,
140 ngx_table_elt_t *h, ngx_uint_t offset); 142 ngx_table_elt_t *h, ngx_uint_t offset);
141 static ngx_int_t 143 static ngx_int_t
142 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, 144 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
143 ngx_table_elt_t *h, ngx_uint_t offset); 145 ngx_table_elt_t *h, ngx_uint_t offset);
291 { ngx_string("Link"), 293 { ngx_string("Link"),
292 ngx_http_upstream_ignore_header_line, 0, 294 ngx_http_upstream_ignore_header_line, 0,
293 ngx_http_upstream_copy_multi_header_lines, 295 ngx_http_upstream_copy_multi_header_lines,
294 offsetof(ngx_http_headers_out_t, link), 0 }, 296 offsetof(ngx_http_headers_out_t, link), 0 },
295 297
298 { ngx_string("Age"),
299 ngx_http_upstream_process_age, 0,
300 ngx_http_upstream_copy_header_line, 0, 0 },
301
296 { ngx_string("X-Accel-Expires"), 302 { ngx_string("X-Accel-Expires"),
297 ngx_http_upstream_process_accel_expires, 0, 303 ngx_http_upstream_process_accel_expires, 0,
298 ngx_http_upstream_copy_header_line, 0, 0 }, 304 ngx_http_upstream_copy_header_line, 0, 0 },
299 305
300 { ngx_string("X-Accel-Redirect"), 306 { ngx_string("X-Accel-Redirect"),
473 { ngx_string("X-Accel-Charset"), NGX_HTTP_UPSTREAM_IGN_XA_CHARSET }, 479 { ngx_string("X-Accel-Charset"), NGX_HTTP_UPSTREAM_IGN_XA_CHARSET },
474 { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES }, 480 { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES },
475 { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL }, 481 { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
476 { ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE }, 482 { ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
477 { ngx_string("Vary"), NGX_HTTP_UPSTREAM_IGN_VARY }, 483 { ngx_string("Vary"), NGX_HTTP_UPSTREAM_IGN_VARY },
484 { ngx_string("Age"), NGX_HTTP_UPSTREAM_IGN_AGE },
478 { ngx_null_string, 0 } 485 { ngx_null_string, 0 }
479 }; 486 };
480 487
481 488
482 ngx_int_t 489 ngx_int_t
4937 4944
4938 u->cacheable = 0; 4945 u->cacheable = 0;
4939 return NGX_OK; 4946 return NGX_OK;
4940 } 4947 }
4941 4948
4942 if (n == 0) { 4949 if (n <= u->headers_in.age_n) {
4943 u->headers_in.no_cache = 1; 4950 u->headers_in.no_cache = 1;
4944 return NGX_OK; 4951 return NGX_OK;
4945 } 4952 }
4946 4953
4947 r->cache->valid_sec = ngx_time() + n; 4954 r->cache->valid_sec = ngx_time() + n - u->headers_in.age_n;
4948 u->headers_in.expired = 0; 4955 u->headers_in.expired = 0;
4956 u->headers_in.max_age = 1;
4949 } 4957 }
4950 4958
4951 extensions: 4959 extensions:
4952 4960
4953 p = ngx_strlcasestrn(start, last, (u_char *) "stale-while-revalidate=", 4961 p = ngx_strlcasestrn(start, last, (u_char *) "stale-while-revalidate=",
5107 5115
5108 default: 5116 default:
5109 r->cache->valid_sec = ngx_time() + n; 5117 r->cache->valid_sec = ngx_time() + n;
5110 u->headers_in.no_cache = 0; 5118 u->headers_in.no_cache = 0;
5111 u->headers_in.expired = 0; 5119 u->headers_in.expired = 0;
5120 u->headers_in.max_age = 0;
5112 return NGX_OK; 5121 return NGX_OK;
5113 } 5122 }
5114 } 5123 }
5115 5124
5116 p++; 5125 p++;
5120 5129
5121 if (n != NGX_ERROR) { 5130 if (n != NGX_ERROR) {
5122 r->cache->valid_sec = n; 5131 r->cache->valid_sec = n;
5123 u->headers_in.no_cache = 0; 5132 u->headers_in.no_cache = 0;
5124 u->headers_in.expired = 0; 5133 u->headers_in.expired = 0;
5134 u->headers_in.max_age = 0;
5125 } 5135 }
5126 } 5136 }
5127 #endif 5137 #endif
5128 5138
5129 return NGX_OK; 5139 return NGX_OK;
5363 if (vary.len > NGX_HTTP_CACHE_VARY_LEN) { 5373 if (vary.len > NGX_HTTP_CACHE_VARY_LEN) {
5364 u->cacheable = 0; 5374 u->cacheable = 0;
5365 } 5375 }
5366 5376
5367 r->cache->vary = vary; 5377 r->cache->vary = vary;
5378 }
5379 #endif
5380
5381 return NGX_OK;
5382 }
5383
5384
5385 static ngx_int_t
5386 ngx_http_upstream_process_age(ngx_http_request_t *r,
5387 ngx_table_elt_t *h, ngx_uint_t offset)
5388 {
5389 ngx_http_upstream_t *u;
5390
5391 u = r->upstream;
5392
5393 if (u->headers_in.age) {
5394 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
5395 "upstream sent duplicate header line: \"%V: %V\", "
5396 "previous value: \"%V: %V\", ignored",
5397 &h->key, &h->value,
5398 &u->headers_in.age->key,
5399 &u->headers_in.age->value);
5400 h->hash = 0;
5401 return NGX_OK;
5402 }
5403
5404 u->headers_in.age = h;
5405 h->next = NULL;
5406
5407 #if (NGX_HTTP_CACHE)
5408 {
5409 ngx_int_t n;
5410
5411 if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_AGE) {
5412 return NGX_OK;
5413 }
5414
5415 if (r->cache == NULL || !u->cacheable) {
5416 return NGX_OK;
5417 }
5418
5419 n = ngx_atoi(h->value.data, h->value.len);
5420
5421 if (n != NGX_ERROR) {
5422 u->headers_in.age_n = n;
5423
5424 if (u->headers_in.max_age) {
5425 if (n >= r->cache->valid_sec - ngx_time()) {
5426 u->headers_in.no_cache = 1;
5427 return NGX_OK;
5428 }
5429
5430 r->cache->valid_sec -= n;
5431 }
5432 }
5368 } 5433 }
5369 #endif 5434 #endif
5370 5435
5371 return NGX_OK; 5436 return NGX_OK;
5372 } 5437 }