You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2015/02/03 20:53:33 UTC

[2/4] cordova-plugin-file-transfer git commit: CB-8095 Rewrite upload method to support progress events properly

CB-8095 Rewrite upload method to support progress events properly

* Uses backgroundUploader class instead of XHR
* Returns proper response body in case of error


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/commit/18f3efda
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/tree/18f3efda
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/diff/18f3efda

Branch: refs/heads/master
Commit: 18f3efdad2379102e7a6d41924d919b58bb94868
Parents: 046e9ae
Author: Vladimir Kotikov <v-...@microsoft.com>
Authored: Thu Nov 27 18:49:13 2014 +0300
Committer: Vladimir Kotikov <v-...@microsoft.com>
Committed: Thu Jan 8 16:50:15 2015 +0300

----------------------------------------------------------------------
 src/windows/FileTransferProxy.js | 163 +++++++++++++++++++++++++---------
 1 file changed, 121 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/blob/18f3efda/src/windows/FileTransferProxy.js
----------------------------------------------------------------------
diff --git a/src/windows/FileTransferProxy.js b/src/windows/FileTransferProxy.js
index 57c9ccd..5211464 100644
--- a/src/windows/FileTransferProxy.js
+++ b/src/windows/FileTransferProxy.js
@@ -106,55 +106,134 @@ exec(win, fail, 'FileTransfer', 'upload',
                 mimeType = storageFile.contentType;
             }
 
-            storageFile.openAsync(Windows.Storage.FileAccessMode.read)
-            .then(function (stream) {
+            // check if download isn't already cancelled
+            var uploadOp = fileTransferOps[uploadId];
+            if (uploadOp && uploadOp.state === FileTransferOperation.CANCELLED) {
+                // Here we should call errorCB with ABORT_ERR error
+                errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));
+                return;
+            }
 
-                // check if upload isn't already cancelled
-                var uploadOp = fileTransferOps[uploadId];
-                if (uploadOp && uploadOp.state == FileTransferOperation.CANCELLED) {
-                    // Here we should call errorCB with ABORT_ERR error
-                    errorCallback(new FTErr(FTErr.ABORT_ERR, filePath, server));
-                    return;
+            // setting request headers for uploader
+            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
+            for (var header in headers) {
+                if (headers.hasOwnProperty(header)) {
+                    uploader.setRequestHeader(header, headers[header]);
                 }
+            }
 
-                var blob = MSApp.createBlobFromRandomAccessStream(mimeType, stream);
-
-                var formData = new FormData();
-                formData.append(fileKey, blob, fileName);
-                // add params
-                for(var key in params) {
-                    formData.append(key,params[key]);
+            // adding params supplied to request payload
+            var transferParts = [];
+            for (var key in params) {
+                if (params.hasOwnProperty(key)) {
+                    var contentPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart();
+                    contentPart.setHeader("Content-Disposition", "form-data; name=\"" + key + "\"");
+                    contentPart.setText(params[key]);
+                    transferParts.push(contentPart);
                 }
+            }
 
-                var uploadOperation;
-                try {
-                    // Create XHR promise for uploading data to server
-                    uploadOperation = WinJS.xhr({ type: "POST", url: server, data: formData, headers: headers });
-                    fileTransferOps[uploadId].promise = uploadOperation;
-                } catch (e) {
-                    // it will fail if URL is malformed, so we handle this situation
-                    errorCallback(new FTErr(FTErr.INVALID_URL_ERR, filePath, server, null, null, e));
-                    return;
-                }
+            // Adding file to upload to request payload
+            var fileToUploadPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart(fileKey, fileName);
+            fileToUploadPart.setFile(storageFile);
+            transferParts.push(fileToUploadPart);
+
+            // create download object. This will throw an exception if URL is malformed
+            var uri = new Windows.Foundation.Uri(server);
+            try {
+                uploader.createUploadAsync(uri, transferParts).then(
+                    function (upload) {
+
+                        // update internal TransferOperation object with newly created promise
+                        var uploadOperation = upload.startAsync();
+                        fileTransferOps[uploadId].promise = uploadOperation;
+
+                        uploadOperation.then(
+                            function (result) {
+                                // Update TransferOperation object with new state, delete promise property
+                                // since it is not actual anymore
+                                var currentUploadOp = fileTransferOps[uploadId];
+                                if (currentUploadOp) {
+                                    currentUploadOp.state = FileTransferOperation.DONE;
+                                    currentUploadOp.promise = null;
+                                }
+
+                                var response = result.getResponseInformation();
+                                // creating a data reader, attached to response stream to get server's response
+                                var reader = new Windows.Storage.Streams.DataReader(result.getResultStreamAt(0));
+                                reader.loadAsync(result.progress.bytesReceived).then(function(size) {
+                                    var responseText = reader.readString(size);
+                                    var ftResult = new FileUploadResult(size, response.statusCode, responseText);
+                                    successCallback(ftResult);
+                                    reader.close();
+                                });
+                            },
+                            function (error) {
+
+                                var source = nativePathToCordova(filePath);
+
+                                // Handle download error here.
+                                // Wrap this routines into promise due to some async methods
+                                var getTransferError = new WinJS.Promise(function(resolve) {
+                                    if (error.message === 'Canceled') {
+                                        // If download was cancelled, message property will be specified
+                                        resolve(new FTErr(FTErr.ABORT_ERR, source, server, null, null, error));
+                                    } else {
+                                        // in the other way, try to get response property
+                                        var response = upload.getResponseInformation();
+                                        if (!response) {
+                                            resolve(new FTErr(FTErr.CONNECTION_ERR, source, server));
+                                        } else {
+                                            var reader = new Windows.Storage.Streams.DataReader(upload.getResultStreamAt(0));
+                                            reader.loadAsync(upload.progress.bytesReceived).then(function (size) {
+                                                var responseText = reader.readString(size);
+                                                resolve(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, server, response.statusCode, responseText, error));
+                                                reader.close();
+                                            });
+                                        }
+                                    }
+                                });
 
-                uploadOperation.then(function (response) {
-                    storageFile.getBasicPropertiesAsync().done(function(basicProperties) {
-                        var ftResult = new FileUploadResult(basicProperties.size, response.status, response.responseText);
-                        successCallback(ftResult);
-                    });
-                }, function(err) {
-                    if ('status' in err) {
-                        errorCallback(new FTErr(FTErr.CONNECTION_ERR, filePath, server, err.status, err.responseText, err));
-                    } else {
-                        errorCallback(new FTErr(FTErr.INVALID_URL_ERR, filePath, server, null, null, err));
+                                // Update TransferOperation object with new state, delete promise property
+                                // since it is not actual anymore
+                                var currentUploadOp = fileTransferOps[uploadId];
+                                if (currentUploadOp) {
+                                    currentUploadOp.state = FileTransferOperation.CANCELLED;
+                                    currentUploadOp.promise = null;
+                                }
+
+                                // Cleanup, remove incompleted file
+                                getTransferError.then(function(transferError) {
+                                    storageFile.deleteAsync().then(function() {
+                                        errorCallback(transferError);
+                                    });
+                                });
+
+
+                            },
+                            function (evt) {
+
+
+                                var progressEvent = new ProgressEvent('progress', {
+                                    loaded: evt.progress.bytesSent,
+                                    total: evt.progress.totalBytesToSend,
+                                    target: evt.resultFile
+                                });
+                                progressEvent.lengthComputable = true;
+                                successCallback(progressEvent, { keepCallback: true });
+                            }
+                        );
+
+                    },
+                    function (err) {
+                        var errorObj = new FTErr(FTErr.INVALID_URL_ERR);
+                        errorObj.exception = err;
+                        errorCallback(errorObj);
                     }
-                }, function(evt) {
-                    // progress event handler, calls successCallback with empty ProgressEvent
-                    // We can't specify ProgressEvent data here since evt not provides any helpful information
-                    var progressEvent = new ProgressEvent('progress');
-                    successCallback(progressEvent, { keepCallback: true });
-                });
-            });
+                );
+            } catch (e) {
+                errorCallback(new FTErr(FTErr.INVALID_URL_ERR));
+            }
         }, function(err) {
             errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, server, server, null, null, err));
         });


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org