Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/cherrypy/_cpchecker.py
diff options
context:
space:
mode:
Diffstat (limited to 'cherrypy/_cpchecker.py')
-rwxr-xr-xcherrypy/_cpchecker.py327
1 files changed, 0 insertions, 327 deletions
diff --git a/cherrypy/_cpchecker.py b/cherrypy/_cpchecker.py
deleted file mode 100755
index 7ccfd89..0000000
--- a/cherrypy/_cpchecker.py
+++ /dev/null
@@ -1,327 +0,0 @@
-import os
-import warnings
-
-import cherrypy
-from cherrypy._cpcompat import iteritems, copykeys, builtins
-
-
-class Checker(object):
- """A checker for CherryPy sites and their mounted applications.
-
- When this object is called at engine startup, it executes each
- of its own methods whose names start with ``check_``. If you wish
- to disable selected checks, simply add a line in your global
- config which sets the appropriate method to False::
-
- [global]
- checker.check_skipped_app_config = False
-
- You may also dynamically add or replace ``check_*`` methods in this way.
- """
-
- on = True
- """If True (the default), run all checks; if False, turn off all checks."""
-
-
- def __init__(self):
- self._populate_known_types()
-
- def __call__(self):
- """Run all check_* methods."""
- if self.on:
- oldformatwarning = warnings.formatwarning
- warnings.formatwarning = self.formatwarning
- try:
- for name in dir(self):
- if name.startswith("check_"):
- method = getattr(self, name)
- if method and hasattr(method, '__call__'):
- method()
- finally:
- warnings.formatwarning = oldformatwarning
-
- def formatwarning(self, message, category, filename, lineno, line=None):
- """Function to format a warning."""
- return "CherryPy Checker:\n%s\n\n" % message
-
- # This value should be set inside _cpconfig.
- global_config_contained_paths = False
-
- def check_app_config_entries_dont_start_with_script_name(self):
- """Check for Application config with sections that repeat script_name."""
- for sn, app in cherrypy.tree.apps.items():
- if not isinstance(app, cherrypy.Application):
- continue
- if not app.config:
- continue
- if sn == '':
- continue
- sn_atoms = sn.strip("/").split("/")
- for key in app.config.keys():
- key_atoms = key.strip("/").split("/")
- if key_atoms[:len(sn_atoms)] == sn_atoms:
- warnings.warn(
- "The application mounted at %r has config " \
- "entries that start with its script name: %r" % (sn, key))
-
- def check_site_config_entries_in_app_config(self):
- """Check for mounted Applications that have site-scoped config."""
- for sn, app in iteritems(cherrypy.tree.apps):
- if not isinstance(app, cherrypy.Application):
- continue
-
- msg = []
- for section, entries in iteritems(app.config):
- if section.startswith('/'):
- for key, value in iteritems(entries):
- for n in ("engine.", "server.", "tree.", "checker."):
- if key.startswith(n):
- msg.append("[%s] %s = %s" % (section, key, value))
- if msg:
- msg.insert(0,
- "The application mounted at %r contains the following "
- "config entries, which are only allowed in site-wide "
- "config. Move them to a [global] section and pass them "
- "to cherrypy.config.update() instead of tree.mount()." % sn)
- warnings.warn(os.linesep.join(msg))
-
- def check_skipped_app_config(self):
- """Check for mounted Applications that have no config."""
- for sn, app in cherrypy.tree.apps.items():
- if not isinstance(app, cherrypy.Application):
- continue
- if not app.config:
- msg = "The Application mounted at %r has an empty config." % sn
- if self.global_config_contained_paths:
- msg += (" It looks like the config you passed to "
- "cherrypy.config.update() contains application-"
- "specific sections. You must explicitly pass "
- "application config via "
- "cherrypy.tree.mount(..., config=app_config)")
- warnings.warn(msg)
- return
-
- def check_app_config_brackets(self):
- """Check for Application config with extraneous brackets in section names."""
- for sn, app in cherrypy.tree.apps.items():
- if not isinstance(app, cherrypy.Application):
- continue
- if not app.config:
- continue
- for key in app.config.keys():
- if key.startswith("[") or key.endswith("]"):
- warnings.warn(
- "The application mounted at %r has config " \
- "section names with extraneous brackets: %r. "
- "Config *files* need brackets; config *dicts* "
- "(e.g. passed to tree.mount) do not." % (sn, key))
-
- def check_static_paths(self):
- """Check Application config for incorrect static paths."""
- # Use the dummy Request object in the main thread.
- request = cherrypy.request
- for sn, app in cherrypy.tree.apps.items():
- if not isinstance(app, cherrypy.Application):
- continue
- request.app = app
- for section in app.config:
- # get_resource will populate request.config
- request.get_resource(section + "/dummy.html")
- conf = request.config.get
-
- if conf("tools.staticdir.on", False):
- msg = ""
- root = conf("tools.staticdir.root")
- dir = conf("tools.staticdir.dir")
- if dir is None:
- msg = "tools.staticdir.dir is not set."
- else:
- fulldir = ""
- if os.path.isabs(dir):
- fulldir = dir
- if root:
- msg = ("dir is an absolute path, even "
- "though a root is provided.")
- testdir = os.path.join(root, dir[1:])
- if os.path.exists(testdir):
- msg += ("\nIf you meant to serve the "
- "filesystem folder at %r, remove "
- "the leading slash from dir." % testdir)
- else:
- if not root:
- msg = "dir is a relative path and no root provided."
- else:
- fulldir = os.path.join(root, dir)
- if not os.path.isabs(fulldir):
- msg = "%r is not an absolute path." % fulldir
-
- if fulldir and not os.path.exists(fulldir):
- if msg:
- msg += "\n"
- msg += ("%r (root + dir) is not an existing "
- "filesystem path." % fulldir)
-
- if msg:
- warnings.warn("%s\nsection: [%s]\nroot: %r\ndir: %r"
- % (msg, section, root, dir))
-
-
- # -------------------------- Compatibility -------------------------- #
-
- obsolete = {
- 'server.default_content_type': 'tools.response_headers.headers',
- 'log_access_file': 'log.access_file',
- 'log_config_options': None,
- 'log_file': 'log.error_file',
- 'log_file_not_found': None,
- 'log_request_headers': 'tools.log_headers.on',
- 'log_to_screen': 'log.screen',
- 'show_tracebacks': 'request.show_tracebacks',
- 'throw_errors': 'request.throw_errors',
- 'profiler.on': ('cherrypy.tree.mount(profiler.make_app('
- 'cherrypy.Application(Root())))'),
- }
-
- deprecated = {}
-
- def _compat(self, config):
- """Process config and warn on each obsolete or deprecated entry."""
- for section, conf in config.items():
- if isinstance(conf, dict):
- for k, v in conf.items():
- if k in self.obsolete:
- warnings.warn("%r is obsolete. Use %r instead.\n"
- "section: [%s]" %
- (k, self.obsolete[k], section))
- elif k in self.deprecated:
- warnings.warn("%r is deprecated. Use %r instead.\n"
- "section: [%s]" %
- (k, self.deprecated[k], section))
- else:
- if section in self.obsolete:
- warnings.warn("%r is obsolete. Use %r instead."
- % (section, self.obsolete[section]))
- elif section in self.deprecated:
- warnings.warn("%r is deprecated. Use %r instead."
- % (section, self.deprecated[section]))
-
- def check_compatibility(self):
- """Process config and warn on each obsolete or deprecated entry."""
- self._compat(cherrypy.config)
- for sn, app in cherrypy.tree.apps.items():
- if not isinstance(app, cherrypy.Application):
- continue
- self._compat(app.config)
-
-
- # ------------------------ Known Namespaces ------------------------ #
-
- extra_config_namespaces = []
-
- def _known_ns(self, app):
- ns = ["wsgi"]
- ns.extend(copykeys(app.toolboxes))
- ns.extend(copykeys(app.namespaces))
- ns.extend(copykeys(app.request_class.namespaces))
- ns.extend(copykeys(cherrypy.config.namespaces))
- ns += self.extra_config_namespaces
-
- for section, conf in app.config.items():
- is_path_section = section.startswith("/")
- if is_path_section and isinstance(conf, dict):
- for k, v in conf.items():
- atoms = k.split(".")
- if len(atoms) > 1:
- if atoms[0] not in ns:
- # Spit out a special warning if a known
- # namespace is preceded by "cherrypy."
- if (atoms[0] == "cherrypy" and atoms[1] in ns):
- msg = ("The config entry %r is invalid; "
- "try %r instead.\nsection: [%s]"
- % (k, ".".join(atoms[1:]), section))
- else:
- msg = ("The config entry %r is invalid, because "
- "the %r config namespace is unknown.\n"
- "section: [%s]" % (k, atoms[0], section))
- warnings.warn(msg)
- elif atoms[0] == "tools":
- if atoms[1] not in dir(cherrypy.tools):
- msg = ("The config entry %r may be invalid, "
- "because the %r tool was not found.\n"
- "section: [%s]" % (k, atoms[1], section))
- warnings.warn(msg)
-
- def check_config_namespaces(self):
- """Process config and warn on each unknown config namespace."""
- for sn, app in cherrypy.tree.apps.items():
- if not isinstance(app, cherrypy.Application):
- continue
- self._known_ns(app)
-
-
-
-
- # -------------------------- Config Types -------------------------- #
-
- known_config_types = {}
-
- def _populate_known_types(self):
- b = [x for x in vars(builtins).values()
- if type(x) is type(str)]
-
- def traverse(obj, namespace):
- for name in dir(obj):
- # Hack for 3.2's warning about body_params
- if name == 'body_params':
- continue
- vtype = type(getattr(obj, name, None))
- if vtype in b:
- self.known_config_types[namespace + "." + name] = vtype
-
- traverse(cherrypy.request, "request")
- traverse(cherrypy.response, "response")
- traverse(cherrypy.server, "server")
- traverse(cherrypy.engine, "engine")
- traverse(cherrypy.log, "log")
-
- def _known_types(self, config):
- msg = ("The config entry %r in section %r is of type %r, "
- "which does not match the expected type %r.")
-
- for section, conf in config.items():
- if isinstance(conf, dict):
- for k, v in conf.items():
- if v is not None:
- expected_type = self.known_config_types.get(k, None)
- vtype = type(v)
- if expected_type and vtype != expected_type:
- warnings.warn(msg % (k, section, vtype.__name__,
- expected_type.__name__))
- else:
- k, v = section, conf
- if v is not None:
- expected_type = self.known_config_types.get(k, None)
- vtype = type(v)
- if expected_type and vtype != expected_type:
- warnings.warn(msg % (k, section, vtype.__name__,
- expected_type.__name__))
-
- def check_config_types(self):
- """Assert that config values are of the same type as default values."""
- self._known_types(cherrypy.config)
- for sn, app in cherrypy.tree.apps.items():
- if not isinstance(app, cherrypy.Application):
- continue
- self._known_types(app.config)
-
-
- # -------------------- Specific config warnings -------------------- #
-
- def check_localhost(self):
- """Warn if any socket_host is 'localhost'. See #711."""
- for k, v in cherrypy.config.items():
- if k == 'server.socket_host' and v == 'localhost':
- warnings.warn("The use of 'localhost' as a socket host can "
- "cause problems on newer systems, since 'localhost' can "
- "map to either an IPv4 or an IPv6 address. You should "
- "use '127.0.0.1' or '[::1]' instead.")