2011-07-11 02:10:22 +01:00
from django . conf import settings
from django import http
2021-03-31 17:57:43 +01:00
from django . urls import reverse , resolve , Resolver404
2020-07-18 16:23:54 +01:00
""" Non-standard django middleware is loaded from this file.
"""
2011-07-11 02:10:22 +01:00
class SmartAppendSlashMiddleware ( object ) :
"""
" SmartAppendSlash " middleware for taking care of URL rewriting .
This middleware appends a missing slash , if :
* the SMART_APPEND_SLASH setting is True
* the URL without the slash does not exist
* the URL with an appended slash does exist .
Otherwise it won ' t touch the URL.
"""
def process_request ( self , request ) :
2021-03-31 17:57:43 +01:00
''' Called for every url so return as quickly as possible
Append a slash if SMART_APPEND_SLASH is set , the resulting URL resolves and it doesn ' t without the /
'''
if not settings . SMART_APPEND_SLASH :
return None
if request . path . endswith ( ' / ' ) :
return None
if request . path . endswith ( ' _edit ' ) :
return None
2011-07-11 02:10:22 +01:00
2018-04-11 22:02:57 +01:00
host = http . HttpRequest . get_host ( request )
2011-07-11 02:10:22 +01:00
old_url = [ host , request . path ]
2021-03-31 17:57:43 +01:00
if _resolves ( old_url [ 1 ] ) :
return None
# So: it does not resolve according to our criteria, i.e. _edit doesn't count
new_url = old_url [ : ]
new_url [ 1 ] = new_url [ 1 ] + ' / '
if not _resolves ( new_url [ 1 ] ) :
return None
else :
2011-07-11 02:10:22 +01:00
if settings . DEBUG and request . method == ' POST ' :
2021-03-31 17:57:43 +01:00
# replace this exception with a redirect to an error page
2020-05-24 01:57:06 +01:00
raise RuntimeError ( " You called this URL via POST, but the URL doesn ' t end in a slash and you have SMART_APPEND_SLASH set. Django can ' t redirect to the slash URL while maintaining POST data. Change your form to point to %s %s (note the trailing slash), or set SMART_APPEND_SLASH=False in your Django settings. " % ( new_url [ 0 ] , new_url [ 1 ] ) )
2011-07-11 02:10:22 +01:00
if new_url != old_url :
# Redirect
if new_url [ 0 ] :
newurl = " %s :// %s %s " % ( request . is_secure ( ) and ' https ' or ' http ' , new_url [ 0 ] , new_url [ 1 ] )
else :
newurl = new_url [ 1 ]
if request . GET :
newurl + = ' ? ' + request . GET . urlencode ( )
return http . HttpResponsePermanentRedirect ( newurl )
return None
def _resolves ( url ) :
try :
2021-03-31 17:57:43 +01:00
# If the URL does not resolve, the function raises a Resolver404 exception (a subclass of Http404)
match = resolve ( url )
# this will ALWAYS be resolved by expopages because it will produce pagenotfound if not the thing asked for
# so handle this in expopages, not in middleware
2011-07-11 02:10:22 +01:00
return True
2021-03-31 17:57:43 +01:00
except Resolver404 :
2020-06-16 11:14:10 +01:00
return False
except :
print ( url )
raise