router debug option, thanks Jonathan
This commit is contained in:
@@ -1 +1 @@
|
||||
Version 1.99.3 (2011-11-30 22:09:17) dev
|
||||
Version 1.99.3 (2011-11-30 22:23:02) dev
|
||||
|
||||
+45
-18
@@ -69,6 +69,7 @@ def _params_default(app=None):
|
||||
p.error_message_ticket = \
|
||||
'<html><body><h1>Internal error</h1>Ticket issued: <a href="/admin/default/ticket/%(ticket)s" target="_blank">%(ticket)s</a></body><!-- this is junk text else IE does not display the page: '+('x'*512)+' //--></html>'
|
||||
p.routers = None
|
||||
p.logging = 'off'
|
||||
return p
|
||||
|
||||
params_apps = dict()
|
||||
@@ -76,6 +77,25 @@ params = _params_default(app=None) # regex rewrite parameters
|
||||
thread.routes = params # default to base regex rewrite parameters
|
||||
routers = None
|
||||
|
||||
def log_rewrite(string):
|
||||
"Log rewrite activity under control of routes.py"
|
||||
if params.logging == 'debug': # catch common cases first
|
||||
logger.debug(string)
|
||||
elif params.logging == 'off' or not params.logging:
|
||||
pass
|
||||
elif params.logging == 'print':
|
||||
print string
|
||||
elif params.logging == 'info':
|
||||
logger.info(string)
|
||||
elif params.logging == 'warning':
|
||||
logger.warning(string)
|
||||
elif params.logging == 'error':
|
||||
logger.error(string)
|
||||
elif params.logging == 'critical':
|
||||
logger.critical(string)
|
||||
else:
|
||||
logger.debug(string)
|
||||
|
||||
ROUTER_KEYS = set(('default_application', 'applications', 'default_controller', 'controllers',
|
||||
'default_function', 'functions', 'default_language', 'languages',
|
||||
'domain', 'domains', 'root_static', 'path_prefix',
|
||||
@@ -254,7 +274,8 @@ def load(routes='routes.py', app=None, data=None, rdict=None):
|
||||
p[sym].append(compile_regex(k, v))
|
||||
for sym in ('routes_onerror', 'routes_apps_raw',
|
||||
'error_handler','error_message', 'error_message_ticket',
|
||||
'default_application','default_controller', 'default_function'):
|
||||
'default_application','default_controller', 'default_function',
|
||||
'logging'):
|
||||
if sym in symbols:
|
||||
p[sym] = symbols[sym]
|
||||
if 'routers' in symbols:
|
||||
@@ -307,7 +328,7 @@ def load(routes='routes.py', app=None, data=None, rdict=None):
|
||||
if app in p.routers:
|
||||
routers[app].update(p.routers[app])
|
||||
|
||||
logger.debug('URL rewrite is on. configuration in %s' % path)
|
||||
log_rewrite('URL rewrite is on. configuration in %s' % path)
|
||||
|
||||
|
||||
regex_at = re.compile(r'(?<!\\)\$[a-zA-Z]\w*')
|
||||
@@ -460,9 +481,9 @@ def regex_uri(e, regexes, tag, default=None):
|
||||
for (regex, value) in regexes:
|
||||
if regex.match(key):
|
||||
rewritten = regex.sub(value, key)
|
||||
logger.debug('%s: [%s] [%s] -> %s' % (tag, key, value, rewritten))
|
||||
log_rewrite('%s: [%s] [%s] -> %s' % (tag, key, value, rewritten))
|
||||
return rewritten
|
||||
logger.debug('%s: [%s] -> %s (not rewritten)' % (tag, key, default))
|
||||
log_rewrite('%s: [%s] -> %s (not rewritten)' % (tag, key, default))
|
||||
return default
|
||||
|
||||
def regex_select(env=None, app=None, request=None):
|
||||
@@ -479,7 +500,7 @@ def regex_select(env=None, app=None, request=None):
|
||||
thread.routes = params_apps.get(app, params)
|
||||
else:
|
||||
thread.routes = params # default to base rewrite parameters
|
||||
logger.debug("select routing parameters: %s" % thread.routes.name)
|
||||
log_rewrite("select routing parameters: %s" % thread.routes.name)
|
||||
return app # for doctest
|
||||
|
||||
def regex_filter_in(e):
|
||||
@@ -643,9 +664,9 @@ def regex_filter_out(url, e=None):
|
||||
for (regex, value) in thread.routes.routes_out:
|
||||
if regex.match(items[0]):
|
||||
rewritten = '?'.join([regex.sub(value, items[0])] + items[1:])
|
||||
logger.debug('routes_out: [%s] -> %s' % (url, rewritten))
|
||||
log_rewrite('routes_out: [%s] -> %s' % (url, rewritten))
|
||||
return rewritten
|
||||
logger.debug('routes_out: [%s] not rewritten' % url)
|
||||
log_rewrite('routes_out: [%s] not rewritten' % url)
|
||||
return url
|
||||
|
||||
|
||||
@@ -660,6 +681,8 @@ def filter_url(url, method='get', remote='0.0.0.0', out=False, app=False, lang=N
|
||||
k = uri.find('?')
|
||||
if k < 0:
|
||||
k = len(uri)
|
||||
if isinstance(domain, str):
|
||||
domain = (domain, None)
|
||||
(path_info, query_string) = (uri[:k], uri[k+1:])
|
||||
path_info = urllib.unquote(path_info) # simulate server
|
||||
e = {
|
||||
@@ -855,7 +878,7 @@ class MapUrlIn(object):
|
||||
|
||||
# set the application router
|
||||
#
|
||||
logger.debug("select application=%s" % self.application)
|
||||
log_rewrite("select application=%s" % self.application)
|
||||
self.request.application = self.application
|
||||
if self.application not in routers:
|
||||
self.router = routers.BASE # support gluon.main.wsgibase init->welcome
|
||||
@@ -884,7 +907,7 @@ class MapUrlIn(object):
|
||||
root_static_file = os.path.join(self.request.env.applications_parent,
|
||||
'applications', self.application,
|
||||
self.controller, self.arg0)
|
||||
logger.debug("route: root static=%s" % root_static_file)
|
||||
log_rewrite("route: root static=%s" % root_static_file)
|
||||
return root_static_file
|
||||
return None
|
||||
|
||||
@@ -896,7 +919,7 @@ class MapUrlIn(object):
|
||||
else:
|
||||
self.language = self.default_language
|
||||
if self.language:
|
||||
logger.debug("route: language=%s" % self.language)
|
||||
log_rewrite("route: language=%s" % self.language)
|
||||
self.pop_arg_if(self.language == arg0)
|
||||
arg0 = self.arg0
|
||||
|
||||
@@ -910,7 +933,7 @@ class MapUrlIn(object):
|
||||
else:
|
||||
self.controller = arg0
|
||||
self.pop_arg_if(arg0 == self.controller)
|
||||
logger.debug("route: controller=%s" % self.controller)
|
||||
log_rewrite("route: controller=%s" % self.controller)
|
||||
if not self.router._acfe_match.match(self.controller):
|
||||
raise HTTP(400, thread.routes.error_message % 'invalid request',
|
||||
web2py_error='invalid controller')
|
||||
@@ -939,7 +962,7 @@ class MapUrlIn(object):
|
||||
static_file = os.path.join(self.request.env.applications_parent,
|
||||
'applications', self.application,
|
||||
'static', file)
|
||||
logger.debug("route: static=%s" % static_file)
|
||||
log_rewrite("route: static=%s" % static_file)
|
||||
return static_file
|
||||
|
||||
def map_function(self):
|
||||
@@ -962,7 +985,7 @@ class MapUrlIn(object):
|
||||
else:
|
||||
self.function = arg0
|
||||
self.pop_arg_if(True)
|
||||
logger.debug("route: function.ext=%s.%s" % (self.function, self.extension))
|
||||
log_rewrite("route: function.ext=%s.%s" % (self.function, self.extension))
|
||||
|
||||
if not self.router._acfe_match.match(self.function):
|
||||
raise HTTP(400, thread.routes.error_message % 'invalid request',
|
||||
@@ -1117,22 +1140,26 @@ class MapUrlOut(object):
|
||||
#
|
||||
# because we presume the lang string to be unambiguous, its presence protects application omission
|
||||
#
|
||||
if self.exclusive_domain:
|
||||
applications = [self.domain_application]
|
||||
else:
|
||||
applications = self.applications
|
||||
if self.omit_language:
|
||||
if not self.applications or self.controller in self.applications:
|
||||
if not applications or self.controller in applications:
|
||||
self.omit_application = False
|
||||
if self.omit_application:
|
||||
if not self.applications or self.function in self.applications:
|
||||
if not applications or self.function in applications:
|
||||
self.omit_controller = False
|
||||
if not self.controllers or self.function in self.controllers:
|
||||
self.omit_controller = False
|
||||
if self.args:
|
||||
if self.args[0] in self.functions or self.args[0] in self.controllers or self.args[0] in self.applications:
|
||||
if self.args[0] in self.functions or self.args[0] in self.controllers or self.args[0] in applications:
|
||||
self.omit_function = False
|
||||
if self.omit_controller:
|
||||
if self.function in self.controllers or self.function in self.applications:
|
||||
if self.function in self.controllers or self.function in applications:
|
||||
self.omit_controller = False
|
||||
if self.omit_application:
|
||||
if self.controller in self.applications:
|
||||
if self.controller in applications:
|
||||
self.omit_application = False
|
||||
|
||||
# handle static as a special case
|
||||
|
||||
@@ -30,12 +30,14 @@ def setUpModule():
|
||||
"build a temporary applications tree"
|
||||
# applications/
|
||||
os.mkdir(abspath('applications'))
|
||||
|
||||
# applications/app/
|
||||
for app in ('admin', 'examples', 'welcome'):
|
||||
os.mkdir(abspath('applications', app))
|
||||
# applications/app/(controllers, static)
|
||||
for subdir in ('controllers', 'static'):
|
||||
os.mkdir(abspath('applications', app, subdir))
|
||||
|
||||
# applications/admin/controllers/*.py
|
||||
for ctr in ('appadmin', 'default', 'gae', 'mercurial', 'shell', 'wizard'):
|
||||
open(abspath('applications', 'admin', 'controllers', '%s.py' % ctr), 'w').close()
|
||||
@@ -855,6 +857,7 @@ class TestRouter(unittest.TestCase):
|
||||
Test REQUEST_URI in env
|
||||
'''
|
||||
load(rdict=dict())
|
||||
|
||||
self.assertEqual(filter_url('http://domain.com/abc', env=True).request_uri,
|
||||
'/init/default/abc')
|
||||
self.assertEqual(filter_url('http://domain.com/abc?def', env=True).request_uri,
|
||||
@@ -866,6 +869,49 @@ class TestRouter(unittest.TestCase):
|
||||
self.assertEqual(filter_url('http://domain.com/index/a%20bc', env=True).request_uri,
|
||||
"/init/default/index/a%20bc")
|
||||
|
||||
def test_request_collide(self):
|
||||
'''
|
||||
Test controller-app name collision: admin vs welcome/admin
|
||||
'''
|
||||
router_collide = dict(
|
||||
BASE = dict(
|
||||
domains = {
|
||||
'ex.domain.com' : 'examples',
|
||||
'ad.domain.com' : 'admin',
|
||||
'welcome.com' : 'welcome',
|
||||
'www.welcome.com' : 'welcome',
|
||||
},
|
||||
exclusive_domain=True,
|
||||
),
|
||||
)
|
||||
load(rdict=router_collide)
|
||||
|
||||
# basic inbound
|
||||
self.assertEqual(filter_url('http://ex.domain.com'), '/examples/default/exdef')
|
||||
self.assertEqual(filter_url('http://ad.domain.com'), '/admin/default/index')
|
||||
self.assertEqual(filter_url('http://welcome.com'), '/welcome/default/index')
|
||||
self.assertEqual(filter_url('http://www.welcome.com'), '/welcome/default/index')
|
||||
# basic outbound
|
||||
self.assertEqual(filter_url('http://ex.domain.com/examples/default/exdef', domain='examples', out=True), "/")
|
||||
self.assertEqual(filter_url('http://ad.domain.com/admin/default/index', domain='admin', out=True), "/")
|
||||
self.assertEqual(filter_url('http://welcome.com/welcome/default/index', domain='welcome', out=True), "/")
|
||||
self.assertEqual(filter_url('http://www.welcome.com/welcome/default/index', domain='welcome', out=True), "/")
|
||||
|
||||
# inbound
|
||||
self.assertEqual(filter_url('http://welcome.com/admin'), '/welcome/admin/index')
|
||||
self.assertEqual(filter_url('http://welcome.com/f1'), '/welcome/default/f1')
|
||||
self.assertEqual(filter_url('http://ad.domain.com/shell'), '/admin/shell/index')
|
||||
self.assertEqual(filter_url('http://ad.domain.com/f1'), '/admin/default/f1')
|
||||
# outbound
|
||||
self.assertEqual(filter_url('http://welcome.com/welcome/other/index', domain='welcome', out=True), "/other")
|
||||
self.assertEqual(filter_url('http://welcome.com/welcome/admin/index', domain='welcome', out=True), "/admin")
|
||||
self.assertEqual(filter_url('http://ad.domain.com/admin/shell/index', domain='admin', out=True), "/shell")
|
||||
self.assertEqual(filter_url('http://ad.domain.com/admin/default/f1', domain='admin', out=True), "/f1")
|
||||
router_collide['BASE']['exclusive_domain'] = False
|
||||
load(rdict=router_collide)
|
||||
self.assertEqual(filter_url('http://welcome.com/welcome/admin/index', domain='welcome', out=True), "/welcome/admin")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setUpModule() # pre-2.7
|
||||
unittest.main()
|
||||
|
||||
@@ -103,6 +103,12 @@ routers = dict(
|
||||
),
|
||||
)
|
||||
|
||||
# Specify log level for rewrite's debug logging
|
||||
# Possible values: debug, info, warning, error, critical (loglevels),
|
||||
# off, print (print uses print statement rather than logging)
|
||||
# GAE users may want to use 'off' to suppress routine logging.
|
||||
#
|
||||
logging = 'debug'
|
||||
|
||||
# Error-handling redirects all HTTP errors (status codes >= 400) to a specified
|
||||
# path. If you wish to use error-handling redirects, uncomment the tuple
|
||||
|
||||
@@ -42,6 +42,13 @@ routes_in = ((r'.*:/favicon.ico', r'/examples/static/favicon.ico'),
|
||||
routes_out = ((r'.*http://otherdomain.com.* /app/ctr(?P<any>.*)', r'\g<any>'),
|
||||
(r'/app(?P<any>.*)', r'\g<any>'))
|
||||
|
||||
# Specify log level for rewrite's debug logging
|
||||
# Possible values: debug, info, warning, error, critical (loglevels),
|
||||
# off, print (print uses print statement rather than logging)
|
||||
# GAE users may want to use 'off' to suppress routine logging.
|
||||
#
|
||||
logging = 'debug'
|
||||
|
||||
# Error-handling redirects all HTTP errors (status codes >= 400) to a specified
|
||||
# path. If you wish to use error-handling redirects, uncomment the tuple
|
||||
# below. You can customize responses by adding a tuple entry with the first
|
||||
|
||||
Reference in New Issue
Block a user