def handle_request(self, listener_name, req, sock, addr): request_start = datetime.now() environ = {} resp = None try: self.cfg.pre_request(self, req) resp, environ = wsgi.create(req, sock, addr, listener_name, self.cfg) environ["wsgi.multithread"] = True self.nr += 1 if self.nr >= self.max_requests: if self.alive: self.log.info( "Autorestarting worker after current request.") self.alive = False if not self.alive or not self.cfg.keepalive: resp.force_close() respiter = self.wsgi(environ, resp.start_response) if self.is_already_handled(respiter): return False try: if isinstance(respiter, environ["wsgi.file_wrapper"]): resp.write_file(respiter) else: for item in respiter: resp.write(item) resp.close() request_time = datetime.now() - request_start self.log.access(resp, req, environ, request_time) finally: if hasattr(respiter, "close"): respiter.close() if resp.should_close(): raise StopIteration() except StopIteration: raise except EnvironmentError: # If the original exception was a socket.error we delegate # handling it to the caller (where handle() might ignore it) util.reraise(*sys.exc_info()) except Exception: if resp and resp.headers_sent: # If the requests have already been sent, we should close the # connection to indicate the error. self.log.exception("Error handling request") try: sock.shutdown(socket.SHUT_RDWR) sock.close() except EnvironmentError: pass raise StopIteration() raise finally: try: self.cfg.post_request(self, req, environ, resp) except Exception: self.log.exception("Exception in post_request hook") return True
def handle_request(self, listener_name, req, sock, addr): request_start = datetime.now() environ = {} resp = None try: self.cfg.pre_request(self, req) resp, environ = wsgi.create(req, sock, addr, listener_name, self.cfg) environ["wsgi.multithread"] = True self.nr += 1 if self.alive and self.nr >= self.max_requests: self.log.info("Autorestarting worker after current request.") resp.force_close() self.alive = False if not self.cfg.keepalive: resp.force_close() respiter = self.wsgi(environ, resp.start_response) if self.is_already_handled(respiter): return False try: if isinstance(respiter, environ['wsgi.file_wrapper']): resp.write_file(respiter) else: for item in respiter: resp.write(item) resp.close() request_time = datetime.now() - request_start self.log.access(resp, req, environ, request_time) finally: if hasattr(respiter, "close"): respiter.close() if resp.should_close(): raise StopIteration() except StopIteration: raise except EnvironmentError: # If the original exception was a socket.error we delegate # handling it to the caller (where handle() might ignore it) util.reraise(*sys.exc_info()) except Exception: if resp and resp.headers_sent: # If the requests have already been sent, we should close the # connection to indicate the error. self.log.exception("Error handling request") try: sock.shutdown(socket.SHUT_RDWR) sock.close() except EnvironmentError: pass raise StopIteration() raise finally: try: self.cfg.post_request(self, req, environ, resp) except Exception: self.log.exception("Exception in post_request hook") return True
def handle(self, listener, client, addr): req = None try: parser = http.RequestParser(self.cfg, client) try: listener_name = listener.getsockname() if not self.cfg.keepalive: req = next(parser) self.handle_request(listener_name, req, client, addr) else: # keepalive loop proxy_protocol_info = {} # 相比于 gthread worker, 此处一直循环读取请求并处理 while True: req = None with self.timeout_ctx(): req = next(parser) if not req: break if req.proxy_protocol_info: proxy_protocol_info = req.proxy_protocol_info else: req.proxy_protocol_info = proxy_protocol_info self.handle_request(listener_name, req, client, addr) except http.errors.NoMoreData as e: self.log.debug("Ignored premature client disconnection. %s", e) except StopIteration as e: self.log.debug("Closing connection. %s", e) except ssl.SSLError: # pass to next try-except level util.reraise(*sys.exc_info()) except EnvironmentError: # pass to next try-except level util.reraise(*sys.exc_info()) except Exception as e: self.handle_error(req, client, addr, e) except ssl.SSLError as e: if e.args[0] == ssl.SSL_ERROR_EOF: self.log.debug("ssl connection closed") client.close() else: self.log.debug("Error processing SSL request.") self.handle_error(req, client, addr, e) except EnvironmentError as e: if e.errno not in (errno.EPIPE, errno.ECONNRESET): self.log.exception("Socket error processing request.") else: if e.errno == errno.ECONNRESET: self.log.debug("Ignoring connection reset") else: self.log.debug("Ignoring EPIPE") except Exception as e: self.handle_error(req, client, addr, e) finally: util.close(client)
def handle_request(self, listener, req, client, addr): environ = {} resp = None try: # 钩子函数 self.cfg.pre_request(self, req) request_start = datetime.now() resp, environ = wsgi.create(req, client, addr, listener.getsockname(), self.cfg) # Force the connection closed until someone shows # a buffering proxy that supports Keep-Alive to # the backend. resp.force_close() self.nr += 1 """`max_requests` -- The maximum number of requests a worker will process before restarting. """ if self.nr >= self.max_requests: self.log.info("Autorestarting worker after current request.") self.alive = False # 调用web应用对象去处理请求 respiter = self.wsgi(environ, resp.start_response) try: # 输出响应 if isinstance(respiter, environ['wsgi.file_wrapper']): resp.write_file(respiter) else: for item in respiter: resp.write(item) resp.close() request_time = datetime.now() - request_start self.log.access(resp, req, environ, request_time) finally: if hasattr(respiter, "close"): respiter.close() except EnvironmentError: # pass to next try-except level util.reraise(*sys.exc_info()) except Exception: if resp and resp.headers_sent: # If the requests have already been sent, we should close the # connection to indicate the error. self.log.exception("Error handling request") try: client.shutdown(socket.SHUT_RDWR) client.close() except EnvironmentError: pass raise StopIteration() raise finally: try: # 钩子函数 self.cfg.post_request(self, req, environ, resp) except Exception: self.log.exception("Exception in post_request hook")
def handle_request(self, listener, req, client, addr): environ = {} resp = None try: self.cfg.pre_request(self, req) request_start = datetime.now() resp, environ = wsgi.create(req=req, sock=client, client=addr, server=listener.getsockname(), cfg=self.cfg) # Force the connection closed until someone shows # a buffering proxy that supports Keep-Alive to # the backend. todo: 不懂 resp.force_close() self.nr += 1 if self.nr >= self.max_requests: self.log.info("Auto restarting worker after current request.") self.alive = False respiter = self.wsgi(environ, resp.start_response) try: if isinstance(respiter, environ['wsgi.file_wrapper']): resp.write_file(respiter) else: for item in respiter: resp.write(item) resp.close() request_time = datetime.now() - request_start self.log.access(resp, req, environ, request_time) finally: if hasattr(respiter, "close"): respiter.close() except EnvironmentError: # pass to next try-except level util.reraise(*sys.exc_info()) except Exception: if resp and resp.headers_sent: # If the requests have already been sent, we should # close the connection to indicate the error. self.log.exception("Error handling request") try: # Shut down one or both halves of the connection # SHUT_RDWR: further sends and receives are disallowed client.shutdown(socket.SHUT_RDWR) client.close() except EnvironmentError: pass raise StopIteration() raise finally: try: self.cfg.post_request(self, req, environ, resp) except Exception: self.log.exception("Exception in post_request hook")
def handle(self, listener, client, addr): req = None try: parser = http.RequestParser(self.cfg, client) try: listener_name = listener.getsockname() if not self.cfg.keepalive: req = next(parser) self.handle_request(listener_name, req, client, addr) else: # keepalive loop proxy_protocol_info = {} while True: req = None with self.timeout_ctx(): req = next(parser) if not req: break if req.proxy_protocol_info: proxy_protocol_info = req.proxy_protocol_info else: req.proxy_protocol_info = proxy_protocol_info self.handle_request(listener_name, req, client, addr) except http.errors.NoMoreData as e: self.log.debug("Ignored premature client disconnection. %s", e) except StopIteration as e: self.log.debug("Closing connection. %s", e) except ssl.SSLError: # pass to next try-except level util.reraise(*sys.exc_info()) except EnvironmentError: # pass to next try-except level util.reraise(*sys.exc_info()) except Exception as e: self.handle_error(req, client, addr, e) except ssl.SSLError as e: if e.args[0] == ssl.SSL_ERROR_EOF: self.log.debug("ssl connection closed") client.close() else: self.log.debug("Error processing SSL request.") self.handle_error(req, client, addr, e) except EnvironmentError as e: if e.errno not in (errno.EPIPE, errno.ECONNRESET): self.log.exception("Socket error processing request.") else: if e.errno == errno.ECONNRESET: self.log.debug("Ignoring connection reset") else: self.log.debug("Ignoring EPIPE") except Exception as e: self.handle_error(req, client, addr, e) finally: util.close(client)
def handle_request(self, listener, req, client, addr): environ = {} resp = None try: self.cfg.pre_request(self, req) request_start = datetime.now() resp, environ = wsgi.create(req, client, addr, listener.getsockname(), self.cfg) # Force the connection closed until someone shows # a buffering proxy that supports Keep-Alive to # the backend. resp.force_close() self.nr += 1 if self.nr >= self.max_requests: self.log.info("Autorestarting worker after current request.") self.alive = False respiter = self.wsgi(environ, resp.start_response) try: if isinstance(respiter, environ['wsgi.file_wrapper']): resp.write_file(respiter) else: for item in respiter: resp.write(item) resp.close() request_time = datetime.now() - request_start self.log.access(resp, req, environ, request_time) finally: if hasattr(respiter, "close"): respiter.close() except EnvironmentError: # pass to next try-except level util.reraise(*sys.exc_info()) except Exception: if resp and resp.headers_sent: # If the requests have already been sent, we should close the # connection to indicate the error. self.log.exception("Error handling request") try: client.shutdown(socket.SHUT_RDWR) client.close() except EnvironmentError: pass raise StopIteration() raise finally: try: self.cfg.post_request(self, req, environ, resp) except Exception: self.log.exception("Exception in post_request hook")
def start_response(self, status, headers, exc_info=None): if exc_info: try: if self.status and self.headers_sent: util.reraise(exc_info[0], exc_info[1], exc_info[2]) finally: exc_info = None elif self.status is not None: raise AssertionError("Response headers already set!") self.status = status # get the status code from the response here so we can use it to check # the need for the connection header later without parsing the string # each time. try: self.status_code = int(self.status.split()[0]) except ValueError: self.status_code = None self.process_headers(headers) self.chunked = self.is_chunked() return self.write