giampaolo / pyftpdlib

Extremely fast and scalable Python FTP server library
MIT License
1.65k stars 266 forks source link

compatibility with weird windows ftp client #559

Open jk987 opened 2 years ago

jk987 commented 2 years ago

Customer's machine has some windows inside and also some ftp client. This client periodically connects to my ftp server (based on pyftpdlib) to read requests and to store results. The trouble is that the client runs on Windows while the server runs on Linux. When the client sends ftp command

LIST requests_dir\*.*

then the server doesn't understand it. (When I used FileZilla server on Windows then it was ok.) I made following modifications to make it working.

handlers.py: FTPHandler.ftp_LIST(): (When there is * in path then I use glob library to get a list.)

            ...
            if isdir or "*" in path:
                if "*" in path:
                    basedir, filename = os.path.split(path)
                    import glob
                    listing = glob.glob(path)
                    for i in range(len(listing)):
                        basedir, listing[i] = os.path.split(listing[i])
                else:
                    listing = self.run_as_current_user(self.fs.listdir, path)
                    basedir = path
                #print "basedir", basedir, "listing", listing
                if isinstance(listing, list):
                    try:
                        # RFC 959 recommends the listing to be sorted.
                        listing.sort()
                    except UnicodeDecodeError:
                        # (Python 2 only) might happen on filesystem not
                        # supporting UTF8 meaning os.listdir() returned a list
                        # of mixed bytes and unicode strings:
                        # http://goo.gl/6DLHD
                        # http://bugs.python.org/issue683592
                        pass
                iterator = self.fs.format_list(basedir, listing)
            else:
                basedir, filename = os.path.split(path)
                #print "basedir", basedir, "filename", filename
                self.fs.lstat(path)  # raise exc in case of problems
                iterator = self.fs.format_list(basedir, [filename])
            ...

filesystems.py: AbstractedFS.ftpnorm(): (Always replace backslash. Not very smart, should be by some parameter.)

        ...
        # normalize string in a standard web-path notation having '/'
        # as separator.
        if True or os.sep == "\\":
            p = p.replace("\\", "/")
        ...

It is up to you whether you would get inspired by these modifications. But they are necessary for me.

(edited formatting)