CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyftpdlib

Very fast asynchronous FTP server library providing RFC-959 compliant FTP servers with advanced features including FTPS, IPv6, Unicode support, and flexible authentication systems

Pending
Overview
Eval results
Files

handlers.mddocs/

FTP Protocol Handlers

Main FTP protocol implementation providing comprehensive RFC-959 compliant FTP server functionality with 40+ FTP commands, SSL/TLS encryption, data transfer management, and extensive customization options through callback hooks and configurable parameters.

Capabilities

Main FTP Handler

Core FTP protocol interpreter implementing the complete FTP command set with configurable behavior and extensive callback hooks for customization.

class FTPHandler:
    # Core configuration attributes
    authorizer: 'Authorizer' = DummyAuthorizer()
    active_dtp: type = 'ActiveDTP'
    passive_dtp: type = 'PassiveDTP' 
    dtp_handler: type = 'DTPHandler'
    abstracted_fs: type = 'AbstractedFS'
    proto_cmds: dict = {}  # FTP command definitions
    
    # Session and security settings
    timeout: int = 300
    banner: str = f"pyftpdlib {__ver__} ready."
    max_login_attempts: int = 3
    permit_foreign_addresses: bool = False
    permit_privileged_ports: bool = False
    
    # Network configuration
    masquerade_address: str = None
    masquerade_address_map: dict = {}
    passive_ports: range = None
    
    # Performance settings
    use_gmt_times: bool = True
    use_sendfile: bool = True  # Use sendfile() system call if available
    tcp_no_delay: bool = True  # Disable Nagle algorithm
    
    # Character encoding
    encoding: str = "utf8"
    unicode_errors: str = 'replace'
    
    # Logging configuration
    log_prefix: str = '%(remote_ip)s:%(remote_port)s-[%(username)s]'
    auth_failed_timeout: int = 3
    
    def __init__(self, conn, server, ioloop=None):
        """
        Initialize FTP session handler.
        
        Parameters:
        - conn: client socket connection
        - server: FTPServer instance
        - ioloop: IOLoop instance (optional)
        """
    
    # Session management
    def handle(self):
        """Send welcome banner to client."""
    
    def handle_max_cons(self):
        """Handle maximum connections limit reached."""
    
    def handle_max_cons_per_ip(self):
        """Handle maximum connections per IP limit reached."""
    
    def handle_timeout(self):
        """Handle session timeout."""
    
    def process_command(self, cmd, *args, **kwargs):
        """
        Process FTP command from client.
        
        Parameters:
        - cmd: FTP command name
        - *args: command arguments
        - **kwargs: additional options
        """
    
    def flush_account(self):
        """Reset user session state."""
    
    def run_as_current_user(self, function, *args, **kwargs):
        """Execute function with current user privileges."""
    
    # Connection event callbacks
    def on_connect(self):
        """Called when client connects."""
    
    def on_disconnect(self):
        """Called when client disconnects."""
    
    # Authentication event callbacks  
    def on_login(self, username):
        """Called when user successfully logs in."""
    
    def on_login_failed(self, username):
        """Called when user login fails."""
    
    def on_logout(self, username):
        """Called when user logs out."""
    
    # File transfer event callbacks
    def on_file_sent(self, file):
        """Called when file transfer (RETR) completes successfully."""
    
    def on_file_received(self, file):  
        """Called when file transfer (STOR/APPE) completes successfully."""
    
    def on_incomplete_file_sent(self, file):
        """Called when file transfer (RETR) is interrupted."""
    
    def on_incomplete_file_received(self, file):
        """Called when file transfer (STOR/APPE) is interrupted."""
    
    # Authentication commands
    def ftp_USER(self, line):
        """USER command - specify username."""
    
    def ftp_PASS(self, line):
        """PASS command - specify password."""
    
    def ftp_QUIT(self, line):
        """QUIT command - terminate session."""
    
    # Data connection commands
    def ftp_PORT(self, line):
        """PORT command - specify client port for active mode."""
    
    def ftp_EPRT(self, line):
        """EPRT command - extended PORT for IPv6."""
    
    def ftp_PASV(self, line):
        """PASV command - enter passive mode."""
    
    def ftp_EPSV(self, line):
        """EPSV command - extended PASV for IPv6."""
    
    # Directory listing commands
    def ftp_LIST(self, path):
        """LIST command - detailed directory listing."""
    
    def ftp_NLST(self, path):
        """NLST command - name-only directory listing."""
    
    def ftp_MLST(self, path):
        """MLST command - machine-readable file info."""
    
    def ftp_MLSD(self, path):
        """MLSD command - machine-readable directory listing."""
    
    # File transfer commands
    def ftp_RETR(self, file):
        """RETR command - retrieve/download file."""
    
    def ftp_STOR(self, file):
        """STOR command - store/upload file."""
    
    def ftp_APPE(self, file):
        """APPE command - append to file."""
    
    def ftp_STOU(self, line):
        """STOU command - store file with unique name."""
    
    def ftp_REST(self, line):
        """REST command - set file restart position."""
    
    def ftp_ABOR(self, line):
        """ABOR command - abort current transfer."""
    
    # Directory navigation commands
    def ftp_CWD(self, path):
        """CWD command - change working directory."""
    
    def ftp_CDUP(self, path):
        """CDUP command - change to parent directory."""
    
    def ftp_PWD(self, line):
        """PWD command - print working directory."""
    
    # File/directory management commands
    def ftp_MKD(self, path):
        """MKD command - create directory."""
    
    def ftp_RMD(self, path):
        """RMD command - remove directory."""
    
    def ftp_DELE(self, path):
        """DELE command - delete file."""
    
    def ftp_RNFR(self, path):
        """RNFR command - rename from (source)."""
    
    def ftp_RNTO(self, path):
        """RNTO command - rename to (destination)."""
    
    # File information commands
    def ftp_SIZE(self, path):
        """SIZE command - get file size."""
    
    def ftp_MDTM(self, path):
        """MDTM command - get file modification time."""
    
    def ftp_MFMT(self, path):
        """MFMT command - set file modification time."""
    
    # Transfer parameter commands
    def ftp_TYPE(self, line):
        """TYPE command - set transfer type (ASCII/Binary)."""
    
    def ftp_MODE(self, line):
        """MODE command - set transfer mode."""
    
    def ftp_STRU(self, line):
        """STRU command - set file structure."""
    
    # Server information commands
    def ftp_STAT(self, line):
        """STAT command - server/transfer status."""
    
    def ftp_FEAT(self, line):
        """FEAT command - list server features."""
    
    def ftp_HELP(self, line):
        """HELP command - display help information."""
    
    # SITE commands (server-specific)
    def ftp_SITE_CHMOD(self, path):
        """SITE CHMOD command - change file permissions."""
    
    def ftp_SITE_HELP(self, line):
        """SITE HELP command - SITE command help."""

SSL/TLS FTP Handler

FTP handler with SSL/TLS encryption support providing secure FTP (FTPS) capabilities with flexible security requirements.

class TLS_FTPHandler(FTPHandler):
    # SSL/TLS configuration
    tls_control_required: bool = False
    tls_data_required: bool = False
    certfile: str = None
    keyfile: str = None
    ssl_protocol = None  # SSL.TLS_SERVER_METHOD
    ssl_options = None   # SSL options (no SSLv2/SSLv3/compression)
    ssl_context = None   # Pre-configured SSL context
    
    # Additional SSL/TLS commands
    def ftp_AUTH(self, line):
        """AUTH command - initiate SSL/TLS handshake."""
    
    def ftp_PBSZ(self, line):
        """PBSZ command - set protection buffer size."""
    
    def ftp_PROT(self, line):
        """PROT command - set data channel protection level."""
    
    def secure_connection(self, ssl_context):
        """Upgrade connection to SSL/TLS."""
    
    def handle_ssl_established(self):
        """Called when SSL handshake completes."""
    
    def handle_ssl_shutdown(self):
        """Called when SSL connection shuts down."""
    
    def handle_failed_ssl_handshake(self):
        """Called when SSL handshake fails."""

Data Transfer Protocol Handlers

Classes managing FTP data connections for file transfers, supporting both active and passive modes with optional SSL/TLS encryption.

class DTPHandler:
    # Transfer configuration
    timeout: int = 300
    ac_in_buffer_size: int = 65536
    ac_out_buffer_size: int = 65536
    
    def __init__(self, sock, cmd_channel):
        """
        Initialize data transfer handler.
        
        Parameters:
        - sock: data connection socket
        - cmd_channel: associated FTP command channel
        """
    
    def use_sendfile(self):
        """Check if sendfile() optimization can be used."""
    
    def push(self, data):
        """Send data to client."""
    
    def push_with_producer(self, producer):
        """Send data using producer pattern."""
    
    def enable_receiving(self, type, cmd):
        """Enable data receiving mode for uploads."""
    
    def get_transmitted_bytes(self):
        """Get number of bytes transferred."""
    
    def get_elapsed_time(self):
        """Get transfer duration in seconds."""
    
    def transfer_in_progress(self):
        """Check if transfer is currently active."""
    
    def handle_read(self):
        """Handle incoming data during upload."""
    
    def handle_timeout(self):
        """Handle stalled transfer timeout."""
    
    def close(self):
        """Close data connection and cleanup."""

class ThrottledDTPHandler(DTPHandler):
    # Bandwidth limiting
    read_limit: int = 0    # Max read bytes/sec (0 = unlimited)
    write_limit: int = 0   # Max write bytes/sec (0 = unlimited)
    auto_sized_buffers: bool = True

class TLS_DTPHandler(DTPHandler):
    """SSL/TLS enabled data transfer handler."""

class PassiveDTP:
    timeout: int = 30
    backlog: int = None
    
    def __init__(self, cmd_channel, extmode=False):
        """Initialize passive data connection listener."""
    
    def handle_accepted(self, sock, addr):
        """Handle client connection to passive port."""

class ActiveDTP:
    timeout: int = 30
    
    def __init__(self, ip, port, cmd_channel):
        """Initialize active data connection to client."""
    
    def handle_connect(self):
        """Handle successful connection to client."""

Data Producers

Producer classes for efficient file transfer using the producer/consumer pattern.

class FileProducer:
    buffer_size: int = 65536
    
    def __init__(self, file, type):
        """
        Initialize file producer.
        
        Parameters:
        - file: file object to read from
        - type: transfer type ('i' for binary, 'a' for ASCII)
        """
    
    def more(self):
        """Read and return next chunk of file data."""

class BufferedIteratorProducer:
    loops: int = 20
    
    def __init__(self, iterator):
        """Initialize producer from iterator."""
    
    def more(self):
        """Get next batch from iterator."""

Exception Classes

class _FileReadWriteError(OSError):
    """File read/write errors during transfer."""

class _GiveUpOnSendfile(Exception):
    """Fallback from sendfile() to regular send()."""

Constants

CR_BYTE: int  # Carriage return byte value
proto_cmds: dict  # FTP command definitions with properties

Usage Examples

Basic FTP Handler Setup

from pyftpdlib.handlers import FTPHandler
from pyftpdlib.authorizers import DummyAuthorizer

# Configure authorizer
authorizer = DummyAuthorizer()
authorizer.add_user("user", "pass", "/home/user", perm="elradfmwMT")

# Configure handler
handler = FTPHandler
handler.authorizer = authorizer
handler.banner = "Welcome to my FTP server"
handler.timeout = 600

SSL/TLS FTP Server

from pyftpdlib.handlers import TLS_FTPHandler

class MyTLS_FTPHandler(TLS_FTPHandler):
    certfile = "/path/to/certificate.pem"
    keyfile = "/path/to/private_key.pem"
    tls_control_required = True
    tls_data_required = True

handler = MyTLS_FTPHandler
handler.authorizer = authorizer

Custom Handler with Callbacks

class CustomFTPHandler(FTPHandler):
    def on_connect(self):
        print(f"Client connected from {self.remote_ip}")
    
    def on_login(self, username):
        print(f"User {username} logged in successfully")
        
    def on_file_sent(self, file):
        print(f"File {file} sent to {self.username}")
        
    def on_file_received(self, file):
        print(f"File {file} received from {self.username}")
    
    def on_logout(self, username):
        print(f"User {username} logged out")

handler = CustomFTPHandler
handler.authorizer = authorizer

Performance Optimization

class OptimizedFTPHandler(FTPHandler):
    # Enable performance optimizations
    use_sendfile = True          # Use sendfile() for uploads
    tcp_no_delay = True          # Disable Nagle algorithm
    
    # Configure timeouts
    timeout = 300                # 5 minute session timeout
    auth_failed_timeout = 1      # Fast auth failure response
    
    # Buffer sizes for data transfers
    dtp_handler = ThrottledDTPHandler

# Configure bandwidth limits
class BandwidthLimitedDTPHandler(ThrottledDTPHandler):
    read_limit = 1024 * 100      # 100 KB/s download limit
    write_limit = 1024 * 50      # 50 KB/s upload limit

handler = OptimizedFTPHandler  
handler.dtp_handler = BandwidthLimitedDTPHandler

Network Configuration

class NetworkConfiguredHandler(FTPHandler):
    # NAT/Firewall configuration
    masquerade_address = "203.0.113.10"     # External IP for PASV
    passive_ports = range(50000, 50099)     # PASV port range
    permit_foreign_addresses = False        # Block FXP transfers
    permit_privileged_ports = False         # Block privileged ports

handler = NetworkConfiguredHandler
handler.authorizer = authorizer

Logging Configuration

class LoggingFTPHandler(FTPHandler):
    log_prefix = '[%(asctime)s] %(remote_ip)s:%(remote_port)s-[%(username)s]'
    
    def process_command(self, cmd, *args, **kwargs):
        print(f"Command: {cmd} {' '.join(args) if args else ''}")
        return super().process_command(cmd, *args, **kwargs)

handler = LoggingFTPHandler
handler.authorizer = authorizer

Custom Command Implementation

class ExtendedFTPHandler(FTPHandler):
    def ftp_SITE_USAGE(self, line):
        """Custom SITE USAGE command."""
        # Implementation here
        self.respond("200 Disk usage: 50% of 1TB")
    
    # Add to proto_cmds to register command
    proto_cmds = FTPHandler.proto_cmds.copy()
    proto_cmds['SITE USAGE'] = dict(
        perm=None, auth=True, help='Syntax: SITE USAGE (show disk usage)'
    )

handler = ExtendedFTPHandler
handler.authorizer = authorizer

Install with Tessl CLI

npx tessl i tessl/pypi-pyftpdlib

docs

authorizers.md

filesystems.md

handlers.md

index.md

ioloop.md

servers.md

utilities.md

tile.json