Compare commits

..

1 Commits

Author SHA1 Message Date
Amir Abbas cd465c1288 Fixes #35 (Dropbox handlers), Fixed FTP response reading length 2017-04-14 11:15:09 +04:30
6 changed files with 59 additions and 81 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
#
s.name = "FileProvider"
s.version = "0.15.4"
s.version = "0.15.5"
s.summary = "FileManager replacement for Local and Remote (WebDAV/FTP/Dropbox/OneDrive/SMB2) files on iOS and macOS."
# This description is used to generate tags and improve search results.
+2 -2
View File
@@ -621,7 +621,7 @@
799396601D48B7BF00086753 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_VERSION_STRING = 0.15.4;
BUNDLE_VERSION_STRING = 0.15.5;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -652,7 +652,7 @@
799396611D48B7BF00086753 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_VERSION_STRING = 0.15.4;
BUNDLE_VERSION_STRING = 0.15.5;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
+2 -2
View File
@@ -128,7 +128,7 @@ open class CloudFileProvider: LocalFileProvider {
query.valueListAttributes = [NSMetadataItemURLKey, NSMetadataItemFSNameKey, NSMetadataItemPathKey, NSMetadataItemFSSizeKey, NSMetadataItemContentTypeTreeKey, NSMetadataItemFSCreationDateKey, NSMetadataItemFSContentChangeDateKey]
query.searchScopes = [self.scope.rawValue]
var finishObserver: NSObjectProtocol?
finishObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: query, queue: nil, using: { (notification) in
finishObserver = NotificationCenter.default.addObserver(forName: .NSMetadataQueryDidFinishGathering, object: query, queue: nil, using: { (notification) in
defer {
query.stop()
NotificationCenter.default.removeObserver(finishObserver!)
@@ -195,7 +195,7 @@ open class CloudFileProvider: LocalFileProvider {
query.valueListAttributes = [NSMetadataItemURLKey, NSMetadataItemFSNameKey, NSMetadataItemPathKey, NSMetadataItemFSSizeKey, NSMetadataItemContentTypeTreeKey, NSMetadataItemFSCreationDateKey, NSMetadataItemFSContentChangeDateKey]
query.searchScopes = [self.scope.rawValue]
var finishObserver: NSObjectProtocol?
finishObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: query, queue: nil, using: { (notification) in
finishObserver = NotificationCenter.default.addObserver(forName: .NSMetadataQueryDidFinishGathering, object: query, queue: nil, using: { (notification) in
defer {
query.stop()
NotificationCenter.default.removeObserver(finishObserver!)
+4 -8
View File
@@ -70,10 +70,6 @@ open class DropboxFileProvider: FileProviderBasicRemote {
}
}
internal var completionHandlersForTasks = [Int: SimpleCompletionHandler]()
internal var downloadCompletionHandlersForTasks = [Int: (URL) -> Void]()
internal var dataCompletionHandlersForTasks = [Int: (Data) -> Void]()
fileprivate var _longpollSession: URLSession?
internal var longpollSession: URLSession {
if _longpollSession == nil {
@@ -323,8 +319,8 @@ extension DropboxFileProvider: FileProviderOperations {
let requestJson = String(jsonDictionary: requestDictionary) ?? ""
request.setValue(requestJson, forHTTPHeaderField: "Dropbox-API-Arg")
let task = session.downloadTask(with: request)
completionHandlersForTasks[task.taskIdentifier] = completionHandler
downloadCompletionHandlersForTasks[task.taskIdentifier] = { tempURL in
completionHandlersForTasks[session.sessionDescription!]?[task.taskIdentifier] = completionHandler
downloadCompletionHandlersForTasks[session.sessionDescription!]?[task.taskIdentifier] = { tempURL in
guard let httpResponse = task.response as? HTTPURLResponse , httpResponse.statusCode < 300 else {
let code = FileProviderHTTPErrorCode(rawValue: (task.response as? HTTPURLResponse)?.statusCode ?? -1)
let errorData : Data? = nil //Data(contentsOf:cacheURL) // TODO: Figure out how to get error response data for the error description
@@ -366,10 +362,10 @@ extension DropboxFileProvider: FileProviderReadWrite {
let requestDictionary: [String: AnyObject] = ["path": correctPath(path)! as NSString]
request.setValue(String(jsonDictionary: requestDictionary), forHTTPHeaderField: "Dropbox-API-Arg")
let task = session.downloadTask(with: request)
completionHandlersForTasks[task.taskIdentifier] = { error in
completionHandlersForTasks[session.sessionDescription!]?[task.taskIdentifier] = { error in
completionHandler(nil, error)
}
downloadCompletionHandlersForTasks[task.taskIdentifier] = { tempURL in
downloadCompletionHandlersForTasks[session.sessionDescription!]?[task.taskIdentifier] = { tempURL in
guard let httpResponse = task.response as? HTTPURLResponse , httpResponse.statusCode < 300 else {
let code = FileProviderHTTPErrorCode(rawValue: (task.response as? HTTPURLResponse)?.statusCode ?? -1)
let errorData : Data? = nil //Data(contentsOf:cacheURL) // TODO: Figure out how to get error response data for the error description
+1 -1
View File
@@ -149,7 +149,7 @@ internal extension DropboxFileProvider {
return nil
}
completionHandlersForTasks[task.taskIdentifier] = { [weak self] error in
completionHandlersForTasks[session.sessionDescription!]?[task.taskIdentifier] = { [weak self] error in
var responseError: FileProviderDropboxError?
if let code = (task.response as? HTTPURLResponse)?.statusCode , code >= 300, let rCode = FileProviderHTTPErrorCode(rawValue: code) {
// We can't fetch server result from delegate!
+49 -67
View File
@@ -441,7 +441,8 @@ extension FTPFileProvider {
}
// Send retreive command
self.execute(command: "TYPE I" + "\r\n" + "REST \(position)" + "\r\n" + "RETR \(filePath)", on: task, minLength: 75, afterSend: { error in
let len = 19 /* TYPE response */ + 65 + String(position).characters.count /* REST Response */ + 53 + filePath.characters.count + String(totalSize).characters.count /* RETR open response */ + 26 /* RETR Transfer complete message. */
self.execute(command: "TYPE I" + "\r\n" + "REST \(position)" + "\r\n" + "RETR \(filePath)", on: task, minLength: len, afterSend: { error in
// starting passive task
onTask?(dataTask)
@@ -547,7 +548,8 @@ extension FTPFileProvider {
}
// Send retreive command
self.execute(command: "TYPE I" + "\r\n" + "REST \(position)" + "\r\n" + "RETR \(filePath)", on: task, minLength: 75, afterSend: { error in
let len = 19 /* TYPE response */ + 65 + String(position).characters.count /* REST Response */ + 53 + filePath.characters.count + String(totalSize).characters.count /* RETR open response */ + 26 /* RETR Transfer complete message. */
self.execute(command: "TYPE I" + "\r\n" + "REST \(position)" + "\r\n" + "RETR \(filePath)", on: task, minLength: len, afterSend: { error in
// starting passive task
onTask?(dataTask)
@@ -614,7 +616,7 @@ extension FTPFileProvider {
return
}
if !(response.hasPrefix("1") || !response.hasPrefix("2")) {
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)
@@ -644,7 +646,8 @@ extension FTPFileProvider {
}
// Send retreive command
self.execute(command: "TYPE I" + "\r\n" + "STOR \(filePath)", on: task, minLength: 75, afterSend: { error in
let len = 17 /* */
self.execute(command: "TYPE I" + "\r\n" + "REST 0" + "\r\n" + "STOR \(filePath)", on: task, minLength: 90 + filePath.characters.count, afterSend: { error in
// starting passive task
let timeout = self.session.configuration.timeoutIntervalForRequest
if self.baseURL?.scheme == "ftps" || self.baseURL?.port == 990 {
@@ -656,74 +659,53 @@ extension FTPFileProvider {
var error: Error?
let chunkSize = 65536
if let data = fromData, data.count > 0 {
var eof = false
var sent: Int = 0
while !eof {
let group = DispatchGroup()
group.enter()
let endIndex = min(data.count, sent + chunkSize)
eof = endIndex == data.count
let subdata = data.subdata(in: sent..<endIndex)
dataTask.write(subdata, timeout: timeout, completionHandler: { (serror) in
error = serror
sent += subdata.count
group.leave()
})
let waitResult = group.wait(timeout: .now() + timeout)
onProgress?(Int64(subdata.count), Int64(sent), Int64(data.count))
if let error = error {
completionHandler(error)
return
}
if waitResult == .timedOut {
error = self.throwError(fromFile?.relativePath ?? filePath, code: URLError.timedOut)
completionHandler(error)
return
}
}
guard let size: Int64 = (fromData != nil ? Int64(fromData!.count) : nil) ?? fromFile?.fileSize else { return }
var fileHandle: FileHandle?
if let file = fromFile {
fileHandle = FileHandle(forReadingAtPath: file.path)
}
defer {
fileHandle?.closeFile()
}
var eof = false
var sent: Int64 = 0
let group = DispatchGroup()
while !eof {
group.enter()
dataTask.closeRead()
dataTask.closeWrite()
completionHandler(nil)
let subdata: Data
if let data = fromData {
let endIndex = min(data.count, Int(sent) + chunkSize)
eof = endIndex == data.count
subdata = data.subdata(in: Int(sent)..<endIndex)
}else if let fileHandle = fileHandle {
subdata = fileHandle.readData(ofLength: chunkSize)
eof = Int64(fileHandle.offsetInFile) == size
} else {
return
}
if subdata.count == 0 { continue }
dataTask.write(subdata, timeout: timeout, completionHandler: { (serror) in
error = serror
sent += Int64(subdata.count)
onProgress?(Int64(subdata.count), sent, size)
group.leave()
})
}
let waitResult = group.wait(timeout: .now() + timeout)
if let error = error {
completionHandler(error)
return
}
guard let file = fromFile, let fileHandle = FileHandle(forReadingAtPath: file.path) else { return }
let size = file.fileSize
fileHandle.seek(toFileOffset: 0)
var eof = false
var sent: Int64 = 0
while !eof {
let group = DispatchGroup()
group.enter()
let data = fileHandle.readData(ofLength: chunkSize)
eof = Int64(fileHandle.offsetInFile) == size
dataTask.write(data, timeout: timeout, completionHandler: { (serror) in
error = serror
sent += Int64(data.count)
group.leave()
})
let waitResult = group.wait(timeout: .now() + timeout)
onProgress?(Int64(data.count), sent, size)
if let error = error {
completionHandler(error)
return
}
if waitResult == .timedOut {
error = self.throwError(fromFile?.relativePath ?? filePath, code: URLError.timedOut)
completionHandler(error)
return
}
if waitResult == .timedOut {
error = self.throwError(fromFile?.relativePath ?? filePath, code: URLError.timedOut)
completionHandler(error)
return
}
dataTask.closeRead()
dataTask.closeWrite()
completionHandler(nil)