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)
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()
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