Use gzip mtime for Last-Modified comparison when in gzip mode

Prior to 1.3.0, uMap was not setting the gzip mtime, so it was
whatever the time it get requested at first.
Since 1.3.0:
- when creating the geojson.gzip, we also force its mtime to be
  the geojson one
- we replaced If-Match by If-Unmodified, which relies on Last-Modified

When uMap is served by a proxy like Nginx (and X-Accel-Redirect),
and if user accepts gzip, then the Last-Modified would be the gzip
one, not the flat geojson one.

So when comparing that value in a subsequent update, we need to
compare with the correct value.

fix #1212
This commit is contained in:
Yohan Boniface 2023-07-19 14:17:40 +02:00
parent f69c959f2a
commit 13a1c3bd5c

View file

@ -784,11 +784,28 @@ class GZipMixin(object):
def path(self): def path(self):
return self.object.geojson.path return self.object.geojson.path
@property
def gzip_path(self):
return Path(f"{self.path}{self.EXT}")
@property @property
def last_modified(self): def last_modified(self):
stat = os.stat(self.path) # Prior to 1.3.0 we did not set gzip mtime as geojson mtime,
# but we switched from If-Match header to IF-Unmodified-Since
# and when users accepts gzip their last modified value is the gzip
# (when umap is served by nginx and X-Accel-Redirect)
# one, so we need to compare with that value in that case.
# cf https://github.com/umap-project/umap/issues/1212
path = self.gzip_path if self.accepts_gzip else self.path
stat = os.stat(path)
return http_date(stat.st_mtime) return http_date(stat.st_mtime)
@property
def accepts_gzip(self):
return settings.UMAP_GZIP and re_accepts_gzip.search(
self.request.META.get("HTTP_ACCEPT_ENCODING", "")
)
class DataLayerView(GZipMixin, BaseDetailView): class DataLayerView(GZipMixin, BaseDetailView):
model = DataLayer model = DataLayer
@ -797,13 +814,9 @@ class DataLayerView(GZipMixin, BaseDetailView):
response = None response = None
path = self.path path = self.path
# Generate gzip if needed # Generate gzip if needed
accepts_gzip = re_accepts_gzip.search( if self.accepts_gzip:
self.request.META.get("HTTP_ACCEPT_ENCODING", "") if not self.gzip_path.exists():
) gzip_file(path, self.gzip_path)
if accepts_gzip and settings.UMAP_GZIP:
gzip_path = Path(f"{path}{self.EXT}")
if not gzip_path.exists():
gzip_file(path, gzip_path)
if getattr(settings, "UMAP_XSENDFILE_HEADER", None): if getattr(settings, "UMAP_XSENDFILE_HEADER", None):
response = HttpResponse() response = HttpResponse()