-def show_error(op, username, fields, err, emsg, traceback):
- """Print an error page when an exception occurs"""
- d = dict(op=op, user=username, fields=fields,
- errorMessage=str(err), stderr=emsg, traceback=traceback)
- details = templates.error_raw(searchList=[d])
- exclude = config.web.errormail_exclude
- if username not in exclude and '*' not in exclude:
- send_error_mail('xvm error on %s for %s: %s' % (op, username, err),
- details)
- d['details'] = details
- return templates.error(searchList=[d])
-
-def handler(username, state, path, fields):
- operation, path = pathSplit(path)
- if not operation:
- operation = 'list'
- print 'Starting', operation
- fun = mapping.get(operation, badOperation)
- return fun(username, state, path, fields)
-
-class App:
- def __init__(self, environ, start_response):
- self.environ = environ
- self.start = start_response
-
- self.username = getUser(environ)
- self.state = State(self.username)
- self.state.environ = environ
-
- random.seed() #sigh
-
- def __iter__(self):
- start_time = time.time()
- database.clear_cache()
- sys.stderr = StringIO()
- fields = cgi.FieldStorage(fp=self.environ['wsgi.input'], environ=self.environ)
- operation = self.environ.get('PATH_INFO', '')
- if not operation:
- self.start("301 Moved Permanently", [('Location', './')])
- return
- if self.username is None:
- operation = 'unauth'
-
- try:
- checkpoint.checkpoint('Before')
- output = handler(self.username, self.state, operation, fields)
- checkpoint.checkpoint('After')
-
- headers = dict(DEFAULT_HEADERS)
- if isinstance(output, tuple):
- new_headers, output = output
- headers.update(new_headers)
- e = revertStandardError()
- if e:
- if hasattr(output, 'addError'):
- output.addError(e)
- else:
- # This only happens on redirects, so it'd be a pain to get
- # the message to the user. Maybe in the response is useful.
- output = output + '\n\nstderr:\n' + e
- output_string = str(output)
- checkpoint.checkpoint('output as a string')
- except Exception, err:
- if not fields.has_key('js'):
- if isinstance(err, InvalidInput):
- self.start('200 OK', [('Content-Type', 'text/html')])
- e = revertStandardError()
- yield str(invalidInput(operation, self.username, fields,
- err, e))
- return
- import traceback
- self.start('500 Internal Server Error',
- [('Content-Type', 'text/html')])
- e = revertStandardError()
- s = show_error(operation, self.username, fields,
- err, e, traceback.format_exc())
- yield str(s)
- return
- status = headers.setdefault('Status', '200 OK')
- del headers['Status']
- self.start(status, headers.items())
- yield output_string
- if fields.has_key('timedebug'):
- yield '<pre>%s</pre>' % cgi.escape(str(checkpoint))
-
-def constructor():
- connect()
- return App
-
-def main():
- from flup.server.fcgi_fork import WSGIServer
- WSGIServer(constructor()).run()
-
-if __name__ == '__main__':
- main()