diff --git a/dynamicweb/settings/local.py b/dynamicweb/settings/local.py index 4ea3dc7e..c48a4a2b 100644 --- a/dynamicweb/settings/local.py +++ b/dynamicweb/settings/local.py @@ -15,6 +15,10 @@ CACHES = { } } +MIDDLEWARE_CLASSES = ( + 'utils.middleware.DevSiteSwitcherMiddleware', +) + MIDDLEWARE_CLASSES + MIDDLEWARE_CLASSES += ("debug_toolbar.middleware.DebugToolbarMiddleware",) INSTALLED_APPS += ( diff --git a/utils/middleware.py b/utils/middleware.py index 980cc092..40472ac1 100644 --- a/utils/middleware.py +++ b/utils/middleware.py @@ -1,3 +1,9 @@ +import json + +from django.conf import settings +from django.http import HttpResponse + + class MultipleProxyMiddleware(object): FORWARDED_FOR_FIELDS = [ 'HTTP_X_FORWARDED_FOR', @@ -15,3 +21,52 @@ class MultipleProxyMiddleware(object): if ',' in request.META[field]: parts = request.META[field].split(',') request.META[field] = parts[-1].strip() + + +class DevSiteSwitcherMiddleware(object): + """ + Dev/test only (enabled from settings/local.py, i.e. DEBUG=True). + + The project picks a site from the request's Host header. To test every + site from a single address without DNS or /etc/hosts entries, visit + http://:8000/?site=datacenterlight.ch once; the choice is kept in + a cookie. ?site= (empty) clears it. + """ + COOKIE = 'dev_site' + + def process_request(self, request): + if request.path == '/dev-sites/': + return self.sites_page() + if 'site' in request.GET: + site = request.GET['site'].strip() + else: + site = request.COOKIES.get(self.COOKIE, '') + request.META['DEV_SITE_SWITCH'] = site + if site: + request.META['HTTP_HOST'] = site + request.META.pop('HTTP_X_FORWARDED_HOST', None) + + def process_response(self, request, response): + if 'site' in request.GET: + site = request.META.get('DEV_SITE_SWITCH', '') + if site: + response.set_cookie(self.COOKIE, site) + else: + response.delete_cookie(self.COOKIE) + return response + + def sites_page(self): + """A page listing every configured site as a link, on any host""" + try: + domains = sorted( + d for d in json.loads(settings.UNGLEICH_SITE_CONFIGS) + if ':' not in d) + except ValueError: + domains = [] + items = ''.join( + '
  • {0}
  • '.format(d) for d in domains) + return HttpResponse( + 'Test sites' + '

    Test sites

    Click a site to browse it; ' + 'clear the choice.

    '.format( + items))