Login

Single Django App behind multiple Apache Proxies

Author:
chadmaine
Posted:
May 3, 2007
Language:
Python
Version:
.96
Score:
2 (after 2 ratings)

Django Proxied Behind Apache Path

Middleware and Context Processor for django applications behind a proxy like Apache's mod_proxy. Setting an HTTP header with the base path of the django application in the Apache mod_proxy configuration, we can pull that variable out of the request and adjust our template URIs and redirects. This allows us to serve the same Django application out from behind multiple VirtualHosts at different URL paths.

Example use in templates:

<a href="{{ base_path }}/login/">Login</a>

Example Apache configuration:

<LocationMatch ^/path/to/django/app/.*>
    RequestHeader set X-Base-Path "/path/to/django/app"
</LocationMatch>
RewriteRule     ^/path/to/django/app/(.*) http://django-host:8080/$1 [P,L]

In settings.py:

VHOST_HEADER = "HTTP_X_BASE_PATH"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#
# middleware
#
from django.conf import settings
from django import http

class VhostMiddleware(object):

    def process_request(self, req):
        '''
        Pull HTTP header containing the vhost base path into the request object
        '''
        vhost_header_name = getattr(settings, "VHOST_HEADER", "HTTP_X_BASE_PATH")
        base_path = req.META.get(vhost_header_name, "")
        ## eliminate trailing slash ##
        if base_path.endswith('/'):
            base_path = base_path[:-1]
        req.base_path = base_path
        return None

    def process_response(self, req, res):
        '''
        Adjust redirects to include the base path
        '''
        if res.status_code in (301,302) and not res["Location"].startswith(req.base_path)                                                                and res["Location"].startswith("/"):
            res["Location"] = "%s%s" % (req.base_path,res["Location"])

        return res

#
# Context Processor
#
def VhostContextProcessor(request):
    ctx = {"base_path": ""}
    try:
        ctx["base_path"] = request.base_path
    except:
        pass
    return ctx

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.