1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/OpenSecurity/install/web.py-0.37/build/lib/web/debugerror.py Mon Dec 02 14:02:05 2013 +0100
1.3 @@ -0,0 +1,354 @@
1.4 +"""
1.5 +pretty debug errors
1.6 +(part of web.py)
1.7 +
1.8 +portions adapted from Django <djangoproject.com>
1.9 +Copyright (c) 2005, the Lawrence Journal-World
1.10 +Used under the modified BSD license:
1.11 +http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
1.12 +"""
1.13 +
1.14 +__all__ = ["debugerror", "djangoerror", "emailerrors"]
1.15 +
1.16 +import sys, urlparse, pprint, traceback
1.17 +from template import Template
1.18 +from net import websafe
1.19 +from utils import sendmail, safestr
1.20 +import webapi as web
1.21 +
1.22 +import os, os.path
1.23 +whereami = os.path.join(os.getcwd(), __file__)
1.24 +whereami = os.path.sep.join(whereami.split(os.path.sep)[:-1])
1.25 +djangoerror_t = """\
1.26 +$def with (exception_type, exception_value, frames)
1.27 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
1.28 +<html lang="en">
1.29 +<head>
1.30 + <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1.31 + <meta name="robots" content="NONE,NOARCHIVE" />
1.32 + <title>$exception_type at $ctx.path</title>
1.33 + <style type="text/css">
1.34 + html * { padding:0; margin:0; }
1.35 + body * { padding:10px 20px; }
1.36 + body * * { padding:0; }
1.37 + body { font:small sans-serif; }
1.38 + body>div { border-bottom:1px solid #ddd; }
1.39 + h1 { font-weight:normal; }
1.40 + h2 { margin-bottom:.8em; }
1.41 + h2 span { font-size:80%; color:#666; font-weight:normal; }
1.42 + h3 { margin:1em 0 .5em 0; }
1.43 + h4 { margin:0 0 .5em 0; font-weight: normal; }
1.44 + table {
1.45 + border:1px solid #ccc; border-collapse: collapse; background:white; }
1.46 + tbody td, tbody th { vertical-align:top; padding:2px 3px; }
1.47 + thead th {
1.48 + padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
1.49 + font-weight:normal; font-size:11px; border:1px solid #ddd; }
1.50 + tbody th { text-align:right; color:#666; padding-right:.5em; }
1.51 + table.vars { margin:5px 0 2px 40px; }
1.52 + table.vars td, table.req td { font-family:monospace; }
1.53 + table td.code { width:100%;}
1.54 + table td.code div { overflow:hidden; }
1.55 + table.source th { color:#666; }
1.56 + table.source td {
1.57 + font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
1.58 + ul.traceback { list-style-type:none; }
1.59 + ul.traceback li.frame { margin-bottom:1em; }
1.60 + div.context { margin: 10px 0; }
1.61 + div.context ol {
1.62 + padding-left:30px; margin:0 10px; list-style-position: inside; }
1.63 + div.context ol li {
1.64 + font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
1.65 + div.context ol.context-line li { color:black; background-color:#ccc; }
1.66 + div.context ol.context-line li span { float: right; }
1.67 + div.commands { margin-left: 40px; }
1.68 + div.commands a { color:black; text-decoration:none; }
1.69 + #summary { background: #ffc; }
1.70 + #summary h2 { font-weight: normal; color: #666; }
1.71 + #explanation { background:#eee; }
1.72 + #template, #template-not-exist { background:#f6f6f6; }
1.73 + #template-not-exist ul { margin: 0 0 0 20px; }
1.74 + #traceback { background:#eee; }
1.75 + #requestinfo { background:#f6f6f6; padding-left:120px; }
1.76 + #summary table { border:none; background:transparent; }
1.77 + #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
1.78 + #requestinfo h3 { margin-bottom:-1em; }
1.79 + .error { background: #ffc; }
1.80 + .specific { color:#cc3300; font-weight:bold; }
1.81 + </style>
1.82 + <script type="text/javascript">
1.83 + //<!--
1.84 + function getElementsByClassName(oElm, strTagName, strClassName){
1.85 + // Written by Jonathan Snook, http://www.snook.ca/jon;
1.86 + // Add-ons by Robert Nyman, http://www.robertnyman.com
1.87 + var arrElements = (strTagName == "*" && document.all)? document.all :
1.88 + oElm.getElementsByTagName(strTagName);
1.89 + var arrReturnElements = new Array();
1.90 + strClassName = strClassName.replace(/\-/g, "\\-");
1.91 + var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$$)");
1.92 + var oElement;
1.93 + for(var i=0; i<arrElements.length; i++){
1.94 + oElement = arrElements[i];
1.95 + if(oRegExp.test(oElement.className)){
1.96 + arrReturnElements.push(oElement);
1.97 + }
1.98 + }
1.99 + return (arrReturnElements)
1.100 + }
1.101 + function hideAll(elems) {
1.102 + for (var e = 0; e < elems.length; e++) {
1.103 + elems[e].style.display = 'none';
1.104 + }
1.105 + }
1.106 + window.onload = function() {
1.107 + hideAll(getElementsByClassName(document, 'table', 'vars'));
1.108 + hideAll(getElementsByClassName(document, 'ol', 'pre-context'));
1.109 + hideAll(getElementsByClassName(document, 'ol', 'post-context'));
1.110 + }
1.111 + function toggle() {
1.112 + for (var i = 0; i < arguments.length; i++) {
1.113 + var e = document.getElementById(arguments[i]);
1.114 + if (e) {
1.115 + e.style.display = e.style.display == 'none' ? 'block' : 'none';
1.116 + }
1.117 + }
1.118 + return false;
1.119 + }
1.120 + function varToggle(link, id) {
1.121 + toggle('v' + id);
1.122 + var s = link.getElementsByTagName('span')[0];
1.123 + var uarr = String.fromCharCode(0x25b6);
1.124 + var darr = String.fromCharCode(0x25bc);
1.125 + s.innerHTML = s.innerHTML == uarr ? darr : uarr;
1.126 + return false;
1.127 + }
1.128 + //-->
1.129 + </script>
1.130 +</head>
1.131 +<body>
1.132 +
1.133 +$def dicttable (d, kls='req', id=None):
1.134 + $ items = d and d.items() or []
1.135 + $items.sort()
1.136 + $:dicttable_items(items, kls, id)
1.137 +
1.138 +$def dicttable_items(items, kls='req', id=None):
1.139 + $if items:
1.140 + <table class="$kls"
1.141 + $if id: id="$id"
1.142 + ><thead><tr><th>Variable</th><th>Value</th></tr></thead>
1.143 + <tbody>
1.144 + $for k, v in items:
1.145 + <tr><td>$k</td><td class="code"><div>$prettify(v)</div></td></tr>
1.146 + </tbody>
1.147 + </table>
1.148 + $else:
1.149 + <p>No data.</p>
1.150 +
1.151 +<div id="summary">
1.152 + <h1>$exception_type at $ctx.path</h1>
1.153 + <h2>$exception_value</h2>
1.154 + <table><tr>
1.155 + <th>Python</th>
1.156 + <td>$frames[0].filename in $frames[0].function, line $frames[0].lineno</td>
1.157 + </tr><tr>
1.158 + <th>Web</th>
1.159 + <td>$ctx.method $ctx.home$ctx.path</td>
1.160 + </tr></table>
1.161 +</div>
1.162 +<div id="traceback">
1.163 +<h2>Traceback <span>(innermost first)</span></h2>
1.164 +<ul class="traceback">
1.165 +$for frame in frames:
1.166 + <li class="frame">
1.167 + <code>$frame.filename</code> in <code>$frame.function</code>
1.168 + $if frame.context_line is not None:
1.169 + <div class="context" id="c$frame.id">
1.170 + $if frame.pre_context:
1.171 + <ol start="$frame.pre_context_lineno" class="pre-context" id="pre$frame.id">
1.172 + $for line in frame.pre_context:
1.173 + <li onclick="toggle('pre$frame.id', 'post$frame.id')">$line</li>
1.174 + </ol>
1.175 + <ol start="$frame.lineno" class="context-line"><li onclick="toggle('pre$frame.id', 'post$frame.id')">$frame.context_line <span>...</span></li></ol>
1.176 + $if frame.post_context:
1.177 + <ol start='${frame.lineno + 1}' class="post-context" id="post$frame.id">
1.178 + $for line in frame.post_context:
1.179 + <li onclick="toggle('pre$frame.id', 'post$frame.id')">$line</li>
1.180 + </ol>
1.181 + </div>
1.182 +
1.183 + $if frame.vars:
1.184 + <div class="commands">
1.185 + <a href='#' onclick="return varToggle(this, '$frame.id')"><span>▶</span> Local vars</a>
1.186 + $# $inspect.formatargvalues(*inspect.getargvalues(frame['tb'].tb_frame))
1.187 + </div>
1.188 + $:dicttable(frame.vars, kls='vars', id=('v' + str(frame.id)))
1.189 + </li>
1.190 + </ul>
1.191 +</div>
1.192 +
1.193 +<div id="requestinfo">
1.194 +$if ctx.output or ctx.headers:
1.195 + <h2>Response so far</h2>
1.196 + <h3>HEADERS</h3>
1.197 + $:dicttable_items(ctx.headers)
1.198 +
1.199 + <h3>BODY</h3>
1.200 + <p class="req" style="padding-bottom: 2em"><code>
1.201 + $ctx.output
1.202 + </code></p>
1.203 +
1.204 +<h2>Request information</h2>
1.205 +
1.206 +<h3>INPUT</h3>
1.207 +$:dicttable(web.input(_unicode=False))
1.208 +
1.209 +<h3 id="cookie-info">COOKIES</h3>
1.210 +$:dicttable(web.cookies())
1.211 +
1.212 +<h3 id="meta-info">META</h3>
1.213 +$ newctx = [(k, v) for (k, v) in ctx.iteritems() if not k.startswith('_') and not isinstance(v, dict)]
1.214 +$:dicttable(dict(newctx))
1.215 +
1.216 +<h3 id="meta-info">ENVIRONMENT</h3>
1.217 +$:dicttable(ctx.env)
1.218 +</div>
1.219 +
1.220 +<div id="explanation">
1.221 + <p>
1.222 + You're seeing this error because you have <code>web.config.debug</code>
1.223 + set to <code>True</code>. Set that to <code>False</code> if you don't want to see this.
1.224 + </p>
1.225 +</div>
1.226 +
1.227 +</body>
1.228 +</html>
1.229 +"""
1.230 +
1.231 +djangoerror_r = None
1.232 +
1.233 +def djangoerror():
1.234 + def _get_lines_from_file(filename, lineno, context_lines):
1.235 + """
1.236 + Returns context_lines before and after lineno from file.
1.237 + Returns (pre_context_lineno, pre_context, context_line, post_context).
1.238 + """
1.239 + try:
1.240 + source = open(filename).readlines()
1.241 + lower_bound = max(0, lineno - context_lines)
1.242 + upper_bound = lineno + context_lines
1.243 +
1.244 + pre_context = \
1.245 + [line.strip('\n') for line in source[lower_bound:lineno]]
1.246 + context_line = source[lineno].strip('\n')
1.247 + post_context = \
1.248 + [line.strip('\n') for line in source[lineno + 1:upper_bound]]
1.249 +
1.250 + return lower_bound, pre_context, context_line, post_context
1.251 + except (OSError, IOError, IndexError):
1.252 + return None, [], None, []
1.253 +
1.254 + exception_type, exception_value, tback = sys.exc_info()
1.255 + frames = []
1.256 + while tback is not None:
1.257 + filename = tback.tb_frame.f_code.co_filename
1.258 + function = tback.tb_frame.f_code.co_name
1.259 + lineno = tback.tb_lineno - 1
1.260 +
1.261 + # hack to get correct line number for templates
1.262 + lineno += tback.tb_frame.f_locals.get("__lineoffset__", 0)
1.263 +
1.264 + pre_context_lineno, pre_context, context_line, post_context = \
1.265 + _get_lines_from_file(filename, lineno, 7)
1.266 +
1.267 + if '__hidetraceback__' not in tback.tb_frame.f_locals:
1.268 + frames.append(web.storage({
1.269 + 'tback': tback,
1.270 + 'filename': filename,
1.271 + 'function': function,
1.272 + 'lineno': lineno,
1.273 + 'vars': tback.tb_frame.f_locals,
1.274 + 'id': id(tback),
1.275 + 'pre_context': pre_context,
1.276 + 'context_line': context_line,
1.277 + 'post_context': post_context,
1.278 + 'pre_context_lineno': pre_context_lineno,
1.279 + }))
1.280 + tback = tback.tb_next
1.281 + frames.reverse()
1.282 + urljoin = urlparse.urljoin
1.283 + def prettify(x):
1.284 + try:
1.285 + out = pprint.pformat(x)
1.286 + except Exception, e:
1.287 + out = '[could not display: <' + e.__class__.__name__ + \
1.288 + ': '+str(e)+'>]'
1.289 + return out
1.290 +
1.291 + global djangoerror_r
1.292 + if djangoerror_r is None:
1.293 + djangoerror_r = Template(djangoerror_t, filename=__file__, filter=websafe)
1.294 +
1.295 + t = djangoerror_r
1.296 + globals = {'ctx': web.ctx, 'web':web, 'dict':dict, 'str':str, 'prettify': prettify}
1.297 + t.t.func_globals.update(globals)
1.298 + return t(exception_type, exception_value, frames)
1.299 +
1.300 +def debugerror():
1.301 + """
1.302 + A replacement for `internalerror` that presents a nice page with lots
1.303 + of debug information for the programmer.
1.304 +
1.305 + (Based on the beautiful 500 page from [Django](http://djangoproject.com/),
1.306 + designed by [Wilson Miner](http://wilsonminer.com/).)
1.307 + """
1.308 + return web._InternalError(djangoerror())
1.309 +
1.310 +def emailerrors(to_address, olderror, from_address=None):
1.311 + """
1.312 + Wraps the old `internalerror` handler (pass as `olderror`) to
1.313 + additionally email all errors to `to_address`, to aid in
1.314 + debugging production websites.
1.315 +
1.316 + Emails contain a normal text traceback as well as an
1.317 + attachment containing the nice `debugerror` page.
1.318 + """
1.319 + from_address = from_address or to_address
1.320 +
1.321 + def emailerrors_internal():
1.322 + error = olderror()
1.323 + tb = sys.exc_info()
1.324 + error_name = tb[0]
1.325 + error_value = tb[1]
1.326 + tb_txt = ''.join(traceback.format_exception(*tb))
1.327 + path = web.ctx.path
1.328 + request = web.ctx.method + ' ' + web.ctx.home + web.ctx.fullpath
1.329 +
1.330 + message = "\n%s\n\n%s\n\n" % (request, tb_txt)
1.331 +
1.332 + sendmail(
1.333 + "your buggy site <%s>" % from_address,
1.334 + "the bugfixer <%s>" % to_address,
1.335 + "bug: %(error_name)s: %(error_value)s (%(path)s)" % locals(),
1.336 + message,
1.337 + attachments=[
1.338 + dict(filename="bug.html", content=safestr(djangoerror()))
1.339 + ],
1.340 + )
1.341 + return error
1.342 +
1.343 + return emailerrors_internal
1.344 +
1.345 +if __name__ == "__main__":
1.346 + urls = (
1.347 + '/', 'index'
1.348 + )
1.349 + from application import application
1.350 + app = application(urls, globals())
1.351 + app.internalerror = debugerror
1.352 +
1.353 + class index:
1.354 + def GET(self):
1.355 + thisdoesnotexist
1.356 +
1.357 + app.run()