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)