Caching ftp server support for RFC3659, Possible fix for #47

This commit is contained in:
Amir Abbas
2017-05-23 19:10:04 +04:30
parent f94719deb0
commit 1dd7561215
3 changed files with 33 additions and 27 deletions
+5 -2
View File
@@ -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)
}
+26 -25
View File
@@ -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
}
}
}
+2
View File
@@ -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