1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
   | class WSGIContainer(object):     def __init__(self, wsgi_application):         self.wsgi_application = wsgi_application
      def __call__(self, request):         data = {}         response = []                  def start_response(status, response_headers, exc_info=None):             data["status"] = status             data["headers"] = response_headers             return response.append                  app_response = self.wsgi_application(             WSGIContainer.environ(request), start_response)         response.extend(app_response)         body = "".join(response)         if hasattr(app_response, "close"):             app_response.close()         if not data: raise Exception("WSGI app did not call start_response")                  status_code = int(data["status"].split()[0])         headers = data["headers"]         header_set = set(k.lower() for (k,v) in headers)         body = escape.utf8(body)         if "content-length" not in header_set:             headers.append(("Content-Length", str(len(body))))         if "content-type" not in header_set:             headers.append(("Content-Type", "text/html; charset=UTF-8"))         if "server" not in header_set:             headers.append(("Server", "TornadoServer/0.1"))
          parts = ["HTTP/1.1 " + data["status"] + "\r\n"]         for key, value in headers:             parts.append(escape.utf8(key) + ": " + escape.utf8(value) + "\r\n")         parts.append("\r\n")         parts.append(body)                  request.write("".join(parts))         request.finish()         self._log(status_code, request)
      @staticmethod     def environ(request):         hostport = request.host.split(":")         if len(hostport) == 2:             host = hostport[0]             port = int(hostport[1])         else:             host = request.host             port = 443 if request.protocol == "https" else 80         environ = {             "REQUEST_METHOD": request.method,             "SCRIPT_NAME": "",             "PATH_INFO": request.path,             "QUERY_STRING": request.query,             "REMOTE_ADDR": request.remote_ip,             "SERVER_NAME": host,             "SERVER_PORT": port,             "SERVER_PROTOCOL": request.version,             "wsgi.version": (1, 0),             "wsgi.url_scheme": request.protocol,             "wsgi.input": cStringIO.StringIO(escape.utf8(request.body)),             "wsgi.errors": sys.stderr,             "wsgi.multithread": False,             "wsgi.multiprocess": True,             "wsgi.run_once": False,         }         if "Content-Type" in request.headers:             environ["CONTENT_TYPE"] = request.headers["Content-Type"]         if "Content-Length" in request.headers:             environ["CONTENT_LENGTH"] = request.headers["Content-Length"]         for key, value in request.headers.iteritems():             environ["HTTP_" + key.replace("-", "_").upper()] = value         return environ
      def _log(self, status_code, request):         if status_code < 400:             log_method = logging.info         elif status_code < 500:             log_method = logging.warning         else:             log_method = logging.error         request_time = 1000.0 * request.request_time()         summary = request.method + " " + request.uri + " (" + \             request.remote_ip + ")"         log_method("%d %s %.2fms", status_code, summary, request_time)
   |