"""
WSGI application implementation
"""
# for error reporting
import sys, traceback
# for Request/Response
import http
class Application (object) :
"""
Our WSGI application, implements the wsgi __call__ interface
"""
def __init__ (self, handler) :
"""
Initialize to use the given handler for requests
"""
self.handler = handler
def handle_request (self, env, start_response) :
"""
The actual request handling code
"""
# build Request object
request = http.Request(env)
try :
# request -> response using our handler
response = self.handler.handle_request(request)
except http.ResponseError, err :
# just use the generated response
response = err.get_response()
# send response
assert response, "No response"
# send response status/headers
start_response(response.get_status(), response.get_headers())
# send respones data
yield response.get_data()
def handle_error (self, exc_info, env, start_response) :
"""
Handle errors thrown by handle_request. This should call start_response with the exc_info and return the
error message (i.e. str), otherwise the error will be thrown up yet another level.
Note that e.g. unicode is a failure...
"""
# try and send 500 ISE to browser, if no headers yet...
start_response("500 Internal Server Error", [('Content-type', "text/plain; charset=UTF-8")], exc_info)
# format traceback
data = ''.join(traceback.format_exception(*exc_info))
# no unicode, kplzthx
return data.encode('utf-8')
def __call__ (self, env, start_response) :
"""
Wraps handle_request to trap errors
"""
try :
# passthrough request_handler
for chunk in self.handle_request(env, start_response) :
yield chunk
except :
# execption info
info = sys.exc_info()
# handle
yield self.handle_error(info, env, start_response)