Mercurial > hg > nginx
comparison src/http/ngx_http_upstream.c @ 9306:e46e1ea89ccd
Upstream: $upstream_cache_age variable.
The variable reflects response age, including the time spent in the
cache and the upstream response age as obtained from the "Age" header.
If the response wasn't cached, the variable reflects the "Age" header
of the upstream response.
If the intended use case is to cache responses as per HTTP/1.1 caching
model, the $upstream_cache_age variable can be used to provide the "Age"
header with the "add_header" directive, such as:
add_header Age $upstream_cache_age;
This now removes the "Age" header if it was present.
Further, the "expires" directives now removes the "Age" header if it
was present in the response, as the "expires" directive assumes zero
age when it adds "Expires" and "Cache-Control" headers.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 18 Jul 2024 19:39:45 +0300 |
parents | 8cdab3d89c44 |
children |
comparison
equal
deleted
inserted
replaced
9305:8cdab3d89c44 | 9306:e46e1ea89ccd |
---|---|
28 static ngx_int_t ngx_http_upstream_cache_key(ngx_http_request_t *r, | 28 static ngx_int_t ngx_http_upstream_cache_key(ngx_http_request_t *r, |
29 ngx_http_variable_value_t *v, uintptr_t data); | 29 ngx_http_variable_value_t *v, uintptr_t data); |
30 static ngx_int_t ngx_http_upstream_cache_last_modified(ngx_http_request_t *r, | 30 static ngx_int_t ngx_http_upstream_cache_last_modified(ngx_http_request_t *r, |
31 ngx_http_variable_value_t *v, uintptr_t data); | 31 ngx_http_variable_value_t *v, uintptr_t data); |
32 static ngx_int_t ngx_http_upstream_cache_etag(ngx_http_request_t *r, | 32 static ngx_int_t ngx_http_upstream_cache_etag(ngx_http_request_t *r, |
33 ngx_http_variable_value_t *v, uintptr_t data); | |
34 static ngx_int_t ngx_http_upstream_cache_age(ngx_http_request_t *r, | |
33 ngx_http_variable_value_t *v, uintptr_t data); | 35 ngx_http_variable_value_t *v, uintptr_t data); |
34 #endif | 36 #endif |
35 | 37 |
36 static void ngx_http_upstream_init_request(ngx_http_request_t *r); | 38 static void ngx_http_upstream_init_request(ngx_http_request_t *r); |
37 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); | 39 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); |
295 ngx_http_upstream_copy_multi_header_lines, | 297 ngx_http_upstream_copy_multi_header_lines, |
296 offsetof(ngx_http_headers_out_t, link), 0 }, | 298 offsetof(ngx_http_headers_out_t, link), 0 }, |
297 | 299 |
298 { ngx_string("Age"), | 300 { ngx_string("Age"), |
299 ngx_http_upstream_process_age, 0, | 301 ngx_http_upstream_process_age, 0, |
300 ngx_http_upstream_copy_header_line, 0, 0 }, | 302 ngx_http_upstream_copy_header_line, |
303 offsetof(ngx_http_headers_out_t, age), 0 }, | |
301 | 304 |
302 { ngx_string("X-Accel-Expires"), | 305 { ngx_string("X-Accel-Expires"), |
303 ngx_http_upstream_process_accel_expires, 0, | 306 ngx_http_upstream_process_accel_expires, 0, |
304 ngx_http_upstream_copy_header_line, 0, 0 }, | 307 ngx_http_upstream_copy_header_line, 0, 0 }, |
305 | 308 |
434 | 437 |
435 { ngx_string("upstream_cache_etag"), NULL, | 438 { ngx_string("upstream_cache_etag"), NULL, |
436 ngx_http_upstream_cache_etag, 0, | 439 ngx_http_upstream_cache_etag, 0, |
437 NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, | 440 NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, |
438 | 441 |
442 { ngx_string("upstream_cache_age"), NULL, | |
443 ngx_http_upstream_cache_age, 0, | |
444 NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, | |
445 | |
439 #endif | 446 #endif |
440 | 447 |
441 { ngx_string("upstream_http_"), NULL, ngx_http_upstream_header_variable, | 448 { ngx_string("upstream_http_"), NULL, ngx_http_upstream_header_variable, |
442 0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 }, | 449 0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 }, |
443 | 450 |
6209 v->data = r->cache->etag.data; | 6216 v->data = r->cache->etag.data; |
6210 | 6217 |
6211 return NGX_OK; | 6218 return NGX_OK; |
6212 } | 6219 } |
6213 | 6220 |
6221 | |
6222 static ngx_int_t | |
6223 ngx_http_upstream_cache_age(ngx_http_request_t *r, | |
6224 ngx_http_variable_value_t *v, uintptr_t data) | |
6225 { | |
6226 u_char *p; | |
6227 time_t now, age; | |
6228 | |
6229 if (r->upstream == NULL) { | |
6230 v->not_found = 1; | |
6231 return NGX_OK; | |
6232 } | |
6233 | |
6234 if (!r->cached | |
6235 || r->cache == NULL | |
6236 || r->upstream->cache_status == NGX_HTTP_CACHE_REVALIDATED) | |
6237 { | |
6238 if (r->upstream->headers_in.age == NULL) { | |
6239 v->not_found = 1; | |
6240 return NGX_OK; | |
6241 } | |
6242 | |
6243 v->valid = 1; | |
6244 v->no_cacheable = 0; | |
6245 v->not_found = 0; | |
6246 v->len = r->upstream->headers_in.age->value.len; | |
6247 v->data = r->upstream->headers_in.age->value.data; | |
6248 | |
6249 return NGX_OK; | |
6250 } | |
6251 | |
6252 p = ngx_pnalloc(r->pool, NGX_TIME_T_LEN); | |
6253 if (p == NULL) { | |
6254 return NGX_ERROR; | |
6255 } | |
6256 | |
6257 now = ngx_time(); | |
6258 age = now - r->cache->date; | |
6259 | |
6260 if (r->cache->date > now) { | |
6261 age = 0; | |
6262 } | |
6263 | |
6264 age += r->upstream->headers_in.age_n; | |
6265 | |
6266 v->len = ngx_sprintf(p, "%T", age) - p; | |
6267 v->valid = 1; | |
6268 v->no_cacheable = 0; | |
6269 v->not_found = 0; | |
6270 v->data = p; | |
6271 | |
6272 return NGX_OK; | |
6273 } | |
6274 | |
6214 #endif | 6275 #endif |
6215 | 6276 |
6216 | 6277 |
6217 static char * | 6278 static char * |
6218 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | 6279 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) |