[Answered ]-Django reverse() behind API Gateway/Proxy

1๐Ÿ‘

I found a workaround to solve it.

Django Rest Framework calls [build_absolute_uri()] (Link) from django.http to build the absolute url.
The variable location contains the generated url paths.

Without changing the core library, I used monkepatching to solve it.
Be aware, that this is a breaking change.
If Django will be updated, you have to check this function.

settings.py

import django.http
from django.utils.encoding import iri_to_uri
from urllib.parse import urljoin, urlsplit

def build_absolute_uri(self, location=None):
    if location is None:
        location = "//%s" % self.get_full_path()
    else:
        # Coerce lazy locations.
        location = str(location)
    
    # !!!!!!!!!!!!!!!!!!!!!
    # I ADD HERE MY CUSTOMIZATION
    # MODIFYING `location`
    # !!!!!!!!!!!!!!!!!!!!!
    location = location.replace(self.META["REQUEST_URI"], self.META["X_FORWARDED_PATH"])

    bits = urlsplit(location)
    if not (bits.scheme and bits.netloc):
        if (
            bits.path.startswith("/")
            and not bits.scheme
            and not bits.netloc
            and "/./" not in bits.path
            and "/../" not in bits.path
        ):
            location = self._current_scheme_host + location.removeprefix("//")
        else:
            location = urljoin(self._current_scheme_host + self.path, location)
    return iri_to_uri(location)

# do monkeypatch and overwrite core functionality with own function  
django.http.request.HttpRequest.build_absolute_uri = build_absolute_uri 
๐Ÿ‘คEwro

Leave a comment