Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/websdk/werkzeug/debug/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'websdk/werkzeug/debug/__init__.py')
-rw-r--r--websdk/werkzeug/debug/__init__.py185
1 files changed, 185 insertions, 0 deletions
diff --git a/websdk/werkzeug/debug/__init__.py b/websdk/werkzeug/debug/__init__.py
new file mode 100644
index 0000000..db91b74
--- /dev/null
+++ b/websdk/werkzeug/debug/__init__.py
@@ -0,0 +1,185 @@
+# -*- coding: utf-8 -*-
+"""
+ werkzeug.debug
+ ~~~~~~~~~~~~~~
+
+ WSGI application traceback debugger.
+
+ :copyright: (c) 2011 by the Werkzeug Team, see AUTHORS for more details.
+ :license: BSD, see LICENSE for more details.
+"""
+import mimetypes
+from os.path import join, dirname, basename, isfile
+from werkzeug.wrappers import BaseRequest as Request, BaseResponse as Response
+from werkzeug.debug.tbtools import get_current_traceback, render_console_html
+from werkzeug.debug.console import Console
+from werkzeug.security import gen_salt
+
+
+#: import this here because it once was documented as being available
+#: from this module. In case there are users left ...
+from werkzeug.debug.repr import debug_repr
+
+
+class _ConsoleFrame(object):
+ """Helper class so that we can reuse the frame console code for the
+ standalone console.
+ """
+
+ def __init__(self, namespace):
+ self.console = Console(namespace)
+ self.id = 0
+
+
+class DebuggedApplication(object):
+ """Enables debugging support for a given application::
+
+ from werkzeug.debug import DebuggedApplication
+ from myapp import app
+ app = DebuggedApplication(app, evalex=True)
+
+ The `evalex` keyword argument allows evaluating expressions in a
+ traceback's frame context.
+
+ .. versionadded:: 0.7
+ The `lodgeit_url` parameter was added.
+
+ :param app: the WSGI application to run debugged.
+ :param evalex: enable exception evaluation feature (interactive
+ debugging). This requires a non-forking server.
+ :param request_key: The key that points to the request object in ths
+ environment. This parameter is ignored in current
+ versions.
+ :param console_path: the URL for a general purpose console.
+ :param console_init_func: the function that is executed before starting
+ the general purpose console. The return value
+ is used as initial namespace.
+ :param show_hidden_frames: by default hidden traceback frames are skipped.
+ You can show them by setting this parameter
+ to `True`.
+ :param lodgeit_url: the base URL of the LodgeIt instance to use for
+ pasting tracebacks.
+ """
+
+ # this class is public
+ __module__ = 'werkzeug'
+
+ def __init__(self, app, evalex=False, request_key='werkzeug.request',
+ console_path='/console', console_init_func=None,
+ show_hidden_frames=False,
+ lodgeit_url='http://paste.pocoo.org/'):
+ if not console_init_func:
+ console_init_func = dict
+ self.app = app
+ self.evalex = evalex
+ self.frames = {}
+ self.tracebacks = {}
+ self.request_key = request_key
+ self.console_path = console_path
+ self.console_init_func = console_init_func
+ self.show_hidden_frames = show_hidden_frames
+ self.lodgeit_url = lodgeit_url
+ self.secret = gen_salt(20)
+
+ def debug_application(self, environ, start_response):
+ """Run the application and conserve the traceback frames."""
+ app_iter = None
+ try:
+ app_iter = self.app(environ, start_response)
+ for item in app_iter:
+ yield item
+ if hasattr(app_iter, 'close'):
+ app_iter.close()
+ except Exception:
+ if hasattr(app_iter, 'close'):
+ app_iter.close()
+ traceback = get_current_traceback(skip=1, show_hidden_frames=
+ self.show_hidden_frames,
+ ignore_system_exceptions=True)
+ for frame in traceback.frames:
+ self.frames[frame.id] = frame
+ self.tracebacks[traceback.id] = traceback
+
+ try:
+ start_response('500 INTERNAL SERVER ERROR', [
+ ('Content-Type', 'text/html; charset=utf-8')
+ ])
+ except Exception:
+ # if we end up here there has been output but an error
+ # occurred. in that situation we can do nothing fancy any
+ # more, better log something into the error log and fall
+ # back gracefully.
+ environ['wsgi.errors'].write(
+ 'Debugging middleware caught exception in streamed '
+ 'response at a point where response headers were already '
+ 'sent.\n')
+ else:
+ yield traceback.render_full(evalex=self.evalex,
+ lodgeit_url=self.lodgeit_url,
+ secret=self.secret) \
+ .encode('utf-8', 'replace')
+
+ traceback.log(environ['wsgi.errors'])
+
+ def execute_command(self, request, command, frame):
+ """Execute a command in a console."""
+ return Response(frame.console.eval(command), mimetype='text/html')
+
+ def display_console(self, request):
+ """Display a standalone shell."""
+ if 0 not in self.frames:
+ self.frames[0] = _ConsoleFrame(self.console_init_func())
+ return Response(render_console_html(secret=self.secret),
+ mimetype='text/html')
+
+ def paste_traceback(self, request, traceback):
+ """Paste the traceback and return a JSON response."""
+ paste_id = traceback.paste(self.lodgeit_url)
+ return Response('{"url": "%sshow/%s/", "id": "%s"}'
+ % (self.lodgeit_url, paste_id, paste_id),
+ mimetype='application/json')
+
+ def get_source(self, request, frame):
+ """Render the source viewer."""
+ return Response(frame.render_source(), mimetype='text/html')
+
+ def get_resource(self, request, filename):
+ """Return a static resource from the shared folder."""
+ filename = join(dirname(__file__), 'shared', basename(filename))
+ if isfile(filename):
+ mimetype = mimetypes.guess_type(filename)[0] \
+ or 'application/octet-stream'
+ f = file(filename, 'rb')
+ try:
+ return Response(f.read(), mimetype=mimetype)
+ finally:
+ f.close()
+ return Response('Not Found', status=404)
+
+ def __call__(self, environ, start_response):
+ """Dispatch the requests."""
+ # important: don't ever access a function here that reads the incoming
+ # form data! Otherwise the application won't have access to that data
+ # any more!
+ request = Request(environ)
+ response = self.debug_application
+ if request.args.get('__debugger__') == 'yes':
+ cmd = request.args.get('cmd')
+ arg = request.args.get('f')
+ secret = request.args.get('s')
+ traceback = self.tracebacks.get(request.args.get('tb', type=int))
+ frame = self.frames.get(request.args.get('frm', type=int))
+ if cmd == 'resource' and arg:
+ response = self.get_resource(request, arg)
+ elif cmd == 'paste' and traceback is not None and \
+ secret == self.secret:
+ response = self.paste_traceback(request, traceback)
+ elif cmd == 'source' and frame and self.secret == secret:
+ response = self.get_source(request, frame)
+ elif self.evalex and cmd is not None and frame is not None and \
+ self.secret == secret:
+ response = self.execute_command(request, cmd, frame)
+ elif self.evalex and self.console_path is not None and \
+ request.path == self.console_path:
+ response = self.display_console(request)
+ return response(environ, start_response)