from django.conf import settings from django.http import HttpResponseNotFound, HttpResponseRedirect, QueryDict from django.urls import reverse class RedirectMiddleware: def __init__(self, get_response): self.get_response = get_response self.redirect_ipv4 = settings.IP_REDIRECT_HOST["ipv4"] self.redirect_ipv6 = settings.IP_REDIRECT_HOST["ipv6"] self.redirect_both = ( settings.IP_REDIRECT_HOST["both"] if self.redirect_ipv4 and self.redirect_ipv6 else "" ) self.disallowed_paths = set(["/favicon.ico", "/robots.txt"]) def __call__(self, request): host = request.get_host() if self.redirect_both and host == self.redirect_both: if request.path in self.disallowed_paths: return HttpResponseNotFound() q = QueryDict(mutable=True) q.appendlist("next", self.build_url(request, self.redirect_ipv6)) return HttpResponseRedirect( f"{self.build_url(request, self.redirect_ipv4)}?{q.urlencode()}" ) if ( self.redirect_ipv4 and host == self.redirect_ipv4 and request.path != reverse("remote_ip") ): if request.path in self.disallowed_paths: return HttpResponseNotFound() return HttpResponseRedirect(self.build_url(request, self.redirect_ipv4)) if ( self.redirect_ipv6 and host == self.redirect_ipv6 and request.path != reverse("remote_ip") ): if request.path in self.disallowed_paths: return HttpResponseNotFound() return HttpResponseRedirect(self.build_url(request, self.redirect_ipv6)) return self.get_response(request) def build_url(self, request, redirect_host): return f"http{'s' if request.is_secure() else ''}://{redirect_host}{reverse('remote_ip')}"