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 respiter == ALREADY_HANDLED: 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) six.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 respiter == ALREADY_HANDLED: 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 socket.error: # If the original exception was a socket.error we delegate # handling it to the caller (where handle() might ignore it) six.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 socket.error: 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 _wrap_error(exc, mapping, key): if key not in mapping: return new_err_cls = mapping[key] new_err = new_err_cls(*exc.args) # raise a new exception with the original traceback six.reraise(new_err_cls, new_err, exc.__traceback__ if hasattr(exc, '__traceback__') else sys.exc_info()[2])
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 = six.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 = six.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: exc_info = sys.exc_info() # pass to next try-except level six.reraise(exc_info[0], exc_info[1], exc_info[2]) except socket.error: exc_info = sys.exc_info() # pass to next try-except level six.reraise(exc_info[0], exc_info[1], exc_info[2]) 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 socket.error as e: if e.args[0] not in (errno.EPIPE, errno.ECONNRESET): self.log.exception("Socket error processing request.") else: if e.args[0] == 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(self, listener, client, addr): req = None try: parser = http.RequestParser(self.cfg, client) try: listener_name = listener.getsockname() if not self.cfg.keepalive: req = six.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 = six.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: exc_info = sys.exc_info() # pass to next try-except level six.reraise(exc_info[0], exc_info[1], exc_info[2]) except EnvironmentError: exc_info = sys.exc_info() # pass to next try-except level six.reraise(exc_info[0], exc_info[1], exc_info[2]) 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 socket.error: exc_info = sys.exc_info() # pass to next try-except level six.reraise(exc_info[0], exc_info[1], exc_info[2]) 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 socket.error: 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: 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 self.process_headers(headers) self.chunked = self.is_chunked() return self.write
def handle_request(self, listener, req, client, addr): environ = {} try: self.resp = resp = FuzzyResponse() self.cfg.pre_request(self, req) request_start = datetime.now() environ = create_environ(req, client, addr, listener.getsockname(), self.cfg) self.nr += 1 if self.nr >= self.max_requests: self.log.info("Autorestarting worker after current request.") self.alive = False self.resp_iter = self.wsgi(environ, self.start_response(req, client)) try: if isinstance(self.resp_iter, environ['wsgi.file_wrapper']): resp.write_file(self.resp_iter) else: if not resp.headers_sent: self.prepare_headers() for item in self.resp_iter: resp.write(item) resp.close() request_time = datetime.now() - request_start self.log.access(resp, req, environ, request_time) finally: if hasattr(self.resp_iter, "close"): self.resp_iter.close() except EnvironmentError: # pass to next try-except level six.reraise(*sys.exc_info()) except Exception: if self.resp and self.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, self.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: 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
def handle_request(self, req, conn): environ = {} resp = None try: self.cfg.pre_request(self, req) request_start = datetime.now() resp, environ = wsgi.create(req, conn.sock, conn.addr, conn.listener.getsockname(), 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) 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(): self.log.debug("Closing connection.") return False except socket.error: exc_info = sys.exc_info() # pass to next try-except level six.reraise(exc_info[0], exc_info[1], exc_info[2]) 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: conn.sock.shutdown(socket.SHUT_RDWR) conn.sock.close() except socket.error: 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, 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 use_cache = False cache_key = "{0}:{1}".format(req.uri, req.method) for route in self.cache_route: if re.match(route["url"], req.uri) and req.method in route["methods"]: use_cache = True if environ.get("HTTP_GUNICORN_CACHE_REFRESH"): result = None else: result = self.redis.get(cache_key) if not result: respiter = self.wsgi(environ, resp.start_response) if resp.status_code == 200: result = {"body": [x for x in respiter], "headers": resp.headers} self.redis.set(cache_key, pickle.dumps(result), route.get("expire", 300)) else: result = pickle.loads(result) if resp.status is None: resp.start_response("200 OK", result["headers"]) respiter = result["body"] if route.get("prolong", True): self.redis.expire(cache_key, route.get("expire", 300)) break if not use_cache: 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 socket.error: exc_info = sys.exc_info() # pass to next try-except level six.reraise(exc_info[0], exc_info[1], exc_info[2]) 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 socket.error: pass raise StopIteration() raise finally: try: self.cfg.post_request(self, req, environ, resp) except Exception: self.log.exception("Exception in post_request hook")