diff --git a/.gitignore b/.gitignore index 719c586c..d9068316 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ static.dist c3nav.cfg /src/data loadproduction.sh +runtileserver.sh .idea diff --git a/src/c3nav/mapdata/urls.py b/src/c3nav/mapdata/urls.py index 9a8be993..2b01be76 100644 --- a/src/c3nav/mapdata/urls.py +++ b/src/c3nav/mapdata/urls.py @@ -1,9 +1,10 @@ from django.conf.urls import url -from c3nav.mapdata.views import history, tile, tile_access +from c3nav.mapdata.views import cache_package, history, tile, tile_access urlpatterns = [ url(r'^(?P\d+)/(?P\d+)/(?P-?\d+)/(?P-?\d+).png$', tile, name='mapdata.tile'), url(r'^history/(?P\d+)/(?Pbase|composite).(?Ppng|data)$', history, name='mapdata.history'), + url(r'^cache/package(?P\.tar|\.tar\.gz|\.tar\.xz)$', cache_package, name='mapdata.cache_package'), url(r'^tile_access$', tile_access, name='mapdata.tile_access'), ] diff --git a/src/c3nav/mapdata/views.py b/src/c3nav/mapdata/views.py index 3d88ed48..139087e3 100644 --- a/src/c3nav/mapdata/views.py +++ b/src/c3nav/mapdata/views.py @@ -1,12 +1,14 @@ +import base64 import hashlib import os from itertools import chain +from wsgiref.util import FileWrapper from django.conf import settings from django.core.cache import cache from django.core.exceptions import PermissionDenied from django.core.signing import b64_encode -from django.http import Http404, HttpResponse, HttpResponseNotModified +from django.http import Http404, HttpResponse, HttpResponseNotModified, StreamingHttpResponse from django.shortcuts import get_object_or_404 from django.views.decorators.http import etag from shapely.geometry import box @@ -122,7 +124,7 @@ def tile_access(request): return response -@etag(lambda *args, **kwargs: MapUpdate.current_cache_key()) +@etag(lambda *args, **kwargs: MapUpdate.current_processed_cache_key()) @no_language() def history(request, level, mode, format): if not request.user.is_superuser: @@ -143,3 +145,30 @@ def history(request, level, mode, format): raise ValueError response['Cache-Control'] = 'no-cache' return response + + +encoded_tile_secret = base64.b64encode(settings.SECRET_TILE_KEY.encode()).decode() + + +@etag(lambda *args, **kwargs: MapUpdate.current_processed_cache_key()) +@no_language() +def cache_package(request, filetype): + x_tile_secret = request.META.get('HTTP_X_TILE_SECRET') + if x_tile_secret: + if x_tile_secret != encoded_tile_secret: + raise PermissionDenied + elif not request.user.is_superuser: + raise PermissionDenied + + filename = os.path.join(settings.CACHE_ROOT, 'package'+filetype) + f = open(filename, 'rb') + + f.seek(0, os.SEEK_END) + size = f.tell() + f.seek(0) + + content_type = 'application/' + {'.tar': 'x-tar', '.tar.gz': 'gzip', '.tar.xz': 'x-xz'}[filetype] + + response = StreamingHttpResponse(FileWrapper(f), content_type=content_type) + response['Content-Length'] = size + return response