def serve_forever(self, timeout=None, blocking=True, handle_exit=True): """Start serving. - (float) timeout: the timeout passed to the underlying IO loop expressed in seconds (default 1.0). - (bool) blocking: if False loop once and then return the timeout of the next scheduled call next to expire soonest (if any). - (bool) handle_exit: when True catches KeyboardInterrupt and SystemExit exceptions (generally caused by SIGTERM / SIGINT signals) and gracefully exits after cleaning up resources. Also, logs server start and stop. """ if handle_exit: log = handle_exit and blocking == True if log: self._log_start() try: self.ioloop.loop(timeout, blocking) except (KeyboardInterrupt, SystemExit): pass if blocking: if log: logger.debug( ">>> shutting down FTP server (%s active fds) <<<", self._map_len()) self.close_all() else: self.ioloop.loop(timeout, blocking)
def serve_forever(self, timeout=None, blocking=True, handle_exit=True): self._exit.clear() if handle_exit: log = handle_exit and blocking == True if log: self._log_start() try: self.ioloop.loop(timeout, blocking) except (KeyboardInterrupt, SystemExit): pass if blocking: if log: logger.debug(">>> shutting down FTP server (%s active " \ "workers) <<<", self._map_len()) self.close_all() else: self.ioloop.loop(timeout, blocking)
def _log_start(self): if not logging.getLogger().handlers: # If we get to this point it means the user hasn't # configured logger. We want to log by default so # we configure logging ourselves so that it will # print to stderr. from FtpServer.pyftpdlib.ioloop import _config_logging _config_logging() if self.handler.passive_ports: pasv_ports = "%s->%s" % (self.handler.passive_ports[0], self.handler.passive_ports[-1]) else: pasv_ports = None logger.debug(">>> starting FTP server on %s:%s <<<" % self.address) logger.debug("poller: %r", self.ioloop.__class__) logger.debug("masquerade (NAT) address: %s", self.handler.masquerade_address) logger.debug("passive ports: %s", pasv_ports) if os.name == 'posix': logger.debug("use sendfile(2): %s", self.handler.use_sendfile)
def _log_start(self): FTPServer._log_start(self) logger.debug("dispatcher: %r", self.__class__)
def _loop(self, handler): """Serve handler's IO loop in a separate thread or process.""" ioloop = IOLoop() try: handler.ioloop = ioloop try: handler.add_channel() except EnvironmentError: err = sys.exc_info()[1] if err.errno == errno.EBADF: # we might get here in case the other end quickly # disconnected (see test_quick_connect()) return else: raise # Here we localize variable access to minimize overhead. poll = ioloop.poll socket_map = ioloop.socket_map tasks = ioloop.sched._tasks sched_poll = ioloop.sched.poll poll_timeout = getattr(self, 'poll_timeout', None) soonest_timeout = poll_timeout while (socket_map or tasks) and not self._exit.is_set(): try: if socket_map: poll(timeout=soonest_timeout) if tasks: soonest_timeout = sched_poll() else: soonest_timeout = None except (KeyboardInterrupt, SystemExit): # note: these two exceptions are raised in all sub # processes self._exit.set() except select.error: # on Windows we can get WSAENOTSOCK if the client # rapidly connect and disconnects err = sys.exc_info()[1] if os.name == 'nt' and err.args[0] == 10038: for fd in list(socket_map.keys()): try: select.select([fd], [], [], 0) except select.error: try: logger.debug("discarding broken socket %r", socket_map[fd]) del socket_map[fd] except KeyError: # dict changed during iteration pass else: raise else: if poll_timeout: if soonest_timeout is None \ or soonest_timeout > poll_timeout: soonest_timeout = poll_timeout finally: try: self._active_tasks.remove(self._current_task()) except ValueError: pass ioloop.close()
def logline(msg): _depwarn("pyftpdlib.ftpserver.logline() is deprecated") logger.debug(msg)