You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2014/10/25 03:26:35 UTC

[17/17] git commit: Add a /getfile endpoing to HarnessServer + Fixes for pipeFileToResponse.

Add a /getfile endpoing to HarnessServer + Fixes for pipeFileToResponse.


Project: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/commit/bc764cb5
Tree: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/tree/bc764cb5
Diff: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/diff/bc764cb5

Branch: refs/heads/master
Commit: bc764cb59a40390fdd610e3b778c1413946ea16a
Parents: c7bb0ef
Author: Andrew Grieve <ag...@chromium.org>
Authored: Fri Oct 3 13:00:17 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Fri Oct 24 21:26:07 2014 -0400

----------------------------------------------------------------------
 www/cdvah/js/HarnessServer.js   | 45 ++++++++++++++++++++++++++++++++-
 www/cdvah/js/ResourcesLoader.js | 48 ++++++++++++++++++++++++++++++++++--
 2 files changed, 90 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/bc764cb5/www/cdvah/js/HarnessServer.js
----------------------------------------------------------------------
diff --git a/www/cdvah/js/HarnessServer.js b/www/cdvah/js/HarnessServer.js
index fe87938..6085789 100644
--- a/www/cdvah/js/HarnessServer.js
+++ b/www/cdvah/js/HarnessServer.js
@@ -106,6 +106,32 @@
             return req.readChunk().then(handleChunk);
         }
 
+        function pipeFileToResponse(srcUrl, resp) {
+            // TODO: HttpServer needs to expose a "readyForWrite" event, and we need to use FileReader
+            // so that we can stream this.
+            // Might also be able to get the file as a Blob via an XHR,
+            // but that doesn't help us to send it to socket (needs an arraybuffer).
+            return ResourcesLoader.resolveFileAsBlob(srcUrl)
+            .then(function(blob) {
+                resp.headers['Content-Type'] = blob.type || 'application/octet-stream';
+                resp.headers['Content-Length'] = '' + blob.size;
+                var readFunc = ResourcesLoader.readBlobInChunks(blob);
+                return readFunc()
+                .then(function writeChunk(arrayBuffer) {
+                    // End of file.
+                    if (!arrayBuffer) {
+                        resp.close();
+                        return;
+                    }
+                    // TODO: Read next chunk while writing current chunk.
+                    return resp.writeChunk(arrayBuffer)
+                    .then(function() {
+                        return readFunc().then(writeChunk);
+                    });
+                });
+            });
+        }
+
         function handleExec(req, resp) {
             var js = req.getQueryParam('code');
             return AppHarnessUI.evalJs(js)
@@ -335,6 +361,22 @@
             });
         }
 
+        function handleGetFile(req, resp) {
+            var appId = req.getQueryParam('appId');
+            var path = req.getQueryParam('path');
+            // Strip beginning /, and any ../ (attempt at security)
+            path = path.replace(/^\/+/, '').replace(/\/\.+\//g, '/');
+
+            return AppsService.getAppById(appId)
+            .then(function(app) {
+                var filePath = app.directoryManager.rootURL + path;
+                return pipeFileToResponse(filePath, resp)
+                .then(null, function() {
+                    throw new HttpServer.ResponseException(404, 'File not found. Tried: ' + filePath);
+                });
+            });
+        }
+
         function handleInfo(req, resp) {
             var activeApp = AppsService.getActiveApp();
             var json = {
@@ -364,7 +406,8 @@
                 .addRoute('/deletefiles', ensureMethodDecorator('POST', handleDeleteFiles))
                 .addRoute('/putfile', ensureMethodDecorator('PUT', handlePutFile))
                 .addRoute('/zippush', ensureMethodDecorator('POST', handleZipPush))
-                .addRoute('/deleteapp', ensureMethodDecorator('POST', handleDeleteApp));
+                .addRoute('/deleteapp', ensureMethodDecorator('POST', handleDeleteApp))
+                .addRoute('/getfile', ensureMethodDecorator('GET', handleGetFile));
             return server.start();
         }
 

http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/bc764cb5/www/cdvah/js/ResourcesLoader.js
----------------------------------------------------------------------
diff --git a/www/cdvah/js/ResourcesLoader.js b/www/cdvah/js/ResourcesLoader.js
index b3e582a..f7c58e8 100644
--- a/www/cdvah/js/ResourcesLoader.js
+++ b/www/cdvah/js/ResourcesLoader.js
@@ -57,6 +57,12 @@
             return deferred.promise;
         }
 
+        function filePromisified(entry) {
+            var deferred = $q.defer();
+            entry.file(deferred.resolve, deferred.reject);
+            return deferred.promise;
+        }
+
         function dirName(path) {
             return path.replace(/\/[^\/]+\/?$/, '/');
         }
@@ -121,6 +127,25 @@
             });
         }
 
+        function createFileReaderGenerator(blob, chunkSize) {
+            var reader = new FileReader();
+            var curOffset = 0;
+            // Returns a promise for the next chunk.
+            return function() {
+                if (curOffset >= blob.size) {
+                    return $q.when(null);
+                }
+                var deferred = $q.defer();
+                reader.onloadend = function() {
+                    deferred.resolve(reader.result);
+                };
+                var curBlob = blob.slice(curOffset, curOffset + chunkSize);
+                curOffset += chunkSize;
+                reader.readAsArrayBuffer(curBlob);
+                return deferred.promise;
+            };
+        }
+
         var ResourcesLoader = {
             createTmpFileUrl: function(extension) {
                 return TEMP_DIR + Math.floor(Math.random()* 100000000) + (extension || '');
@@ -143,13 +168,32 @@
                 return ResourcesLoader.xhrGet(url);
             },
 
+            //returns a promise with the contents of the file
+            readBinaryFileContents: function(url) {
+                return ResourcesLoader.xhrGet(url, false, true);
+            },
+
+            resolveFileAsBlob: function(url) {
+                return resolveURL(url)
+                .then(function(fileEntry) {
+                    return filePromisified(fileEntry);
+                });
+            },
+
+            //returns a promise with a function that returns promises of array buffers.
+            readBlobInChunks: function(blob, chunkSize) {
+                chunkSize = chunkSize || 256 * 1024;
+                return createFileReaderGenerator(blob, chunkSize);
+            },
+
             //returns a promise with the json contents of the file
             readJSONFileContents: function(url) {
                 return ResourcesLoader.xhrGet(url, true);
             },
 
-            xhrGet: function(url, json) {
-                var opts = json ? null : {transformResponse: []};
+            xhrGet: function(url, json, binary) {
+                var opts = binary ? {responseType: 'arraybuffer'} :
+                           json ? null : {transformResponse: []};
                 return $http.get(url, opts)
                 .then(function(response, status) {
                     if (!response) {


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