allow to cache proxied remote data requests

cf #513
cf #510
cf #160
This commit is contained in:
Yohan Boniface 2018-08-04 20:50:03 +02:00
parent e319fa963e
commit 81f6b429bc
7 changed files with 63 additions and 10 deletions

View file

@ -49,6 +49,13 @@ COMMIT;
umap compress umap compress
## dev
- allow to cache proxied remote data requests (#513 #510 #160)
- fixed popup template parsing of url with url as query string (#607)
- naive support for nested variables in templates (#600)
- Removed Map.tilelayer foreignkey
## 1.0.0.rc-1 ## 1.0.0.rc-1
- BREAKING: support of python 2 is removed per upgrading to Django 2.0 - BREAKING: support of python 2 is removed per upgrading to Django 2.0
- WARNING: merge Leaflet-Storage and django-leaflet-storage inside umap to ease - WARNING: merge Leaflet-Storage and django-leaflet-storage inside umap to ease
@ -81,7 +88,6 @@ COMMIT;
- add `{rank}` as dynamic feature property (to be used in popup or icon symbol) - add `{rank}` as dynamic feature property (to be used in popup or icon symbol)
- add an explicit button to attach a owner to an anonyous map (#568) - add an explicit button to attach a owner to an anonyous map (#568)
- Add 'TablePanel' popup template (#481) - Add 'TablePanel' popup template (#481)
- Removed Map.tilelayer foreignkey
## 0.8.0 ## 0.8.0

View file

@ -167,7 +167,7 @@ ENABLE_ACCOUNT_LOGIN = False
UMAP_ALLOW_ANONYMOUS = False UMAP_ALLOW_ANONYMOUS = False
UMAP_EXTRA_URLS = { UMAP_EXTRA_URLS = {
'routing': 'http://www.openstreetmap.org/directions?engine=osrm_car&route={lat},{lng}&locale={locale}#map={zoom}/{lat}/{lng}', # noqa 'routing': 'http://www.openstreetmap.org/directions?engine=osrm_car&route={lat},{lng}&locale={locale}#map={zoom}/{lat}/{lng}', # noqa
'ajax_proxy': '/ajax-proxy/?url={url}' 'ajax_proxy': '/ajax-proxy/?url={url}&ttl={ttl}'
} }
UMAP_KEEP_VERSIONS = 10 UMAP_KEEP_VERSIONS = 10
SITE_URL = "http://umap.org" SITE_URL = "http://umap.org"

View file

@ -70,8 +70,8 @@ L.FormBuilder.Select.include({
}, },
getDefault: function () { getDefault: function () {
if (this.options.inheritable) return undefined if (this.options.inheritable) return undefined;
else return L.FormBuilder.Select.prototype.getDefault.call(this) return this.getOptions()[0][0];
} }
}); });
@ -201,6 +201,17 @@ L.FormBuilder.IconClassSwitcher = L.FormBuilder.Select.extend({
}); });
L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
selectOptions: [
[undefined, L._('No cache')],
['300', L._('5 min')],
['3600', L._('1 hour')],
['86400', L._('1 day')]
]
});
L.FormBuilder.PopupTemplate = L.FormBuilder.Select.extend({ L.FormBuilder.PopupTemplate = L.FormBuilder.Select.extend({
selectOptions: [ selectOptions: [

View file

@ -1624,9 +1624,9 @@ L.U.Map.include({
return L.Util.greedyTemplate(url, this.getGeoContext(), true); return L.Util.greedyTemplate(url, this.getGeoContext(), true);
}, },
proxyUrl: function (url) { proxyUrl: function (url, ttl) {
if (this.options.urls.ajax_proxy) { if (this.options.urls.ajax_proxy) {
url = L.Util.template(this.options.urls.ajax_proxy, {url: encodeURIComponent(url)}); url = L.Util.greedyTemplate(this.options.urls.ajax_proxy, {url: encodeURIComponent(url), ttl: ttl});
} }
return url; return url;
}, },

View file

@ -339,7 +339,7 @@ L.U.DataLayer = L.Class.extend({
if (!this.isVisible()) return; if (!this.isVisible()) return;
var self = this, var self = this,
url = this.map.localizeUrl(this.options.remoteData.url); url = this.map.localizeUrl(this.options.remoteData.url);
if (this.options.remoteData.proxy) url = this.map.proxyUrl(url); if (this.options.remoteData.proxy) url = this.map.proxyUrl(url, this.options.remoteData.ttl);
this.map.ajax({ this.map.ajax({
uri: url, uri: url,
verb: 'GET', verb: 'GET',
@ -804,6 +804,7 @@ L.U.DataLayer = L.Class.extend({
]; ];
if (this.map.options.urls.ajax_proxy) { if (this.map.options.urls.ajax_proxy) {
remoteDataFields.push(['options.remoteData.proxy', {handler: 'Switch', label: L._('Proxy request'), helpEntries: 'proxyRemoteData'}]); remoteDataFields.push(['options.remoteData.proxy', {handler: 'Switch', label: L._('Proxy request'), helpEntries: 'proxyRemoteData'}]);
remoteDataFields.push(['options.remoteData.ttl', {handler: 'ProxyTTLSelect', label: L._('Cache proxied request')}]);
} }
var remoteDataContainer = L.DomUtil.createFieldset(container, L._('Remote data')); var remoteDataContainer = L.DomUtil.createFieldset(container, L._('Remote data'));

View file

@ -82,6 +82,34 @@ def test_valid_proxy_request(client):
assert 'Cookie' not in response['Vary'] assert 'Cookie' not in response['Vary']
def test_valid_proxy_request_with_ttl(client):
url = reverse('ajax-proxy')
params = {'url': 'http://example.org', 'ttl': 3600}
headers = {
'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
'HTTP_REFERER': settings.SITE_URL
}
response = client.get(url, params, **headers)
assert response.status_code == 200
assert 'Example Domain' in response.content.decode()
assert 'Cookie' not in response['Vary']
assert response['X-Accel-Expires'] == '3600'
def test_valid_proxy_request_with_invalid_ttl(client):
url = reverse('ajax-proxy')
params = {'url': 'http://example.org', 'ttl': 'invalid'}
headers = {
'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
'HTTP_REFERER': settings.SITE_URL
}
response = client.get(url, params, **headers)
assert response.status_code == 200
assert 'Example Domain' in response.content.decode()
assert 'Cookie' not in response['Vary']
assert 'X-Accel-Expires' not in response
@pytest.mark.django_db @pytest.mark.django_db
def test_login_does_not_contain_form_if_not_enabled(client, settings): def test_login_does_not_contain_form_if_not_enabled(client, settings):
settings.ENABLE_ACCOUNT_LOGIN = False settings.ENABLE_ACCOUNT_LOGIN = False

View file

@ -267,7 +267,7 @@ class AjaxProxy(View):
# You should not use this in production (use Nginx or so) # You should not use this in production (use Nginx or so)
try: try:
url = validate_url(self.request) url = validate_url(self.request)
except AssertionError as e: except AssertionError:
return HttpResponseBadRequest() return HttpResponseBadRequest()
headers = { headers = {
'User-Agent': 'uMapProxy +http://wiki.openstreetmap.org/wiki/UMap' 'User-Agent': 'uMapProxy +http://wiki.openstreetmap.org/wiki/UMap'
@ -285,8 +285,15 @@ class AjaxProxy(View):
content = proxied_request.read() content = proxied_request.read()
# Quick hack to prevent Django from adding a Vary: Cookie header # Quick hack to prevent Django from adding a Vary: Cookie header
self.request.session.accessed = False self.request.session.accessed = False
return HttpResponse(content, status=status_code, response = HttpResponse(content, status=status_code,
content_type=mimetype) content_type=mimetype)
try:
ttl = int(self.request.GET.get('ttl'))
except (TypeError, ValueError):
pass
else:
response['X-Accel-Expires'] = ttl
return response
ajax_proxy = AjaxProxy.as_view() ajax_proxy = AjaxProxy.as_view()