diff options
Diffstat (limited to 'nixpkgs/pkgs/servers/http/nginx/nix-etag-1.15.4.patch')
-rw-r--r-- | nixpkgs/pkgs/servers/http/nginx/nix-etag-1.15.4.patch | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/nixpkgs/pkgs/servers/http/nginx/nix-etag-1.15.4.patch b/nixpkgs/pkgs/servers/http/nginx/nix-etag-1.15.4.patch index d001b842f335..8c8c8ce74b21 100644 --- a/nixpkgs/pkgs/servers/http/nginx/nix-etag-1.15.4.patch +++ b/nixpkgs/pkgs/servers/http/nginx/nix-etag-1.15.4.patch @@ -2,10 +2,10 @@ This patch makes it possible to serve static content from Nix store paths, by using the hash of the store path for the ETag header. diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c -index cb49ef74..7b456993 100644 +index 97a91aee2..2d07d71e6 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c -@@ -1583,6 +1583,8 @@ ngx_http_set_etag(ngx_http_request_t *r) +@@ -1676,6 +1676,8 @@ ngx_http_set_etag(ngx_http_request_t *r) { ngx_table_elt_t *etag; ngx_http_core_loc_conf_t *clcf; @@ -14,14 +14,25 @@ index cb49ef74..7b456993 100644 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); -@@ -1598,16 +1600,60 @@ ngx_http_set_etag(ngx_http_request_t *r) - etag->hash = 1; +@@ -1692,16 +1694,82 @@ ngx_http_set_etag(ngx_http_request_t *r) + etag->next = NULL; ngx_str_set(&etag->key, "ETag"); - etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3); - if (etag->value.data == NULL) { - etag->hash = 0; - return NGX_ERROR; ++ // Upstream nginx uses file mod timestamp and content-length for Etag, but ++ // files in the Nix store have their timestamps reset, so that doesn't work. ++ // Instead, when serving from the Nix store, we use the hash from the store ++ // path and content-length. ++ // ++ // Every file in under the given store path will share the same store path ++ // hash. It is fine to serve different resources with the same Etag, but ++ // different representations of the same resource (eg the same file, but ++ // gzip-compressed) should have different Etags. Thus, we also append ++ // content-length, which should be different when the response is compressed ++ + err = ngx_errno; + real = ngx_realpath(clcf->root.data, NULL); + ngx_set_errno(err); @@ -35,8 +46,10 @@ index cb49ef74..7b456993 100644 + && real[NIX_STORE_LEN] == '/' + && real[NIX_STORE_LEN + 1] != '\0') + { -+ ptr1 = real + NIX_STORE_LEN; -+ *ptr1 = '"'; ++ // extract the hash from a path formatted like ++ // /nix/store/hashhere1234-pname-1.0.0 ++ // +1 to skip the leading / ++ ptr1 = real + NIX_STORE_LEN + 1; + + ptr2 = (u_char *) ngx_strchr(ptr1, '-'); + @@ -46,11 +59,11 @@ index cb49ef74..7b456993 100644 + return NGX_ERROR; + } + -+ *ptr2++ = '"'; + *ptr2 = '\0'; + -+ etag->value.len = ngx_strlen(ptr1); -+ etag->value.data = ngx_pnalloc(r->pool, etag->value.len); ++ // hash + content-length + quotes and hyphen. Note that the ++ // content-length part of the string can vary in length. ++ etag->value.data = ngx_pnalloc(r->pool, ngx_strlen(ptr1) + NGX_OFF_T_LEN + 3); + + if (etag->value.data == NULL) { + ngx_free(real); @@ -58,9 +71,18 @@ index cb49ef74..7b456993 100644 + return NGX_ERROR; + } + -+ ngx_memcpy(etag->value.data, ptr1, etag->value.len); ++ ++ // set value.data content to "{hash}-{content-length}" (including quote ++ // marks), and set value.len to the length of the resulting string ++ etag->value.len = ngx_sprintf(etag->value.data, "\"\%s-%xO\"", ++ ptr1, ++ r->headers_out.content_length_n) ++ - etag->value.data; ++ + ngx_http_clear_last_modified(r); + } else { ++ // outside of Nix store, use the upstream Nginx logic for etags ++ + etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3); + + if (etag->value.data == NULL) { @@ -82,4 +104,3 @@ index cb49ef74..7b456993 100644 + ngx_free(real); r->headers_out.etag = etag; - |