pngtile/tornado_handler.py
changeset 136 caa2509e6404
parent 135 e99dd75afa15
child 137 79eedd96112d
equal deleted inserted replaced
135:e99dd75afa15 136:caa2509e6404
     1 """
       
     2     A tornado-based HTTP app
       
     3 """
       
     4 
       
     5 import tornado.web
       
     6 import tornado.httpserver
       
     7 import tornado.wsgi
       
     8 import werkzeug
       
     9 
       
    10 from pngtile import handlers
       
    11 
       
    12 class MainHandler (tornado.web.RequestHandler) :
       
    13     """
       
    14         Main handler for the / URL, pass off requests to werkzeug-based handlers...
       
    15     """
       
    16 
       
    17     def build_environ (self, path) :
       
    18         """
       
    19             Yield a series of (key, value) pairs suitable for use with WSGI
       
    20         """
       
    21 
       
    22         request = self.request
       
    23 
       
    24         hostport = request.host.split(":")
       
    25 
       
    26         if len(hostport) == 2:
       
    27             host = hostport[0]
       
    28             port = int(hostport[1])
       
    29         else:
       
    30             host = request.host
       
    31             port = 443 if request.protocol == "https" else 80
       
    32 
       
    33         yield "REQUEST_METHOD", request.method
       
    34         yield "SCRIPT_NAME", ""
       
    35         yield "PATH_INFO", path
       
    36         yield "QUERY_STRING", request.query
       
    37         yield "SERVER_NAME", host
       
    38         yield "SERVER_PORT", port
       
    39 
       
    40         yield "wsgi.version", (1, 0)
       
    41         yield "wsgi.url_scheme", request.protocol
       
    42         
       
    43         yield "CONTENT_TYPE", request.headers.get("Content-Type")
       
    44         yield "CONTENT_LENGTH", request.headers.get("Content-Length")
       
    45 
       
    46         for key, value in request.headers.iteritems():
       
    47             yield "HTTP_" + key.replace("-", "_").upper(), value
       
    48     
       
    49     def get (self, path) :
       
    50         environ = dict(self.build_environ(path))
       
    51 
       
    52         # build Request
       
    53         request = werkzeug.Request(environ)
       
    54 
       
    55         # handle
       
    56         try :
       
    57             response = handlers.handle_req(request)
       
    58 
       
    59         except werkzeug.exceptions.HTTPException, ex :
       
    60             response = ex
       
    61 
       
    62         # return
       
    63         def start_response (_status, _headers) :
       
    64             status = int(_status.split()[0])
       
    65             headers = _headers
       
    66 
       
    67             self.set_status(status)
       
    68 
       
    69             for name, value in headers :
       
    70                 self.set_header(name, value)
       
    71         
       
    72         # invoke Response
       
    73         data = response(environ, start_response)
       
    74 
       
    75         # output data
       
    76         for chunk in data :
       
    77             self.write(chunk)
       
    78         
       
    79 def build_app () :
       
    80     return tornado.web.Application([
       
    81         # static, from $CWD/static/
       
    82         (r"/static/(.*)",           tornado.web.StaticFileHandler,  dict(path = "static/")),
       
    83         
       
    84         # dir listings, image html, PNG tiles
       
    85         (r"(/.*)",     MainHandler),
       
    86     ])  
       
    87 
       
    88 def build_httpserver (app, port) :
       
    89     server = tornado.httpserver.HTTPServer(app)
       
    90     server.listen(port)
       
    91 
       
    92     return server
       
    93 
       
    94 def main (port=8000) :
       
    95     """
       
    96         Build the app, http server and run the main loop
       
    97     """
       
    98 
       
    99     import logging
       
   100 
       
   101     logging.basicConfig(level=logging.DEBUG)
       
   102 
       
   103     app = build_app()
       
   104     server = build_httpserver(app, port)
       
   105 
       
   106     tornado.ioloop.IOLoop.instance().start()
       
   107 
       
   108