2010-09-26 23:03:53 +00:00
from django import http
2015-03-03 18:40:18 +00:00
from django . conf import settings
2010-09-26 23:03:53 +00:00
from django . utils . cache import patch_response_headers
2023-09-07 13:15:48 +00:00
class ForceCanonicalHostnameMiddleware :
2010-09-26 23:03:53 +00:00
def process_request ( self , request ) :
""" Modified common middleware for Conservancy site
* Performs redirects to strip trailing " index.html "
* performs redirects based on APPEND_SLASH
* performs redirects based on site - specific REDIRECT_TABLE
* adds cache headers to provide hints to squid
"""
2013-04-26 17:09:24 +00:00
# Never allow connection to the /admin part of the site without SSL
if ( not request . is_secure ) and request . path . startswith ( ' /admin ' ) :
url = ' https://sfconservancy.org %s ' % request . path
return http . HttpResponseRedirect ( url )
2010-09-26 23:03:53 +00:00
# Check for a redirect based on settings.APPEND_SLASH
2015-03-03 18:40:18 +00:00
host = request . get_host ( )
2010-09-26 23:03:53 +00:00
old_url = [ host , request . path ]
new_url = old_url [ : ]
# Append a slash if append_slash is set and the URL doesn't have a
# trailing slash or a file extension.
if settings . APPEND_SLASH and ( old_url [ 1 ] [ - 1 ] != ' / ' ) and ( ' . ' not in old_url [ 1 ] . split ( ' / ' ) [ - 1 ] ) :
new_url [ 1 ] = new_url [ 1 ] + ' / '
if settings . DEBUG and request . method == ' POST ' :
2023-09-07 13:15:48 +00:00
raise ( RuntimeError , " You called this URL via POST, but the URL doesn ' t end in a slash and you have APPEND_SLASH set. Django can ' t redirect to the slash URL while maintaining POST data. Change your form to point to {} {} (note the trailing slash), or set APPEND_SLASH=False in your Django settings. " . format ( new_url [ 0 ] , new_url [ 1 ] ) )
2010-09-26 23:03:53 +00:00
# Strip trailing index.html
if new_url [ 1 ] . endswith ( ' /index.html ' ) :
new_url [ 1 ] = new_url [ 1 ] [ : new_url [ 1 ] . rfind ( ' index.html ' ) ]
# Consult redirect table (if exists)
if hasattr ( settings , " REDIRECT_TABLE " ) :
2021-11-26 02:00:20 +00:00
if new_url [ 1 ] in settings . REDIRECT_TABLE :
2010-09-26 23:03:53 +00:00
new_url [ 1 ] = settings . REDIRECT_TABLE [ new_url [ 1 ] ]
if new_url != old_url :
# Force canonical hostname
if settings . FORCE_CANONICAL_HOSTNAME :
new_url [ 0 ] = settings . FORCE_CANONICAL_HOSTNAME
# Redirect
if new_url [ 0 ] :
2023-09-07 13:15:48 +00:00
newurl = " {} :// {} {} " . format ( request . is_secure ( ) and ' https ' or ' http ' , new_url [ 0 ] , new_url [ 1 ] )
2010-09-26 23:03:53 +00:00
else :
newurl = new_url [ 1 ]
if request . GET :
newurl + = ' ? ' + request . GET . urlencode ( )
return http . HttpResponseRedirect ( newurl )
return None
def process_response ( self , request , response ) :
# provide hints to squid
if request . method in ( ' GET ' , ' HEAD ' ) and response . status_code == 200 :
patch_response_headers ( response )
return response