mirror of
https://github.com/apache/cordova-plugin-file-transfer.git
synced 2026-05-17 00:00:03 +08:00
Merge branch 'dev' (early part)
Conflicts: RELEASENOTES.md plugin.xml
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
Apache Cordova
|
||||
Copyright 2012 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
This product includes a copy of OkHttp from:
|
||||
https://github.com/square/okhttp
|
||||
@@ -57,3 +57,14 @@
|
||||
* CB-5658 Delete stale snapshot of plugin docs
|
||||
* Remove @1 designation from file plugin dependency until pushed to npm
|
||||
* CB-5466: Update to work with filesystem URLs
|
||||
|
||||
### 0.4.2 (Feb 28, 2014)
|
||||
* CB-6106 Ensure that nativeURL is used by file transfer download
|
||||
* iOS: Fix default value for trustAllHosts on iOS (YES->NO)
|
||||
* CB-6059 iOS: Stop FileTransfer.download doing IO on the UI thread.
|
||||
* CB-5588 iOS: Add response headers to upload result
|
||||
* CB-2190 iOS: Make backgroundTaskId apply to downloads as well. Move backgroundTaskId to the delegate.
|
||||
* CB-6050 Android: Use instance method on actual file plugin object to get FileEntry to return on download
|
||||
* CB-6000 Android: Nginx rejects Content-Type without a space before "boundary".
|
||||
* CB-4907 Android: Close stream when we're finished with it
|
||||
* CB-6022 Add backwards-compatibility notes to doc
|
||||
|
||||
+37
-13
@@ -58,7 +58,7 @@ multi-part POST request, and to download files as well.
|
||||
|
||||
__Parameters__:
|
||||
|
||||
- __filePath__: Full path of the file on the device.
|
||||
- __fileURL__: Filesystem URL representing the file on the device. For backwards compatibility, this can also be the full path of the file on the device. (See [Backwards Compatibility Notes] below)
|
||||
|
||||
- __server__: URL of the server to receive the file, as encoded by `encodeURI()`.
|
||||
|
||||
@@ -78,7 +78,8 @@ __Parameters__:
|
||||
|
||||
### Example
|
||||
|
||||
// !! Assumes variable fileURI contains a valid URI to a text file on the device
|
||||
// !! Assumes variable fileURL contains a valid URL to a text file on the device,
|
||||
// for example, cdvfile://localhost/persistent/path/to/file.txt
|
||||
|
||||
var win = function (r) {
|
||||
console.log("Code = " + r.responseCode);
|
||||
@@ -94,7 +95,7 @@ __Parameters__:
|
||||
|
||||
var options = new FileUploadOptions();
|
||||
options.fileKey = "file";
|
||||
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
|
||||
options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
|
||||
options.mimeType = "text/plain";
|
||||
|
||||
var params = {};
|
||||
@@ -104,7 +105,7 @@ __Parameters__:
|
||||
options.params = params;
|
||||
|
||||
var ft = new FileTransfer();
|
||||
ft.upload(fileURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
|
||||
ft.upload(fileURL, encodeURI("http://some.server.com/upload.php"), win, fail, options);
|
||||
|
||||
### Example with Upload Headers and Progress Events (Android and iOS only)
|
||||
|
||||
@@ -124,7 +125,7 @@ __Parameters__:
|
||||
|
||||
var options = new FileUploadOptions();
|
||||
options.fileKey="file";
|
||||
options.fileName=fileURI.substr(fileURI.lastIndexOf('/')+1);
|
||||
options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);
|
||||
options.mimeType="text/plain";
|
||||
|
||||
var headers={'headerParam':'headerValue'};
|
||||
@@ -139,7 +140,7 @@ __Parameters__:
|
||||
loadingStatus.increment();
|
||||
}
|
||||
};
|
||||
ft.upload(fileURI, uri, win, fail, options);
|
||||
ft.upload(fileURL, uri, win, fail, options);
|
||||
|
||||
## FileUploadResult
|
||||
|
||||
@@ -154,6 +155,9 @@ A `FileUploadResult` object is passed to the success callback of the
|
||||
|
||||
- __response__: The HTTP response returned by the server. (DOMString)
|
||||
|
||||
- __headers__: The HTTP response headers by the server. (Object)
|
||||
- Currently supported on iOS only.
|
||||
|
||||
### iOS Quirks
|
||||
|
||||
- Does not support `responseCode` or `bytesSent`.
|
||||
@@ -165,7 +169,7 @@ __Parameters__:
|
||||
|
||||
- __source__: URL of the server to download the file, as encoded by `encodeURI()`.
|
||||
|
||||
- __target__: Full path of the file on the device.
|
||||
- __target__: Filesystem url representing the file on the device. For backwards compatibility, this can also be the full path of the file on the device. (See [Backwards Compatibility Notes] below)
|
||||
|
||||
- __successCallback__: A callback that is passed a `FileEntry` object. _(Function)_
|
||||
|
||||
@@ -177,14 +181,15 @@ __Parameters__:
|
||||
|
||||
### Example
|
||||
|
||||
// !! Assumes filePath is a valid path on the device
|
||||
// !! Assumes variable fileURL contains a valid URL to a path on the device,
|
||||
// for example, cdvfile://localhost/persistent/path/to/downloads/
|
||||
|
||||
var fileTransfer = new FileTransfer();
|
||||
var uri = encodeURI("http://some.server.com/download.php");
|
||||
|
||||
fileTransfer.download(
|
||||
uri,
|
||||
filePath,
|
||||
fileURL,
|
||||
function(entry) {
|
||||
console.log("download complete: " + entry.fullPath);
|
||||
},
|
||||
@@ -207,7 +212,8 @@ Aborts an in-progress transfer. The onerror callback is passed a FileTransferErr
|
||||
|
||||
### Example
|
||||
|
||||
// !! Assumes variable fileURI contains a valid URI to a text file on the device
|
||||
// !! Assumes variable fileURL contains a valid URL to a text file on the device,
|
||||
// for example, cdvfile://localhost/persistent/path/to/file.txt
|
||||
|
||||
var win = function(r) {
|
||||
console.log("Should not be called.");
|
||||
@@ -226,7 +232,7 @@ Aborts an in-progress transfer. The onerror callback is passed a FileTransferErr
|
||||
options.mimeType="image/jpeg";
|
||||
|
||||
var ft = new FileTransfer();
|
||||
ft.upload(fileURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
|
||||
ft.upload(fileURL, encodeURI("http://some.server.com/upload.php"), win, fail, options);
|
||||
ft.abort();
|
||||
|
||||
|
||||
@@ -238,9 +244,9 @@ A `FileTransferError` object is passed to an error callback when an error occurs
|
||||
|
||||
- __code__: One of the predefined error codes listed below. (Number)
|
||||
|
||||
- __source__: URI to the source. (String)
|
||||
- __source__: URL to the source. (String)
|
||||
|
||||
- __target__: URI to the target. (String)
|
||||
- __target__: URL to the target. (String)
|
||||
|
||||
- __http_status__: HTTP status code. This attribute is only available when a response code is received from the HTTP connection. (Number)
|
||||
|
||||
@@ -251,3 +257,21 @@ A `FileTransferError` object is passed to an error callback when an error occurs
|
||||
- `FileTransferError.CONNECTION_ERR`
|
||||
- `FileTransferError.ABORT_ERR`
|
||||
|
||||
## Backwards Compatibility Notes
|
||||
|
||||
Previous versions of this plugin would only accept device-absolute-file-paths as the source for uploads, or as the target for downloads. These paths would typically be of the form
|
||||
|
||||
/var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS)
|
||||
/storage/emulated/0/path/to/file (Android)
|
||||
|
||||
For backwards compatibility, these paths are still accepted, and if your application has recorded paths like these in persistent storage, then they can continue to be used.
|
||||
|
||||
These paths were previously exposed in the `fullPath` property of `FileEntry` and `DirectoryEntry` objects returned by the File plugin. New versions of the File plugin, however, no longer expose these paths to JavaScript.
|
||||
|
||||
If you are upgrading to a new (1.0.0 or newer) version of File, and you have previously been using `entry.fullPath` as arguments to `download()` or `upload()`, then you will need to change your code to use filesystem URLs instead.
|
||||
|
||||
`FileEntry.toURL()` and `DirectoryEntry.toURL()` return a filesystem URL of the form
|
||||
|
||||
cdvfile://localhost/persistent/path/to/file
|
||||
|
||||
which can be used in place of the absolute file path in both `download()` and `upload()` methods.
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
id="org.apache.cordova.file-transfer"
|
||||
version="0.4.1">
|
||||
version="0.4.2">
|
||||
<name>File Transfer</name>
|
||||
<description>Cordova File Transfer Plugin</description>
|
||||
<license>Apache 2.0</license>
|
||||
@@ -11,7 +11,7 @@
|
||||
<issue>https://issues.apache.org/jira/browse/CB/component/12320650</issue>
|
||||
|
||||
<!-- dependency id="org.apache.cordova.file@1" /-->
|
||||
<dependency id="org.apache.cordova.file" />
|
||||
<dependency id="org.apache.cordova.file" version="1.0.1" />
|
||||
|
||||
<js-module src="www/FileTransferError.js" name="FileTransferError">
|
||||
<clobbers target="window.FileTransferError" />
|
||||
|
||||
@@ -315,7 +315,7 @@ public class FileTransfer extends CordovaPlugin {
|
||||
|
||||
// Use a post method.
|
||||
conn.setRequestMethod(httpMethod);
|
||||
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
|
||||
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
|
||||
|
||||
// Set the cookies on the response
|
||||
String cookie = CookieManager.getInstance().getCookie(target);
|
||||
@@ -582,15 +582,19 @@ public class FileTransfer extends CordovaPlugin {
|
||||
if(err != null)
|
||||
{
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(err, "UTF-8"));
|
||||
String line = reader.readLine();
|
||||
while(line != null)
|
||||
{
|
||||
bodyBuilder.append(line);
|
||||
line = reader.readLine();
|
||||
if(line != null)
|
||||
bodyBuilder.append('\n');
|
||||
try {
|
||||
String line = reader.readLine();
|
||||
while(line != null) {
|
||||
bodyBuilder.append(line);
|
||||
line = reader.readLine();
|
||||
if(line != null) {
|
||||
bodyBuilder.append('\n');
|
||||
}
|
||||
}
|
||||
body = bodyBuilder.toString();
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
body = bodyBuilder.toString();
|
||||
}
|
||||
}
|
||||
// IOException can leave connection object in a bad state, so catch all exceptions.
|
||||
@@ -793,9 +797,21 @@ public class FileTransfer extends CordovaPlugin {
|
||||
Log.d(LOG_TAG, "Saved file: " + target);
|
||||
|
||||
// create FileEntry object
|
||||
JSONObject fileEntry = FileUtils.getEntry(file);
|
||||
FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File");
|
||||
if (filePlugin != null) {
|
||||
JSONObject fileEntry = filePlugin.getEntryForFile(file);
|
||||
if (fileEntry != null) {
|
||||
result = new PluginResult(PluginResult.Status.OK, fileEntry);
|
||||
} else {
|
||||
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);
|
||||
Log.e(LOG_TAG, "File plugin cannot represent download path");
|
||||
result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
|
||||
}
|
||||
} else {
|
||||
Log.e(LOG_TAG, "File plugin not found; cannot save downloaded file");
|
||||
result = new PluginResult(PluginResult.Status.ERROR, "File plugin not found; cannot save downloaded file");
|
||||
}
|
||||
|
||||
result = new PluginResult(PluginResult.Status.OK, fileEntry);
|
||||
} catch (FileNotFoundException e) {
|
||||
JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection);
|
||||
Log.e(LOG_TAG, error.toString(), e);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cordova/CDVPlugin.h>
|
||||
#import "CDVFile.h"
|
||||
|
||||
enum CDVFileTransferError {
|
||||
FILE_NOT_FOUND_ERR = 1,
|
||||
@@ -52,8 +53,8 @@ extern NSString* const kOptionsKeyCookie;
|
||||
AndTarget:(NSString*)target
|
||||
AndHttpStatus:(int)httpStatus
|
||||
AndBody:(NSString*)body;
|
||||
@property (nonatomic, strong) NSOperationQueue* queue;
|
||||
@property (readonly) NSMutableDictionary* activeTransfers;
|
||||
@property (nonatomic, assign) UIBackgroundTaskIdentifier backgroundTaskID;
|
||||
@end
|
||||
|
||||
@class CDVFileTransferEntityLengthRequest;
|
||||
@@ -64,6 +65,8 @@ extern NSString* const kOptionsKeyCookie;
|
||||
- (void)cancelTransfer:(NSURLConnection*)connection;
|
||||
|
||||
@property (strong) NSMutableData* responseData; // atomic
|
||||
@property (nonatomic, strong) NSDictionary* responseHeaders;
|
||||
@property (nonatomic, assign) UIBackgroundTaskIdentifier backgroundTaskID;
|
||||
@property (nonatomic, strong) CDVFileTransfer* command;
|
||||
@property (nonatomic, assign) CDVFileTransferDirection direction;
|
||||
@property (nonatomic, strong) NSURLConnection* connection;
|
||||
@@ -79,5 +82,6 @@ extern NSString* const kOptionsKeyCookie;
|
||||
@property (nonatomic, assign) BOOL trustAllHosts;
|
||||
@property (strong) NSFileHandle* targetFileHandle;
|
||||
@property (nonatomic, strong) CDVFileTransferEntityLengthRequest* entityLengthRequest;
|
||||
@property (nonatomic, strong) CDVFile *filePlugin;
|
||||
|
||||
@end;
|
||||
|
||||
+66
-43
@@ -19,7 +19,6 @@
|
||||
|
||||
#import <Cordova/CDV.h>
|
||||
#import "CDVFileTransfer.h"
|
||||
#import "CDVFile.h"
|
||||
#import "CDVLocalFilesystem.h"
|
||||
|
||||
#import <AssetsLibrary/ALAsset.h>
|
||||
@@ -27,8 +26,6 @@
|
||||
#import <AssetsLibrary/ALAssetsLibrary.h>
|
||||
#import <CFNetwork/CFNetwork.h>
|
||||
|
||||
extern CDVFile *filePlugin;
|
||||
|
||||
@interface CDVFileTransfer ()
|
||||
// Sets the requests headers for the request.
|
||||
- (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLRequest*)req;
|
||||
@@ -75,6 +72,10 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
@implementation CDVFileTransfer
|
||||
@synthesize activeTransfers;
|
||||
|
||||
- (void)pluginInitialize {
|
||||
activeTransfers = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
- (NSString*)escapePathComponentForUrlString:(NSString*)urlString
|
||||
{
|
||||
NSRange schemeAndHostRange = [urlString rangeOfString:@"://.*?/" options:NSRegularExpressionSearch];
|
||||
@@ -220,12 +221,6 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
CFStreamCreateBoundPair(NULL, &readStream, &writeStream, kStreamBufferSize);
|
||||
[req setHTTPBodyStream:CFBridgingRelease(readStream)];
|
||||
|
||||
self.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
|
||||
self.backgroundTaskID = UIBackgroundTaskInvalid;
|
||||
NSLog(@"Background task to upload media finished.");
|
||||
}];
|
||||
|
||||
[self.commandDelegate runInBackground:^{
|
||||
if (CFWriteStreamOpen(writeStream)) {
|
||||
NSData* chunks[] = {postBodyBeforeFile, fileData, postBodyAfterFile};
|
||||
@@ -255,7 +250,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
{
|
||||
NSString* source = [command.arguments objectAtIndex:0];
|
||||
NSString* server = [command.arguments objectAtIndex:1];
|
||||
BOOL trustAllHosts = [[command.arguments objectAtIndex:6 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
|
||||
BOOL trustAllHosts = [[command.arguments objectAtIndex:6 withDefault:[NSNumber numberWithBool:NO]] boolValue]; // allow self-signed certs
|
||||
NSString* objectId = [command.arguments objectAtIndex:9];
|
||||
|
||||
CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];
|
||||
@@ -267,6 +262,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
delegate.source = source;
|
||||
delegate.target = server;
|
||||
delegate.trustAllHosts = trustAllHosts;
|
||||
delegate.filePlugin = [self.commandDelegate getCommandInstance:@"File"];
|
||||
|
||||
return delegate;
|
||||
}
|
||||
@@ -282,7 +278,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
if (sourceURL) {
|
||||
// Try to get a CDVFileSystem which will handle this file.
|
||||
// This requires talking to the current CDVFile plugin.
|
||||
fs = [filePlugin filesystemForURL:sourceURL];
|
||||
fs = [[self.commandDelegate getCommandInstance:@"File"] filesystemForURL:sourceURL];
|
||||
}
|
||||
if (fs) {
|
||||
[fs readFileAtURL:sourceURL start:0 end:-1 callback:^(NSData *fileData, NSString *mimeType, CDVFileError err) {
|
||||
@@ -333,25 +329,34 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
return;
|
||||
}
|
||||
CDVFileTransferDelegate* delegate = [self delegateForUploadCommand:command];
|
||||
[NSURLConnection connectionWithRequest:req delegate:delegate];
|
||||
|
||||
if (activeTransfers == nil) {
|
||||
activeTransfers = [[NSMutableDictionary alloc] init];
|
||||
delegate.connection = [[NSURLConnection alloc] initWithRequest:req delegate:delegate startImmediately:NO];
|
||||
if (self.queue == nil) {
|
||||
self.queue = [[NSOperationQueue alloc] init];
|
||||
}
|
||||
[delegate.connection setDelegateQueue:self.queue];
|
||||
|
||||
[activeTransfers setObject:delegate forKey:delegate.objectId];
|
||||
// sets a background task ID for the transfer object.
|
||||
delegate.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||
[delegate cancelTransfer:delegate.connection];
|
||||
}];
|
||||
|
||||
@synchronized (activeTransfers) {
|
||||
activeTransfers[delegate.objectId] = delegate;
|
||||
}
|
||||
[delegate.connection start];
|
||||
}
|
||||
|
||||
- (void)abort:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
NSString* objectId = [command.arguments objectAtIndex:0];
|
||||
|
||||
CDVFileTransferDelegate* delegate = [activeTransfers objectForKey:objectId];
|
||||
|
||||
if (delegate != nil) {
|
||||
[delegate cancelTransfer:delegate.connection];
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:CONNECTION_ABORTED AndSource:delegate.source AndTarget:delegate.target]];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:delegate.callbackId];
|
||||
@synchronized (activeTransfers) {
|
||||
CDVFileTransferDelegate* delegate = activeTransfers[objectId];
|
||||
if (delegate != nil) {
|
||||
[delegate cancelTransfer:delegate.connection];
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:CONNECTION_ABORTED AndSource:delegate.source AndTarget:delegate.target]];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:delegate.callbackId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +365,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
DLog(@"File Transfer downloading file...");
|
||||
NSString* source = [command.arguments objectAtIndex:0];
|
||||
NSString* target = [command.arguments objectAtIndex:1];
|
||||
BOOL trustAllHosts = [[command.arguments objectAtIndex:2 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
|
||||
BOOL trustAllHosts = [[command.arguments objectAtIndex:2 withDefault:[NSNumber numberWithBool:NO]] boolValue]; // allow self-signed certs
|
||||
NSString* objectId = [command.arguments objectAtIndex:3];
|
||||
NSDictionary* headers = [command.arguments objectAtIndex:4 withDefault:nil];
|
||||
|
||||
@@ -374,7 +379,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
* Check here to see if it looks like the user passed in a raw filesystem path. (Perhaps they had the path saved, and were previously using it with the old version of File). If so, normalize it by removing empty path segments, and check with File to see if any of the installed filesystems will handle it. If so, then we will end up with a filesystem url to use for the remainder of this operation.
|
||||
*/
|
||||
target = [target stringByReplacingOccurrencesOfString:@"//" withString:@"/"];
|
||||
targetURL = [filePlugin fileSystemURLforLocalPath:target].url;
|
||||
targetURL = [[self.commandDelegate getCommandInstance:@"File"] fileSystemURLforLocalPath:target].url;
|
||||
} else {
|
||||
targetURL = [NSURL URLWithString:target];
|
||||
}
|
||||
@@ -410,14 +415,23 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
delegate.target = [targetURL absoluteString];
|
||||
delegate.targetURL = targetURL;
|
||||
delegate.trustAllHosts = trustAllHosts;
|
||||
delegate.filePlugin = [self.commandDelegate getCommandInstance:@"File"];
|
||||
delegate.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||
[delegate cancelTransfer:delegate.connection];
|
||||
}];
|
||||
|
||||
delegate.connection = [NSURLConnection connectionWithRequest:req delegate:delegate];
|
||||
delegate.connection = [[NSURLConnection alloc] initWithRequest:req delegate:delegate startImmediately:NO];
|
||||
|
||||
if (activeTransfers == nil) {
|
||||
activeTransfers = [[NSMutableDictionary alloc] init];
|
||||
if (self.queue == nil) {
|
||||
self.queue = [[NSOperationQueue alloc] init];
|
||||
}
|
||||
[delegate.connection setDelegateQueue:self.queue];
|
||||
|
||||
@synchronized (activeTransfers) {
|
||||
activeTransfers[delegate.objectId] = delegate;
|
||||
}
|
||||
|
||||
[activeTransfers setObject:delegate forKey:delegate.objectId];
|
||||
[delegate.connection start];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary*)createFileTransferError:(int)code AndSource:(NSString*)source AndTarget:(NSString*)target
|
||||
@@ -460,13 +474,13 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)onReset
|
||||
{
|
||||
for (CDVFileTransferDelegate* delegate in [activeTransfers allValues]) {
|
||||
[delegate.connection cancel];
|
||||
- (void)onReset {
|
||||
@synchronized (activeTransfers) {
|
||||
while ([activeTransfers count] > 0) {
|
||||
CDVFileTransferDelegate* delegate = [activeTransfers allValues][0];
|
||||
[delegate cancelTransfer:delegate.connection];
|
||||
}
|
||||
}
|
||||
|
||||
[activeTransfers removeAllObjects];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -513,7 +527,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
|
||||
@implementation CDVFileTransferDelegate
|
||||
|
||||
@synthesize callbackId, connection = _connection, source, target, responseData, command, bytesTransfered, bytesExpected, direction, responseCode, objectId, targetFileHandle;
|
||||
@synthesize callbackId, connection = _connection, source, target, responseData, responseHeaders, command, bytesTransfered, bytesExpected, direction, responseCode, objectId, targetFileHandle, filePlugin;
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
|
||||
{
|
||||
@@ -532,6 +546,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
uploadResult = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
if (uploadResponse != nil) {
|
||||
[uploadResult setObject:uploadResponse forKey:@"response"];
|
||||
[uploadResult setObject:self.responseHeaders forKey:@"headers"];
|
||||
}
|
||||
[uploadResult setObject:[NSNumber numberWithLongLong:self.bytesTransfered] forKey:@"bytesSent"];
|
||||
[uploadResult setObject:[NSNumber numberWithInt:self.responseCode] forKey:@"responseCode"];
|
||||
@@ -546,7 +561,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
self.targetFileHandle = nil;
|
||||
DLog(@"File Transfer Download success");
|
||||
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[filePlugin makeEntryForURL:self.targetURL]];
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self.filePlugin makeEntryForURL:self.targetURL]];
|
||||
} else {
|
||||
downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
|
||||
@@ -556,11 +571,12 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
[self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
|
||||
|
||||
// remove connection for activeTransfers
|
||||
[command.activeTransfers removeObjectForKey:objectId];
|
||||
|
||||
// remove background id task in case our upload was done in the background
|
||||
[[UIApplication sharedApplication] endBackgroundTask:self.command.backgroundTaskID];
|
||||
self.command.backgroundTaskID = UIBackgroundTaskInvalid;
|
||||
@synchronized (command.activeTransfers) {
|
||||
[command.activeTransfers removeObjectForKey:objectId];
|
||||
// remove background id task in case our upload was done in the background
|
||||
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
|
||||
self.backgroundTaskID = UIBackgroundTaskInvalid;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeTargetFile
|
||||
@@ -573,7 +589,13 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
- (void)cancelTransfer:(NSURLConnection*)connection
|
||||
{
|
||||
[connection cancel];
|
||||
[self.command.activeTransfers removeObjectForKey:self.objectId];
|
||||
@synchronized (self.command.activeTransfers) {
|
||||
CDVFileTransferDelegate* delegate = self.command.activeTransfers[self.objectId];
|
||||
[self.command.activeTransfers removeObjectForKey:self.objectId];
|
||||
[[UIApplication sharedApplication] endBackgroundTask:delegate.backgroundTaskID];
|
||||
delegate.backgroundTaskID = UIBackgroundTaskInvalid;
|
||||
}
|
||||
|
||||
[self removeTargetFile];
|
||||
}
|
||||
|
||||
@@ -600,6 +622,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
|
||||
self.responseCode = [httpResponse statusCode];
|
||||
self.bytesExpected = [response expectedContentLength];
|
||||
self.responseHeaders = [httpResponse allHeaderFields];
|
||||
if ((self.direction == CDV_TRANSFER_DOWNLOAD) && (self.responseCode == 200) && (self.bytesExpected == NSURLResponseUnknownLength)) {
|
||||
// Kick off HEAD request to server to get real length
|
||||
// bytesExpected will be updated when that response is returned
|
||||
@@ -619,7 +642,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
|
||||
CDVFilesystemURL *sourceURL = [CDVFilesystemURL fileSystemURLWithString:self.target];
|
||||
if (sourceURL && sourceURL.fileSystemName != nil) {
|
||||
// This requires talking to the current CDVFile plugin
|
||||
NSObject<CDVFileSystem> *fs = [filePlugin filesystemForURL:sourceURL];
|
||||
NSObject<CDVFileSystem> *fs = [self.filePlugin filesystemForURL:sourceURL];
|
||||
filePath = [fs filesystemPathForURL:sourceURL];
|
||||
} else {
|
||||
// Extract the path part out of a file: URL.
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
return;
|
||||
}
|
||||
webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
|
||||
webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
|
||||
webRequest.ContentType = "multipart/form-data; boundary=" + Boundary;
|
||||
webRequest.Method = uploadOptions.Method;
|
||||
|
||||
if (!string.IsNullOrEmpty(uploadOptions.Headers))
|
||||
|
||||
+2
-1
@@ -184,7 +184,8 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
|
||||
entry.isFile = result.isFile;
|
||||
entry.name = result.name;
|
||||
entry.fullPath = result.fullPath;
|
||||
entry.filesystem = new FileSystem(result.filesystem == window.PERSISTENT ? 'persistent' : 'temporary');
|
||||
entry.filesystem = new FileSystem(result.filesystemName || (result.filesystem == window.PERSISTENT ? 'persistent' : 'temporary'));
|
||||
entry.nativeURL = result.nativeURL;
|
||||
successCallback(entry);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user