2011-07-11 02:10:22 +01:00
from django import http
2023-01-19 18:35:56 +00:00
from django . conf import settings
2023-01-30 23:04:11 +00:00
from django . urls import Resolver404 , resolve
2023-01-19 18:35:56 +00:00
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
2021-04-30 23:21:38 +01:00
"""
2023-01-30 19:04:36 +00:00
todo = """ SmartAppendSlashMiddleware(object) Not Working.
2021-04-30 23:21:38 +01:00
It needs re - writing to be compatible with Django v2 .0 and later
2023-01-30 19:04:36 +00:00
"""
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 ) :
2023-01-30 19:04:36 +00:00
""" Called for every url so return as quickly as possible
2021-03-31 17:57:43 +01:00
Append a slash if SMART_APPEND_SLASH is set , the resulting URL resolves and it doesn ' t without the /
2023-01-30 19:04:36 +00:00
"""
2021-03-31 17:57:43 +01:00
if not settings . SMART_APPEND_SLASH :
return None
2023-01-30 19:04:36 +00:00
if request . path . endswith ( " / " ) :
2021-03-31 17:57:43 +01:00
return None
2023-01-30 19:04:36 +00:00
if request . path . endswith ( " _edit " ) :
2021-03-31 17:57:43 +01:00
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
2023-01-30 19:04:36 +00:00
2021-03-31 17:57:43 +01:00
# So: it does not resolve according to our criteria, i.e. _edit doesn't count
2023-01-30 19:04:36 +00:00
new_url = old_url [ : ]
new_url [ 1 ] = new_url [ 1 ] + " / "
2021-03-31 17:57:43 +01:00
if not _resolves ( new_url [ 1 ] ) :
return None
2023-01-30 19:04:36 +00:00
else :
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
2023-01-30 19:04:36 +00:00
raise RuntimeError (
f " 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 { new_url [ 0 ] } { new_url [ 1 ] } (note the trailing slash), or set SMART_APPEND_SLASH=False in your Django settings. "
)
2011-07-11 02:10:22 +01:00
if new_url != old_url :
# Redirect
if new_url [ 0 ] :
2022-11-23 10:48:39 +00:00
newurl = f " { request . is_secure ( ) and ' https ' or ' http ' } :// { new_url [ 0 ] } { new_url [ 1 ] } "
2011-07-11 02:10:22 +01:00
else :
newurl = new_url [ 1 ]
if request . GET :
2023-01-30 19:04:36 +00:00
newurl + = " ? " + request . GET . urlencode ( )
2011-07-11 02:10:22 +01:00
return http . HttpResponsePermanentRedirect ( newurl )
return None
2023-01-30 19:04:36 +00:00
2011-07-11 02:10:22 +01:00
def _resolves ( url ) :
try :
2023-01-30 19:04:36 +00:00
# If the URL does not resolve, the function raises a Resolver404 exception (a subclass of Http404)
2023-01-30 23:04:11 +00:00
resolve ( url )
2021-03-31 17:57:43 +01:00
# this will ALWAYS be resolved by expopages because it will produce pagenotfound if not the thing asked for
2023-01-30 19:04:36 +00:00
# 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