terom@94: """ terom@94: A tornado-based HTTP app terom@94: """ terom@94: terom@94: import tornado.web terom@94: import tornado.httpserver terom@94: import tornado.wsgi terom@94: import werkzeug terom@94: terom@94: from pngtile import handlers terom@94: terom@94: class MainHandler (tornado.web.RequestHandler) : terom@94: """ terom@94: Main handler for the / URL, pass off requests to werkzeug-based handlers... terom@94: """ terom@94: terom@94: def build_environ (self, path) : terom@94: """ terom@94: Yield a series of (key, value) pairs suitable for use with WSGI terom@94: """ terom@94: terom@94: request = self.request terom@94: terom@94: hostport = request.host.split(":") terom@94: terom@94: if len(hostport) == 2: terom@94: host = hostport[0] terom@94: port = int(hostport[1]) terom@94: else: terom@94: host = request.host terom@94: port = 443 if request.protocol == "https" else 80 terom@94: terom@94: yield "REQUEST_METHOD", request.method terom@94: yield "SCRIPT_NAME", "" terom@94: yield "PATH_INFO", path terom@94: yield "QUERY_STRING", request.query terom@94: yield "SERVER_NAME", host terom@94: yield "SERVER_PORT", port terom@94: terom@94: yield "wsgi.version", (1, 0) terom@94: yield "wsgi.url_scheme", request.protocol terom@94: terom@94: yield "CONTENT_TYPE", request.headers.get("Content-Type") terom@94: yield "CONTENT_LENGTH", request.headers.get("Content-Length") terom@94: terom@94: for key, value in request.headers.iteritems(): terom@94: yield "HTTP_" + key.replace("-", "_").upper(), value terom@94: terom@94: def get (self, path) : terom@94: environ = dict(self.build_environ(path)) terom@94: terom@94: # build Request terom@94: request = werkzeug.Request(environ) terom@94: terom@94: # handle terom@94: try : terom@94: response = handlers.handle_req(request) terom@94: terom@94: except werkzeug.exceptions.HTTPException, ex : terom@94: response = ex terom@94: terom@94: # return terom@94: def start_response (_status, _headers) : terom@94: status = int(_status.split()[0]) terom@94: headers = _headers terom@94: terom@94: self.set_status(status) terom@94: terom@94: for name, value in headers : terom@94: self.set_header(name, value) terom@94: terom@94: # invoke Response terom@94: data = response(environ, start_response) terom@94: terom@94: # output data terom@94: for chunk in data : terom@94: self.write(chunk) terom@94: terom@94: def build_app () : terom@94: return tornado.web.Application([ terom@94: # static, from $CWD/static/ terom@94: (r"/static/(.*)", tornado.web.StaticFileHandler, dict(path = "static/")), terom@94: terom@94: # dir listings, image html, PNG tiles terom@94: (r"(/.*)", MainHandler), terom@94: ]) terom@94: terom@94: def build_httpserver (app, port) : terom@94: server = tornado.httpserver.HTTPServer(app) terom@94: server.listen(port) terom@94: terom@94: return server terom@94: terom@94: def main (port=8000) : terom@94: """ terom@94: Build the app, http server and run the main loop terom@94: """ terom@94: terom@94: import logging terom@94: terom@94: logging.basicConfig(level=logging.DEBUG) terom@94: terom@94: app = build_app() terom@94: server = build_httpserver(app, port) terom@94: terom@94: tornado.ioloop.IOLoop.instance().start() terom@94: terom@94: