comparison src/http/ngx_http_upstream.c @ 7514:319242d2ddc9

Upstream: background cache update before cache send (ticket #1782). In case of filter finalization, essential request fields like r->uri, r->args etc could be changed, which affected the cache update subrequest. Also, after filter finalization r->cache could be set to NULL, leading to null pointer dereference in ngx_http_upstream_cache_background_update(). The fix is to create background cache update subrequest before sending the cached response. Since initial introduction in 1aeaae6e9446 (1.11.10) background cache update subrequest was created after sending the cached response because otherwise it blocked the parent request output. In 9552758a786e (1.13.1) background subrequests were introduced to eliminate the delay before sending the final part of the cached response. This also made it possible to create the background cache update subrequest before sending the response. Note that creating the subrequest earlier does not change the fact that in case of filter finalization the background cache update subrequest will likely not have enough time to successfully update the cache entry. Filter finalization leads to the main request termination as soon the current iteration of request processing is complete.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 03 Jun 2019 20:33:26 +0300
parents c19ca381b2e6
children 08ed570ad93c
comparison
equal deleted inserted replaced
7513:d964b0aee8e7 7514:319242d2ddc9
595 r->cached = 0; 595 r->cached = 0;
596 u->buffer.start = NULL; 596 u->buffer.start = NULL;
597 u->cache_status = NGX_HTTP_CACHE_MISS; 597 u->cache_status = NGX_HTTP_CACHE_MISS;
598 u->request_sent = 1; 598 u->request_sent = 1;
599 } 599 }
600
601 if (ngx_http_upstream_cache_background_update(r, u) != NGX_OK) {
602 rc = NGX_ERROR;
603 }
604 } 600 }
605 601
606 if (rc != NGX_DECLINED) { 602 if (rc != NGX_DECLINED) {
607 ngx_http_finalize_request(r, rc); 603 ngx_http_finalize_request(r, rc);
608 return; 604 return;
900 896
901 if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) 897 if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
902 || c->stale_updating) && !r->background 898 || c->stale_updating) && !r->background
903 && u->conf->cache_background_update) 899 && u->conf->cache_background_update)
904 { 900 {
905 r->cache->background = 1; 901 if (ngx_http_upstream_cache_background_update(r, u) == NGX_OK) {
906 u->cache_status = rc; 902 r->cache->background = 1;
907 rc = NGX_OK; 903 u->cache_status = rc;
904 rc = NGX_OK;
905
906 } else {
907 rc = NGX_ERROR;
908 }
908 } 909 }
909 910
910 break; 911 break;
911 912
912 case NGX_HTTP_CACHE_UPDATING: 913 case NGX_HTTP_CACHE_UPDATING:
1103 static ngx_int_t 1104 static ngx_int_t
1104 ngx_http_upstream_cache_background_update(ngx_http_request_t *r, 1105 ngx_http_upstream_cache_background_update(ngx_http_request_t *r,
1105 ngx_http_upstream_t *u) 1106 ngx_http_upstream_t *u)
1106 { 1107 {
1107 ngx_http_request_t *sr; 1108 ngx_http_request_t *sr;
1108
1109 if (!r->cached || !r->cache->background) {
1110 return NGX_OK;
1111 }
1112 1109
1113 if (r == r->main) { 1110 if (r == r->main) {
1114 r->preserve_body = 1; 1111 r->preserve_body = 1;
1115 } 1112 }
1116 1113