Changeset - 55a10b750b6a
[Not reviewed]
0 2 0
Christopher Neugebauer - 7 years ago 2017-08-17 15:09:21
chrisjrn@gmail.com
Adds a middleware to canonicalise the hostname
2 files changed with 25 insertions and 1 deletions:
0 comments (0 inline, 0 general)
pinaxcon/middleware.py
Show inline comments
 
import re
 
import warnings
 

	
 
from django import http
 
from django.conf import settings
 
from django.utils.deprecation import MiddlewareMixin
 

	
 
class CanonicalHostMiddleware(MiddlewareMixin):
 
    """ Redirects to a canonical host if the current host is not the canonical
 
    host. """
 

	
 
    response_redirect_class = http.HttpResponsePermanentRedirect
 

	
 
    def process_request(self, request):
 

	
 
        canonical_host = getattr(settings, "CANONICAL_HOST", None)
 

	
 
        if not canonical_host:
 
            return
 

	
 
        host = request.get_host()
 

	
 
        if host == canonical_host:
 
            return
 

	
 
        path = request.get_full_path()
 
        redirect_url = ('%s://%s%s' % (request.scheme, canonical_host, path))
 
        return self.response_redirect_class(redirect_url)
 

	
 

	
 
class UnprependWWWMiddleware(MiddlewareMixin):
 
    """ Unprepends www if necessary. """
 

	
 
    response_redirect_class = http.HttpResponsePermanentRedirect
 

	
 
    def process_request(self, request):
 
        """
 
        Rewrite the URL based on settings.UNPREPEND_WWW
 
        """
 

	
 
        unprepend_www = getattr(settings, "UNPREPEND_WWW", False)
 

	
 
        if not unprepend_www:
 
            return
 

	
 
        # Check for a redirect based on settings.UNPREPEND_WWW
 
        host = request.get_host()
 
        must_unprepend = unprepend_www and host and host.lower().startswith('www.')
 
        wwwless_host = host[4:]
 
        redirect_url = ('%s://%s' % (request.scheme, wwwless_host)) if must_unprepend else ''
 

	
 
        path = request.get_full_path()
 

	
 
        # Return a redirect if necessary
pinaxcon/settings.py
Show inline comments
...
 
@@ -2,48 +2,49 @@ import os
 
import dj_database_url
 

	
 

	
 
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
 
PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))
 
BASE_DIR = PACKAGE_ROOT
 

	
 
DEBUG = bool(int(os.environ.get("DEBUG", "1")))
 

	
 
DATABASES = {
 
    "default": {
 
        "ENGINE": "django.db.backends.sqlite3",
 
        "NAME": os.path.join(PROJECT_ROOT, "dev.db"),
 
    }
 
}
 

	
 
UNPREPEND_WWW = bool(os.environ.get("DJANGO_UNPREPEND_WWW", False))
 

	
 
# HEROKU: Update database configuration with $DATABASE_URL.
 
import dj_database_url
 
db_from_env = dj_database_url.config()
 
DATABASES['default'].update(db_from_env)
 

	
 
ALLOWED_HOSTS = [".localhost", ".herokuapp.com", ".northbaypython.org"]
 
CANONICAL_HOST = os.environ.get("DJANGO_CANONICAL_HOST", None)
 

	
 
# Local time zone for this installation. Choices can be found here:
 
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
 
# although not all choices may be available on all operating systems.
 
# On Unix systems, a value of None will cause Django to use the same
 
# timezone as the operating system.
 
# If running in a Windows environment this must be set to the same as your
 
# system time zone.
 
TIME_ZONE = os.environ.get("TZ", "America/Los_Angeles")
 

	
 

	
 
# Use SSLRedirectMiddleware
 
SSL_ON = os.environ.get("DJANGO_SSL_ON", True)
 
SSL_ALWAYS = os.environ.get("DJANGO_SSL_ALWAYS", False)
 

	
 
# Language code for this installation. All choices can be found here:
 
# http://www.i18nguy.com/unicode/language-identifiers.html
 
LANGUAGE_CODE = "en-us"
 

	
 
SITE_ID = int(os.environ.get("SITE_ID", 1))
 

	
 
# If you set this to False, Django will make some optimizations so as not
 
# to load the internationalization machinery.
 
USE_I18N = True
...
 
@@ -113,50 +114,50 @@ TEMPLATES = [
 
                "django.template.context_processors.i18n",
 
                "django.template.context_processors.media",
 
                "django.template.context_processors.static",
 
                "django.template.context_processors.tz",
 
                "django.template.context_processors.request",
 
                "django.contrib.messages.context_processors.messages",
 
                "account.context_processors.account",
 
                "pinax_theme_bootstrap.context_processors.theme",
 
                "symposion.reviews.context_processors.reviews",
 
            ],
 
        },
 
    },
 
]
 

	
 
MIDDLEWARE_CLASSES = [
 
    "django.contrib.sessions.middleware.SessionMiddleware",
 
    "django.middleware.common.CommonMiddleware",
 
    "django.middleware.csrf.CsrfViewMiddleware",
 
    "django.contrib.auth.middleware.AuthenticationMiddleware",
 
    "django.contrib.auth.middleware.SessionAuthenticationMiddleware",
 
    "django.contrib.messages.middleware.MessageMiddleware",
 
    "reversion.middleware.RevisionMiddleware",
 
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
 
    "ssl_redirect.middleware.SSLRedirectMiddleware",
 
    "pinaxcon.middleware.CanonicalHostMiddleware",
 
    "pinaxcon.middleware.UnprependWWWMiddleware",
 

	
 
]
 

	
 
ROOT_URLCONF = "pinaxcon.urls"
 

	
 
# Python dotted path to the WSGI application used by Django's runserver.
 
WSGI_APPLICATION = "pinaxcon.wsgi.application"
 

	
 
INSTALLED_APPS = [
 
    "django.contrib.admin",
 
    "django.contrib.auth",
 
    "django.contrib.contenttypes",
 
    "django.contrib.messages",
 
    "django.contrib.sessions",
 
    "django.contrib.sites",
 
    "django.contrib.staticfiles",
 

	
 
    # theme
 
    "bootstrapform",
 
    "pinax_theme_bootstrap",
 

	
 
    # external
 
    "account",
 
    "easy_thumbnails",
 
    "taggit",
0 comments (0 inline, 0 general)