diff --git a/Sources/FTPFileProvider.swift b/Sources/FTPFileProvider.swift index 326165a..88126b4 100644 --- a/Sources/FTPFileProvider.swift +++ b/Sources/FTPFileProvider.swift @@ -140,8 +140,10 @@ open class FTPFileProvider: FileProviderBasicRemote { } } + internal var serverSupportsRFC3659: Bool = true + open func contentsOfDirectory(path: String, completionHandler: @escaping (([FileObject], Error?) -> Void)) { - self.contentsOfDirectory(path: path, rfc3659enabled: true, completionHandler: completionHandler) + self.contentsOfDirectory(path: path, rfc3659enabled: serverSupportsRFC3659, completionHandler: completionHandler) } /** @@ -197,7 +199,7 @@ open class FTPFileProvider: FileProviderBasicRemote { } open func attributesOfItem(path: String, completionHandler: @escaping ((FileObject?, Error?) -> Void)) { - self.attributesOfItem(path: path, rfc3659enabled: true, completionHandler: completionHandler) + self.attributesOfItem(path: path, rfc3659enabled: serverSupportsRFC3659, completionHandler: completionHandler) } /** @@ -243,6 +245,7 @@ open class FTPFileProvider: FileProviderBasicRemote { } if response.hasPrefix("500") { + self.serverSupportsRFC3659 = false self.attributesOfItem(path: path, rfc3659enabled: false, completionHandler: completionHandler) } diff --git a/Sources/FTPHelper.swift b/Sources/FTPHelper.swift index c85f62b..de73454 100644 --- a/Sources/FTPHelper.swift +++ b/Sources/FTPHelper.swift @@ -94,10 +94,7 @@ internal extension FTPFileProvider { } guard response.hasPrefix("22") else { - let spaceIndex = response.characters.index(of: "-") ?? response.startIndex - let code = Int(response.substring(to: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines)) ?? -1 - let description = response.substring(from: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines) - let error = FileProviderFTPError(code: code, path: "", errorDescription: description) + let error = FileProviderFTPError(message: response) completionHandler(error) return } @@ -132,10 +129,7 @@ internal extension FTPFileProvider { return } - let spaceIndex = response.characters.index(of: "-") ?? response.startIndex - let code = Int(response.substring(to: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines)) ?? -1 - let description = response.substring(from: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines) - let error = FileProviderFTPError(code: code, path: "", errorDescription: description) + let error = FileProviderFTPError(message: response) completionHandler(error) return } @@ -170,10 +164,7 @@ internal extension FTPFileProvider { } // not logged in else if response.hasPrefix("55") { - let spaceIndex = response.characters.index(of: "-") ?? response.startIndex - let code = Int(response.substring(to: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines)) ?? -1 - let description = response.substring(from: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines) - let error = FileProviderFTPError(code: code, path: "", errorDescription: description) + let error = FileProviderFTPError(message: response) completionHandler(error) return } @@ -352,8 +343,9 @@ internal extension FTPFileProvider { return } - if response.hasPrefix("50") && useMLST { + if response.hasPrefix("500") && useMLST { dataTask.cancel() + self.serverSupportsRFC3659 = false completionHandler([], self.throwError(path, code: URLError.unsupportedURL)) return } @@ -504,10 +496,7 @@ internal extension FTPFileProvider { } if !(response.hasPrefix("1") || !response.hasPrefix("2")) { - let spaceIndex = response.characters.index(of: "-") ?? response.startIndex - let code = Int(response.substring(to: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines)) ?? -1 - let description = response.substring(from: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines) - let error = FileProviderFTPError(code: code, path: "", errorDescription: description) + let error = FileProviderFTPError(message: response) self.dispatch_queue.async { completionHandler(nil, error) @@ -620,10 +609,7 @@ internal extension FTPFileProvider { } if !(response.hasPrefix("1") || response.hasPrefix("2")) { - let spaceIndex = response.characters.index(of: "-") ?? response.startIndex - let code = Int(response.substring(to: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines)) ?? -1 - let description = response.substring(from: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines) - let error = FileProviderFTPError(code: code, path: "", errorDescription: description) + let error = FileProviderFTPError(message: response) self.dispatch_queue.async { completionHandler(nil, error) @@ -748,10 +734,7 @@ internal extension FTPFileProvider { } if !(response.hasPrefix("1") || response.hasPrefix("2")) { - let spaceIndex = response.characters.index(of: "-") ?? response.startIndex - let code = Int(response.substring(to: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines)) ?? -1 - let description = response.substring(from: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines) - let error = FileProviderFTPError(code: code, path: "", errorDescription: description) + let error = FileProviderFTPError(message: response) self.dispatch_queue.async { completionHandler(error) @@ -921,4 +904,22 @@ public struct FileProviderFTPError: Error { public let path: String /// Contents returned by server as error description public let errorDescription: String? + + init(code: Int, path: String, errorDescription: String?) { + self.code = code + self.path = path + self.errorDescription = errorDescription + } + + init(message response: String, path: String = "") { + let message = response.components(separatedBy: .newlines).last ?? "No Response" + let spaceIndex = message.characters.index(of: "-") ?? message.characters.index(of: " ") ?? message.startIndex + self.code = Int(message.substring(to: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines)) ?? -1 + self.path = path + if code > 0 { + self.errorDescription = message.substring(from: spaceIndex).trimmingCharacters(in: .whitespacesAndNewlines) + } else { + self.errorDescription = message + } + } } diff --git a/Sources/RemoteSession.swift b/Sources/RemoteSession.swift index 4e947ad..a66209d 100644 --- a/Sources/RemoteSession.swift +++ b/Sources/RemoteSession.swift @@ -72,6 +72,8 @@ open class RemoteOperationHandle: OperationHandle { /// A protocol defines properties for errors returned by HTTP/S based providers. /// Including Dropbox, OneDrive and WebDAV. public protocol FileProviderHTTPError: Error, CustomStringConvertible { + /// HTTP status codes as an enum. + typealias Code = FileProviderHTTPErrorCode /// HTTP status code returned for error by server. var code: FileProviderHTTPErrorCode { get } /// Path of file/folder casued that error