Mercurial > hg > nginx
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 } |