Exemplo n.º 1
0
    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
            if log:
                self._log_start()
            try:
                self.ioloop.loop(timeout, blocking)
            except (KeyboardInterrupt, SystemExit):
                pass
            if blocking:
                if log:
                    logger.info(
                        ">>> shutting down FTP server (%s active fds) <<<",
                        self._map_len())
                self.close_all()
        else:
            self.ioloop.loop(timeout, blocking)
Exemplo n.º 2
0
    def _log_start(self):
        if (not logging.getLogger('pyftpdlib').handlers and not
                logging.root.handlers):
            # If we get to this point it means the user hasn't
            # configured any logger. We want logging to be on
            # by default (stderr).
            from 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
        addr = self.address
        if hasattr(self.handler, 'ssl_protocol'):
            proto = "FTP+SSL"
        else:
            proto = "FTP"
        logger.info(">>> starting %s server on %s:%s, pid=%i <<<"
                    % (proto, addr[0], addr[1], os.getpid()))
        logger.info("poller: %r", self.ioloop.__class__)
        logger.info("masquerade (NAT) address: %s",
                    self.handler.masquerade_address)
        logger.info("passive ports: %s", pasv_ports)
        if os.name == 'posix':
            logger.info("use sendfile(2): %s", self.handler.use_sendfile)
Exemplo n.º 3
0
    def _log_start(self):
        if (not logging.getLogger('pyftpdlib').handlers
                and not logging.root.handlers):
            # If we get to this point it means the user hasn't
            # configured any logger. We want logging to be on
            # by default (stderr).
            from 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
        addr = self.address
        if hasattr(self.handler, 'ssl_protocol'):
            proto = "FTP+SSL"
        else:
            proto = "FTP"
        logger.info(">>> starting %s server on %s:%s, pid=%i <<<" %
                    (proto, addr[0], addr[1], os.getpid()))
        logger.info("poller: %r", self.ioloop.__class__)
        logger.info("masquerade (NAT) address: %s",
                    self.handler.masquerade_address)
        logger.info("passive ports: %s", pasv_ports)
        if os.name == 'posix':
            logger.info("use sendfile(2): %s", self.handler.use_sendfile)
Exemplo n.º 4
0
 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.info(">>> shutting down FTP server (%s active " "workers) <<<", self._map_len())
             self.close_all()
     else:
         self.ioloop.loop(timeout, blocking)
Exemplo n.º 5
0
 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.info(">>> shutting down FTP server (%s active " \
                             "workers) <<<", self._map_len())
             self.close_all()
     else:
         self.ioloop.loop(timeout, blocking)
Exemplo n.º 6
0
 def serve_forever(self, timeout=None, blocking=True, handle_exit=True):
     if handle_exit:
         log = handle_exit and blocking
         if log:
             self._log_start()
         try:
             self.ioloop.loop(timeout, blocking)
         except (KeyboardInterrupt, SystemExit):
             logger.info("received interrupt signal")
         if blocking:
             if log:
                 logger.info(
                     ">>> shutting down FTP server (%s active socket "
                     "fds) <<<",
                     self._map_len())
             self.close_all()
     else:
         self.ioloop.loop(timeout, blocking)
Exemplo n.º 7
0
    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 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.info(">>> starting FTP server on %s:%s <<<" % self.address)
        logger.info("poller: %r", self.ioloop.__class__)
        logger.info("masquerade (NAT) address: %s", self.handler.masquerade_address)
        logger.info("passive ports: %s", pasv_ports)
        if os.name == "posix":
            logger.info("use sendfile(2): %s", self.handler.use_sendfile)
Exemplo n.º 8
0
    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 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.info(">>> starting FTP server on %s:%s <<<" % self.address)
        logger.info("poller: %r", self.ioloop.__class__)
        logger.info("masquerade (NAT) address: %s",
                    self.handler.masquerade_address)
        logger.info("passive ports: %s", pasv_ports)
        if os.name == 'posix':
            logger.info("use sendfile(2): %s", self.handler.use_sendfile)
Exemplo n.º 9
0
 def _log_start(self):
     FTPServer._log_start(self)
     logger.info("dispatcher: %r", self.__class__)
Exemplo n.º 10
0
    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
            sched_poll = ioloop.sched.poll
            poll_timeout = getattr(self, 'poll_timeout', None)
            soonest_timeout = poll_timeout

            while (ioloop.socket_map or ioloop.sched._tasks) and \
                    not self._exit.is_set():
                try:
                    if ioloop.socket_map:
                        poll(timeout=soonest_timeout)
                    if ioloop.sched._tasks:
                        soonest_timeout = sched_poll()
                        # Handle the case where socket_map is emty but some
                        # cancelled scheduled calls are still around causing
                        # this while loop to hog CPU resources.
                        # In theory this should never happen as all the sched
                        # functions are supposed to be cancel()ed on close()
                        # but by using threads we can incur into
                        # synchronization issues such as this one.
                        # https://github.com/giampaolo/pyftpdlib/issues/245
                        if not ioloop.socket_map:
                            # get rid of cancel()led calls
                            ioloop.sched.reheapify()
                            soonest_timeout = sched_poll()
                            if soonest_timeout:
                                time.sleep(min(soonest_timeout, 1))
                    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(ioloop.socket_map.keys()):
                            try:
                                select.select([fd], [], [], 0)
                            except select.error:
                                try:
                                    logger.info("discarding broken socket %r",
                                                ioloop.socket_map[fd])
                                    del ioloop.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:
            ioloop.close()
Exemplo n.º 11
0
def log(msg):
    _depwarn("pyftpdlib.ftpserver.log() is deprecated")
    logger.info(msg)
Exemplo n.º 12
0
def log(msg):
    _depwarn("pyftpdlib.ftpserver.log() is deprecated")
    logger.info(msg)
Exemplo n.º 13
0
    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.info("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()
Exemplo n.º 14
0
    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.info("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()