From 37ce9c95fcb64fde8b911998df56bbbd1740c373 Mon Sep 17 00:00:00 2001 From: Amir Abbas Date: Tue, 13 Mar 2018 10:53:26 +0330 Subject: [PATCH] FTP provider fallbacks from EPSV to PASV if extended is not implmented --- Sources/FTPFileProvider.swift | 8 +++++--- Sources/FTPHelper.swift | 10 ++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Sources/FTPFileProvider.swift b/Sources/FTPFileProvider.swift index 2ad7b4e..d8b8b36 100644 --- a/Sources/FTPFileProvider.swift +++ b/Sources/FTPFileProvider.swift @@ -16,6 +16,8 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil /// FTP data connection mode. public enum Mode: String { + /// Passive mode for FTP and Extended Passive mode for FTP over TLS. + case `default` /// Data connection would establish by client to determined server host/port. case passive /// Data connection would establish by server to determined client's port. @@ -82,10 +84,10 @@ open class FTPFileProvider: FileProviderBasicRemote, FileProviderOperations, Fil - Parameter credential: a `URLCredential` object contains user and password. - Parameter cache: A URLCache to cache downloaded files and contents. (unimplemented for FTP and should be nil) - - Important: Extended Passive or Active modes won't fallback to normal Passive or Active modes. If your server - does not support these relatively new modes, connection will fail qith `URLError.badServerResponse` error. + - Important: Extended Passive or Active modes will fallback to normal Passive or Active modes if your server + does not support extended modes. */ - public init? (baseURL: URL, mode: Mode = .passive, credential: URLCredential? = nil, cache: URLCache? = nil) { + public init? (baseURL: URL, mode: Mode = .default, credential: URLCredential? = nil, cache: URLCache? = nil) { guard ["ftp", "ftps", "ftpes"].contains(baseURL.uw_scheme.lowercased()) else { return nil } diff --git a/Sources/FTPHelper.swift b/Sources/FTPHelper.swift index 7a6eec9..be4564d 100644 --- a/Sources/FTPHelper.swift +++ b/Sources/FTPHelper.swift @@ -223,6 +223,10 @@ internal extension FTPFileProvider { throw self.urlError("", code: .badServerResponse) } + if response.trimmingCharacters(in: .whitespaces).hasPrefix("50") { + self.ftpPassive(task, completionHandler: completionHandler) + } + let destArray = destString.components(separatedBy: "|") guard destArray.count >= 4, let port = Int(trimmedNumber(destArray[3])) else { throw self.urlError("", code: .badServerResponse) @@ -284,6 +288,12 @@ internal extension FTPFileProvider { func ftpDataConnect(_ task: FileProviderStreamTask, completionHandler: @escaping (_ dataTask: FileProviderStreamTask?, _ error: Error?) -> Void) { switch self.mode { + case .default: + if self.baseURL?.port == 990 || self.baseURL?.scheme == "ftps" || self.baseURL?.scheme == "ftpes" { + self.ftpExtendedPassive(task, completionHandler: completionHandler) + } else { + self.ftpPassive(task, completionHandler: completionHandler) + } case .passive: self.ftpPassive(task, completionHandler: completionHandler) case .extendedPassive: