FTP provider fallbacks from EPSV to PASV if extended is not implmented
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user