Example #1
0
def wsgiApp(environ, start_response):
    """The WSGI 'application object' for CherryPy."""

    # Trap screen output from BaseHTTPRequestHandler.log_message()
    if not cherrypy.config.get("server.logToScreen"):
        sys.stderr = NullWriter()

    try:
        cherrypy.request.purge__()
        cherrypy.response.purge__()

        # LOGON_USER is served by IIS, and is the name of the
        # user after having been mapped to a local account.
        # Both IIS and Apache set REMOTE_USER, when possible.
        cherrypy.request.login = environ.get("LOGON_USER") or environ.get("REMOTE_USER") or None
        cherrypy.request.multithread = environ["wsgi.multithread"]
        cherrypy.request.multiprocess = environ["wsgi.multiprocess"]
        clientAddr = (environ.get("REMOTE_ADDR", ""), int(environ.get("REMOTE_PORT", -1)))
        cherrypy.server.request(
            clientAddr,
            environ.get("REMOTE_ADDR", ""),
            requestLine(environ),
            translate_headers(environ),
            environ["wsgi.input"],
            environ["wsgi.url_scheme"],
        )
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        tb = _cputil.formatExc()
        cherrypy.log(tb)
        defaultOn = cherrypy.config.get("server.environment") == "development"
        if not cherrypy.config.get("server.showTracebacks", defaultOn):
            tb = ""
        s, h, b = _cphttptools.bareError(tb)
        exc = sys.exc_info()
    else:
        response = cherrypy.response
        s, h, b = response.status, response.headers, response.body
        exc = None

    try:
        start_response(s, h, exc)
        for chunk in b:
            # WSGI requires all data to be of type "str". This coercion should
            # not take any time at all if chunk is already of type "str".
            # If it's unicode, it could be a big performance hit (x ~500).
            chunk = str(chunk)
            yield chunk
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        tb = _cputil.formatExc()
        cherrypy.log(tb)
        s, h, b = _cphttptools.bareError()
        # CherryPy test suite expects bareError body to be output,
        # so don't call start_response (which, according to PEP 333,
        # may raise its own error at that point).
        for chunk in b:
            yield str(chunk)
Example #2
0
 def _getRequest(self, url, headers, method, body):
     # Like getPage, but for serverless requests.
     webtest.ServerError.on = False
     self.url = url
     
     requestLine = "%s %s HTTP/1.1" % (method.upper(), url)
     headers = webtest.cleanHeaders(headers, method, body,
                                    self.HOST, self.PORT)
     if body is not None:
         body = StringIO.StringIO(body)
     
     cherrypy.request.purge__()
     cherrypy.response.purge__()
     
     cherrypy.server.request((self.HOST, self.PORT), self.HOST,
                             requestLine, headers, body, "http")
     
     self.status = cherrypy.response.status
     self.headers = cherrypy.response.headers
     
     # Build a list of request cookies from the previous response cookies.
     self.cookies = [('Cookie', v) for k, v in self.headers
                     if k.lower() == 'set-cookie']
     
     try:
         self.body = []
         for chunk in cherrypy.response.body:
             self.body.append(chunk)
     except:
         if cherrypy.config.get("streamResponse", False):
             # Pass the error through
             raise
         
         from cherrypy import _cphttptools
         s, h, b = _cphttptools.bareError()
         # Don't reset status or headers; we're emulating an error which
         # occurs after status and headers have been written to the client.
         for chunk in b:
             self.body.append(chunk)
     self.body = "".join(self.body)
     
     if webtest.ServerError.on:
         self.tearDown()
         raise webtest.ServerError()
Example #3
0
 def handle_one_request(self):
     """Handle a single HTTP request."""
     
     self.raw_requestline = self.rfile.readline()
     if not self.raw_requestline:
         self.close_connection = 1
         return
     if not self.parse_request(): # An error code has been sent, just exit
         return
     
     cherrypy.request.purge__()
     cherrypy.response.purge__()
     
     tp = cherrypy.config.get("server.threadPool")
     cherrypy.request.multithread = (tp > 1)
     cherrypy.request.multiprocess = False
     cherrypy.server.request(self.client_address,
                             self.address_string(),
                             self.raw_requestline,
                             self._headerlist(),
                             self.rfile, "http")
     wfile = self.wfile
     wfile.write("%s %s\r\n" %
                 (self.protocol_version, cherrypy.response.status))
     
     has_close_conn = False
     for name, value in cherrypy.response.headers:
         wfile.write("%s: %s\r\n" % (name, value))
         if name.lower == 'connection' and value.lower == 'close':
             has_close_conn = True
     if not has_close_conn:
         # This server doesn't support persistent connections yet, so we
         # must add a "Connection: close" header to tell the client that
         # we will close the connection when we're done sending output.
         # 
         # From RFC 2616 sec 14.10:
         # HTTP/1.1 defines the "close" connection option for the sender
         # to signal that the connection will be closed after completion
         # of the response. For example,
         # 
         #    Connection: close
         # 
         # in either the request or the response header fields indicates
         # that the connection SHOULD NOT be considered `persistent'
         # (section 8.1) after the current request/response is complete.
         # 
         # HTTP/1.1 applications that do not support persistent connections
         # MUST include the "close" connection option in every message.
         wfile.write("Connection: close\r\n")
     
     wfile.write("\r\n")
     try:
         for chunk in cherrypy.response.body:
             wfile.write(chunk)
     except:
         s, h, b = _cphttptools.bareError()
         for chunk in b:
             wfile.write(chunk)
     
     if self.command == "POST":
         self.connection = self.request
     
     # Close the conn, since we do not yet support persistent connections.
     self.close_connection = 1