speedup tileserver by factor 2x (not 0.6ms per request)
This commit is contained in:
parent
0f6b372b92
commit
d74d9a8a77
1 changed files with 20 additions and 17 deletions
|
@ -3,7 +3,6 @@ import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
from http.cookies import SimpleCookie
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
@ -19,7 +18,8 @@ logger = logging.getLogger('c3nav')
|
||||||
|
|
||||||
|
|
||||||
class TileServer:
|
class TileServer:
|
||||||
regex = re.compile(r'^/(?P<level>\d+)/(?P<zoom>\d+)/(?P<x>-?\d+)/(?P<y>-?\d+).png$')
|
path_regex = re.compile(r'^/(\d+)/(\d+)/(-?\d+)/(-?\d+).png$')
|
||||||
|
cookie_regex = re.compile(r'[^ ]c3nav_tile_access=([^; ])')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
try:
|
try:
|
||||||
|
@ -86,11 +86,13 @@ class TileServer:
|
||||||
return [text]
|
return [text]
|
||||||
|
|
||||||
def __call__(self, env, start_response):
|
def __call__(self, env, start_response):
|
||||||
match = self.regex.match(env['PATH_INFO'])
|
match = self.path_regex.match(env['PATH_INFO'])
|
||||||
if match is None:
|
if match is None:
|
||||||
return self.not_found(start_response, b'invalid tile path.')
|
return self.not_found(start_response, b'invalid tile path.')
|
||||||
|
|
||||||
zoom = int(match.group('zoom'))
|
level, zoom, x, y = match.groups()
|
||||||
|
|
||||||
|
zoom = int(zoom)
|
||||||
if not (0 <= zoom <= 10):
|
if not (0 <= zoom <= 10):
|
||||||
return self.not_found(start_response, b'zoom out of bounds.')
|
return self.not_found(start_response, b'zoom out of bounds.')
|
||||||
|
|
||||||
|
@ -98,25 +100,25 @@ class TileServer:
|
||||||
cache_package = self.cache_package
|
cache_package = self.cache_package
|
||||||
|
|
||||||
# check if bounds are valid
|
# check if bounds are valid
|
||||||
x = int(match.group('x'))
|
x = int(x)
|
||||||
y = int(match.group('y'))
|
y = int(y)
|
||||||
minx, miny, maxx, maxy = get_tile_bounds(zoom, x, y)
|
minx, miny, maxx, maxy = get_tile_bounds(zoom, x, y)
|
||||||
if not cache_package.bounds_valid(minx, miny, maxx, maxy):
|
if not cache_package.bounds_valid(minx, miny, maxx, maxy):
|
||||||
return self.not_found(start_response, b'coordinates out of bounds.')
|
return self.not_found(start_response, b'coordinates out of bounds.')
|
||||||
|
|
||||||
# get level
|
# get level
|
||||||
level = int(match.group('level'))
|
level = int(level)
|
||||||
level_data = cache_package.levels.get(level)
|
level_data = cache_package.levels.get(level)
|
||||||
if level_data is None:
|
if level_data is None:
|
||||||
return self.not_found(start_response, b'invalid level.')
|
return self.not_found(start_response, b'invalid level.')
|
||||||
|
|
||||||
# decode access permissions
|
# decode access permissions
|
||||||
try:
|
cookie = env.get('HTTP_COOKIE', None)
|
||||||
cookie = SimpleCookie(env['HTTP_COOKIE'])['c3nav_tile_access'].value
|
if cookie:
|
||||||
except KeyError:
|
cookie = self.cookie_regex.match(cookie)
|
||||||
access_permissions = set()
|
if cookie:
|
||||||
else:
|
cookie = cookie.group(0)
|
||||||
access_permissions = parse_tile_access_cookie(cookie, self.tile_secret)
|
access_permissions = parse_tile_access_cookie(cookie, self.tile_secret) if cookie else set()
|
||||||
|
|
||||||
# only access permissions that are affecting this tile
|
# only access permissions that are affecting this tile
|
||||||
access_permissions &= set(level_data.restrictions[minx:miny, maxx:maxy])
|
access_permissions &= set(level_data.restrictions[minx:miny, maxx:maxy])
|
||||||
|
@ -127,8 +129,9 @@ class TileServer:
|
||||||
access_cache_key = build_access_cache_key(access_permissions)
|
access_cache_key = build_access_cache_key(access_permissions)
|
||||||
|
|
||||||
# check browser cache
|
# check browser cache
|
||||||
tile_etag = build_tile_etag(level, zoom, x, y, base_cache_key, access_cache_key, self.tile_secret)
|
|
||||||
if_none_match = env.get('HTTP_IF_NONE_MATCH')
|
if_none_match = env.get('HTTP_IF_NONE_MATCH')
|
||||||
|
if if_none_match:
|
||||||
|
tile_etag = build_tile_etag(level, zoom, x, y, base_cache_key, access_cache_key, self.tile_secret)
|
||||||
if if_none_match == tile_etag:
|
if if_none_match == tile_etag:
|
||||||
start_response('304 Not Modified', [('Content-Type', 'text/plain'), ('ETag', tile_etag)])
|
start_response('304 Not Modified', [('Content-Type', 'text/plain'), ('ETag', tile_etag)])
|
||||||
return [b'']
|
return [b'']
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue