def finish_request(self, fs): try: (keepalive, conn) = fs.result() # if the connection should be kept alived add it # to the eventloop and record it if keepalive: # flag the socket as non blocked conn.sock.setblocking(False) # register the connection conn.set_timeout() self._keep.append(conn) # add the socket to the event loop self.poller.register(conn.sock, selectors.EVENT_READ, partial(self.handle_client, conn)) else: util.close(conn.sock) except: # an exception happened, make sure to close the # socket. util.close(fs.conn.sock) finally: # remove the future from our list try: self.futures.remove(fs) except ValueError: pass
def handle(self, listener, client, addr): req = None try: if self.cfg.is_ssl: client = ssl.wrap_socket(client, server_side=True, **self.cfg.ssl_options) parser = http.RequestParser(self.cfg, client) req = six.next(parser) self.handle_request(listener, 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 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: if self.cfg.is_ssl: client = ssl.wrap_socket(client, server_side=True, **self.cfg.ssl_options) parser = http.RequestParser(self.cfg, client) req = six.next(parser) self.handle_request(listener, 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 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(self, listener, client, addr): environ = {} req = None resp = None try: parser = http.RequestParser(self.cfg, client) req = six.next(parser) environ, resp = self.handle_request(listener, 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 socket.error as e: if e.args[0] != errno.EPIPE: self.log.exception("Error processing request.") else: self.log.debug("Ignoring EPIPE") except Exception as e: self.handle_error(req, client, addr, e) finally: util.close(client) try: if resp is not None: self.cfg.post_request(self, req, environ, resp) else: self.log.exception("Error during post_request.") except: self.log.exception("Error during post_request.")
def send(self): # send headers resp_head = [] resp_head.append("HTTP/1.1 %s\r\n" % (self.status)) resp_head.append("Server: %s\r\n" % self.SERVER_VERSION) resp_head.append("Date: %s\r\n" % http_date()) # broken clients resp_head.append("Status: %s\r\n" % str(self.status)) # always close the conenction resp_head.append("Connection: close\r\n") for name, value in self.headers.items(): resp_head.append("%s: %s\r\n" % (name, value)) write(self.sock, "%s\r\n" % "".join(resp_head)) for chunk in list(self.data): write(self.sock, chunk) close(self.sock) if hasattr(self.data, "close"): self.data.close()
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(self, server_sock, client_sock, addr): """Handle client connection The client may send one or more requests. """ req = None try: parser = http.RequestParser(self.cfg, client_sock) try: server_name = server_sock.getsockname() if not self.cfg.keepalive: req = next(parser) self.handle_request(server_name, req, client_sock, addr) else: # keepalive loop while True: req = None with self.timeout_ctx(): req = next(parser) if not req: break self.handle_request(server_name, req, client_sock, addr) gyield() 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 reraise(exc_info[0], exc_info[1], exc_info[2]) except socket.error: exc_info = sys.exc_info() # pass to next try-except level reraise(exc_info[0], exc_info[1], exc_info[2]) except Exception as e: self.handle_error(req, client_sock, addr, e) except ssl.SSLError as e: if get_errno(e) == ssl.SSL_ERROR_EOF: self.log.debug("ssl connection closed") client_sock.close() else: self.log.debug("Error processing SSL request.") self.handle_error(req, client_sock, addr, e) except socket.error as e: if get_errno(e) not in BROKEN_SOCK: self.log.exception("Socket error processing request.") else: if get_errno(e) == errno.ECONNRESET: self.log.debug("Ignoring connection reset") else: self.log.debug("Ignoring EPIPE") except Exception as e: self.handle_error(req, client_sock, addr, e) finally: util.close(client_sock)
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 run(self): # init listeners, add them to the event loop for s in self.sockets: s.setblocking(False) self.poller.register(s, selectors.EVENT_READ, self.accept) timeout = self.cfg.timeout or 0.5 while self.alive: # If our parent changed then we shut down. if self.ppid != os.getppid(): self.log.info("Parent changed, shutting down: %s", self) return # notify the arbiter we are alive self.notify() events = self.poller.select(0.2) for key, mask in events: callback = key.data callback(key.fileobj) # hanle keepalive timeouts self.murder_keepalived() # if we more connections than the max number of connections # accepted on a worker, wait until some complete or exit. if len(self.futures) >= self.worker_connections: res = futures.wait(self.futures, timeout=timeout) if not res: self.log.info("max requests achieved") break # shutdown the pool self.poller.close() self.tpool.shutdown(False) # wait for the workers futures.wait(self.futures, timeout=self.cfg.graceful_timeout) # if we have still fures running, try to close them while True: try: fs = self.futures.popleft() except IndexError: break sock = fs.conn.sock # the future is not running, cancel it if not fs.done() and not fs.running(): fs.cancel() # make sure we close the sockets after the graceful timeout util.close(sock)
def handle(self, client, addr): util.close_on_exec(client) try: req = http.HttpRequest(client, addr, self.address) response = self.app(req.read(), req.start_response) http.HttpResponse(client, response, req).send() except Exception, e: # TODO: try to send something if an error happend self.log.exception("Error processing request. [%s]" % str(e)) # try to send something if an error happend util.close(client)
def handle(self, client, addr): self.close_on_exec(client) try: req = http.HTTPRequest(client, addr, self.address) response = self.app(req.read(), req.start_response) http.HTTPResponse(client, response, req).send() except Exception, e: self.log.exception("Error processing request. [%s]" % str(e)) # try to send something if an error happend msg = "HTTP/1.1 500 Internal Server Error\r\n\r\n" util.write_nonblock(client, msg) 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 while True: req = None with self.timeout_ctx(): req = six.next(parser) if not req: break 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): try: listener_name = listener.getsockname() self.handle_request(listener_name, client, addr) 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.log.error(str(e) + traceback.format_exc()) finally: util.close(client)
def handle(self, listener, client, addr): req = None try: parser = http.RequestParser(self.cfg, client) try: if not self.cfg.keepalive: req = six.next(parser) self.handle_request_implemented(listener, req, client, addr) else: # keepalive loop while True: req = None with self.timeout_ctx(): req = six.next(parser) if not req: break self.handle_request_implemented(listener, 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: raise # pass to next try-except level except socket.error: raise # pass to next try-except level 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): u = Unpacker(encoding='utf8') again = True while again: u.feed(client.recv(4096)) self.notify() for msg in u: _, msgid, method, params = msg try: r = self.cfg.methods[method](*params) except Exception as e: client.sendall(packb([1, msgid, str(e), None])) else: client.sendall(packb([1, msgid, None, r])) finally: util.close(client) again = False
def handle(self, client, addr): req = None try: parser = http.RequestParser(self.cfg, client) req = six.next(parser) self.handle_request(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 socket.error as e: if e.args[0] != errno.EPIPE: self.log.exception("Error processing request.") 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): self._log('handle client=%s' % str(addr)) req = None try: if self.cfg.is_ssl: client = ssl.wrap_socket(client, server_side=True, **self.cfg.ssl_options) # 仅处理了一个请求, 没有考虑长连接中多个请求的情况? parser = http.RequestParser(self.cfg, client) # 解析HTTP报文得到一个请求对象, 会处理请求行, headers, 请求体 req = next(parser) self.handle_request(listener, req, client, addr) except http.errors.NoMoreData as e: self._log("handle Ignored premature client disconnection. %s" % e) except StopIteration as e: self._log("handle Closing connection. %s" % e) except ssl.SSLError as e: self._log('handle SSLError %s' % 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: self._log('handle EnvironmentError %s' % e) # EPIPE: Broken pipe # ECONNRESET: Connection reset by peer, 是 RST 么? 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(self, listener, client, address): # noqa: C901, pragma: no cover """Handle a request Method is almost identical to :meth:`gunicorn.workers.sync.SyncWorker` one. We need to overide this method because we use non blocking socket connections thus we are more sensitive to :meth:`errno.EAGAIN` errors. """ req = None try: if self.cfg.is_ssl: client = ssl.wrap_socket(client, server_side=True, **self.cfg.ssl_options) parser = http.RequestParser(self.cfg, client) req = next(parser) self.handle_request(listener, req, client, address) 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 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, address, e) except EnvironmentError as e: # Added in ConsenSys-Utils: we do not log exception on :meth:`errno.EAGAIN` if e.errno not in (errno.EPIPE, errno.ECONNRESET, errno.EAGAIN): self.log.exception("Socket error processing request.") else: if e.errno == errno.ECONNRESET: self.log.debug("Ignoring connection reset") elif e.errno == errno.EAGAIN: self.log.debug("Ignoring EAGAIN") else: self.log.debug("Ignoring EPIPE") except Exception as e: self.handle_error(req, client, address, e) finally: util.close(client)
def send(self): # send headers resp_head = [ "HTTP/1.1 %s\r\n" % self.status, "Server: %s\r\n" % self.SERVER_VERSION, "Date: %s\r\n" % http_date(), "Connection: close\r\n" ] resp_head.extend(["%s: %s\r\n" % (n, v) for n, v in self.headers]) write(self._sock, "%s\r\n" % "".join(resp_head)) for chunk in list(self.data): if chunk == "": break write(self._sock, chunk, self.chunked) if self.chunked: # send last chunk write_chunk(self._sock, "") close(self._sock) if hasattr(self.data, "close"): self.data.close()
def send(self): # send headers resp_head = [] resp_head.append("HTTP/1.1 %s\r\n" % (self.status)) resp_head.append("Server: %s\r\n" % self.SERVER_VERSION) resp_head.append("Date: %s\r\n" % http_date()) # broken clients resp_head.append("Status: %s\r\n" % str(self.status)) # always close the connection resp_head.append("Connection: close\r\n") for name, value in self.headers.items(): resp_head.append("%s: %s\r\n" % (name, value)) write(self.sock, "%s\r\n" % "".join(resp_head)) for chunk in list(self.data): write(self.sock, chunk) close(self.sock) if hasattr(self.data, "close"): self.data.close()
def handle(self, client, addr): req = None try: parser = http.RequestParser(self.cfg, client) try: if not self.cfg.keepalive: req = six.next(parser) self.handle_request(req, client, addr) else: # keepalive loop while True: req = None with self.timeout_ctx(): req = six.next(parser) if not req: break self.handle_request(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 socket.error: raise # pass to next try-except level except Exception as e: 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 murder_keepalived(self): now = time.time() while True: try: conn = self._keep.popleft() except IndexError: break delta = conn.timeout - now if delta > 0: self._keep.appendleft(conn) break else: # remove the connection from the queue try: conn = self._keep.popleft() except IndexError: break # remove the socket from the poller self.poller.unregister(conn.sock) # close the socket util.close(conn.sock)
self.handle_request(req, client, addr) except StopIteration: pass except socket.error, e: if e[0] not in (errno.EPIPE, errno.ECONNRESET): self.log.exception("Socket error processing request.") else: if e[0] == errno.ECONNRESET: self.log.debug("Ignoring connection reset") else: self.log.debug("Ignoring EPIPE") except Exception, e: self.log.exception("General error processing request.") self.handle_error(client, e) finally: util.close(client) def handle_request(self, req, sock, addr): try: self.cfg.pre_request(self, req) resp, environ = wsgi.create(req, sock, addr, self.address, self.cfg) 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 respiter = self.wsgi(environ, resp.start_response) if respiter == ALREADY_HANDLED: return False for item in respiter: resp.write(item)
break self.handle_request(req, client, addr) except StopIteration: pass except socket.error, e: if e[0] not in (errno.EPIPE, errno.ECONNRESET): self.log.exception("Socket error processing request.") else: if e[0] == errno.ECONNRESET: self.log.debug("Ignoring connection reset") else: self.log.debug("Ignoring EPIPE") except Exception, e: self.handle_error(client, e) finally: util.close(client) def handle_request(self, req, sock, addr): try: self.cfg.pre_request(self, req) request_start = datetime.now() resp, environ = wsgi.create(req, sock, addr, self.address, self.cfg) 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 respiter = self.wsgi(environ, resp.start_response) if respiter == ALREADY_HANDLED: return False