########################################################################################## JILS-42: Last-Modified isn't updated if a Project Description changes ########################################################################################## Issue Type: Bug ----------------------------------------------------------------------------------------- Issue Information ==================== Priority: Major Status: Closed Resolution: Fixed (2018-01-05 08:39:50) Project: Jira Issue Listing Script (JILS) Reported By: btasker Assigned To: btasker Affected Versions: - 0.1 - 0.01b Targeted for fix in version: - 0.1 Labels: Caching, Time Estimate: 65 minutes Time Logged: 55 minutes ----------------------------------------------------------------------------------------- Issue Description ================== JILS-41 introduced support for two new response headers - E-Tag - Last-Modified And for two new request headers - If-None-Match - If-Modified-Since Unfortunately on Project Index pages (also Component and Version indexes), whilst the E-Tag will update if Project properties (description, name, url etc) change, the Last-Modified date doesn't. This is an issue, because some downstream caches (NGinx being one) only use If-Modified-Since when revalidating. So although the page content has changed, the page will revalidate. There isn't actually a good way to get around this, as JIRA doesn't keep a log of when project/version/component properties were changed. So there isn't a date in the database we can extract to identify the most recent change (unless an issue has changed, then we can use that). ----------------------------------------------------------------------------------------- Issue Relations ================ - Discovered In JILS-41: Add support for downstream re-validation - NGinx Configuration Manual (http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_revalidate) - NGinx Ticket 101 (https://trac.nginx.org/nginx/ticket/101) ----------------------------------------------------------------------------------------- Activity ========== ----------------------------------------------------------------------------------------- 2016-04-22 13:44:35 btasker ----------------------------------------------------------------------------------------- Looking at the NGinx configuration options, it seems to imply that If-None-Match is supported. My testbox (nginx/1.8.0) definitely isn't using it, and the NGinx caching guide (https://www.nginx.com/blog/nginx-caching-guide/) says If-Modified-Since will be used. So it's possible If-None-Match support is more recent. Alternatively - Etags aren't currently enabled on that proxy, so perhaps they need to be turned on for it to consider etags when going upstream? ----------------------------------------------------------------------------------------- 2016-04-22 14:31:00 btasker ----------------------------------------------------------------------------------------- Got sidetracked... Simply enabling etags isn't sufficient, as by default NGinx is using HTTP/1.0 to go upstream -- BEGIN SNIPPET -- GET /browse/EXAMPLE-1.html HTTP/1.0 -- END SNIPPET -- E-tags don't exist in 1.0, so need to tell NGinx to use 1.1 when going to the origin -- BEGIN SNIPPET -- proxy_http_version 1.1; -- END SNIPPET -- But even then they don't seem to be used. I'm probabyl missing a config option somewhere, will have a look at the code-base to try and see what (and when it was introduced) ----------------------------------------------------------------------------------------- 2016-04-22 14:39:50 btasker ----------------------------------------------------------------------------------------- Looks like If-None-Match support was introduced in 1.7.3 (see NGinx ticket 101), so should be available on on my install. Looking at the commits against that issue (primarily https://trac.nginx.org/nginx/changeset/c95d7882dfc9ff90ee161328747114b6b54667a5/nginx ) it looks like the only config variable taken into account is proxy_cache_revalidate, which is already set. The check's pretty simple: -- BEGIN SNIPPET -- static ngx_int_t ngx_http_upstream_cache_etag(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { if (r->upstream == NULL || !r->upstream->conf->cache_revalidate || r->upstream->cache_status != NGX_HTTP_CACHE_EXPIRED || r->cache->etag.len == 0) { v->not_found = 1; return NGX_OK; } v->valid = 1; v->no_cacheable = 0; v->not_found = 0; v->len = r->cache->etag.len; v->data = r->cache->etag.data; return NGX_OK; } -- END SNIPPET -- ----------------------------------------------------------------------------------------- 2016-04-22 14:40:55 btasker ----------------------------------------------------------------------------------------- That moment where you realise you're being a twatspanner on the public internet. I'm returning an E-Tag header not an ETag header, so of course NGinx isn't trying to use it. ----------------------------------------------------------------------------------------- 2016-04-22 14:45:26 git ----------------------------------------------------------------------------------------- -- BEGIN QUOTE -- Repo: Jira-Issue-Listing Commit: d4cf7f137964a4d143d341775b68f52b6589de53 Author: Ben Tasker