from urllib.parse import urlparse from django.http import HttpRequest, HttpResponse, HttpResponseForbidden def same_origin(current_uri, redirect_uri): a = urlparse(current_uri) if not a.scheme: return True b = urlparse(redirect_uri) return (a.scheme, a.hostname, a.port) == (b.scheme, b.hostname, b.port) def turbolinks(request: HttpRequest): ctx = {} if request.META.get('HTTP_TURBOLINKS_REFERRER') is not None: ctx['is_turbolinks'] = True return ctx class TurbolinksMiddleware: def process_request(self, request: HttpRequest): referrer = request.META.get('HTTP_TURBOLINKS_REFERRER') if referrer: request.META['HTTP_REFERER'] = referrer return def process_response(self, request: HttpRequest, response: HttpResponse): referrer = request.META.get('HTTP_TURBOLINKS_REFERRER') if referrer is None: return response if response.has_header('Location'): loc = response['Location'] request.session['_turbolinks_redirect_to'] = loc if referrer and not same_origin(loc, referrer): return HttpResponseForbidden() else: if request.session.get('_turbolinks_redirect_to'): loc = request.session.pop('_turbolinks_redirect_to') response['Turbolinks-Location'] = loc return response