You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2013/09/13 01:35:53 UTC

[12/16] git commit: [CB-4797] Change `serve` command to serve platforms keyed off of path component.

[CB-4797] Change `serve` command to serve platforms keyed off of path component.

E.g. /ios/www will have iOS's www


Project: http://git-wip-us.apache.org/repos/asf/cordova-cli/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-cli/commit/887ee125
Tree: http://git-wip-us.apache.org/repos/asf/cordova-cli/tree/887ee125
Diff: http://git-wip-us.apache.org/repos/asf/cordova-cli/diff/887ee125

Branch: refs/heads/ffos
Commit: 887ee1256b3787b15603bbf83f66728e2f3203a8
Parents: aba4599
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Sep 12 11:20:28 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Thu Sep 12 11:20:28 2013 -0400

----------------------------------------------------------------------
 package.json | 159 +++++++++++++++++++++++++++++++++++++---------------
 src/serve.js | 165 ++++++++++++++++++++++++++----------------------------
 2 files changed, 193 insertions(+), 131 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/887ee125/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index d2f9ebc..40e6af5 100644
--- a/package.json
+++ b/package.json
@@ -4,10 +4,10 @@
   "preferGlobal": "true",
   "description": "Cordova command line interface tool",
   "main": "cordova",
-  "engines":{
-      "node":">=0.9.9"
+  "engines": {
+    "node": ">=0.9.9"
   },
-  "engineStrict":true,
+  "engineStrict": true,
   "bin": {
     "cordova": "./bin/cordova"
   },
@@ -18,9 +18,9 @@
     "type": "git",
     "url": "https://git-wip-us.apache.org/repos/asf/cordova-cli.git"
   },
-  "bugs":{
-    "url" : "https://issues.apache.org/jira/browse/CB",
-    "email" : "dev@cordova.apache.org"
+  "bugs": {
+    "url": "https://issues.apache.org/jira/browse/CB",
+    "email": "dev@cordova.apache.org"
   },
   "keywords": [
     "cordova",
@@ -28,52 +28,119 @@
     "cli"
   ],
   "dependencies": {
-    "colors":">=0.6.0",
-    "elementtree":"0.1.3",
-    "plugman":"0.11.x",
-    "plist":"0.4.x",
-    "xcode":"0.5.1",
-    "express":"3.0.0",
-    "shelljs":"0.1.2",
-    "ncallbacks":"1.0.0",
-    "request":"2.22.0",
-    "ripple-emulator":"0.9.18",
-    "semver":"1.1.0",
-    "glob":"3.2.x",
-    "follow-redirects":"0.0.x",
-    "prompt":"0.2.7",
-    "tar":"0.1.x",
+    "colors": ">=0.6.0",
+    "elementtree": "0.1.3",
+    "plugman": "0.11.x",
+    "plist": "0.4.x",
+    "xcode": "0.5.1",
+    "express": "3.0.0",
+    "shelljs": "0.1.2",
+    "ncallbacks": "1.0.0",
+    "request": "2.22.0",
+    "ripple-emulator": "0.9.18",
+    "semver": "1.1.0",
+    "glob": "3.2.x",
+    "follow-redirects": "0.0.x",
+    "prompt": "0.2.7",
+    "tar": "0.1.x",
     "open": "0.0.3",
-    "npm":"1.3.x",
-    "optimist":"0.6.0"
+    "npm": "1.3.x",
+    "optimist": "0.6.0",
+    "mime": "~1.2.11"
   },
   "devDependencies": {
-    "jasmine-node":"1.8.x"
+    "jasmine-node": "1.8.x"
   },
   "author": "Anis Kadri",
   "contributors": [
-    {"name": "Brian LeRoux","email": "b@brian.io"},
-    {"name": "Fil Maj", "email": "maj.fil@gmail.com"},
-    {"name": "Mike Reinstein", "email":"reinstein.mike@gmail.com"},
-    {"name": "Darry Pogue", "email":"darryl@dpogue.ca"},
-    {"name": "Michael Brooks", "email":"michael@michaelbrooks.ca"},
-    {"name": "Braden Shepherdson", "email":"braden@chromium.org"},
-    {"name": "Gord Tanner", "email":"gtanner@gmail.com"},
-    {"name": "Tim Kim", "email": "timk@adobe.com"},
-    {"name": "Benn Mapes", "email": "Benn.Mapes@gmail.com"},
-    {"name": "Michael Wolf", "email": "Michael.Wolf@Cynergy.com"},
-    {"name": "Andrew Grieve", "email": "agrieve@chromium.org"},
-    {"name": "Bryan Higgins", "email": "bhiggins@blackberry.com"},
-    {"name": "Don Coleman", "email": "dcoleman@chariotsolutions.com"},
-    {"name": "Germano Gabbianelli", "email": "tyron.mx@gmail.com"},
-    {"name": "Ian Clelland", "email": "iclelland@chromium.org"},
-    {"name": "Lucas Holmqust", "email": "lholmqui@redhat.com"},
-    {"name": "Matt LeGrand", "email": "mlegrand@gmail.com"},
-    {"name": "Michal Mocny", "email": "mmocny@gmail.com"},
-    {"name": "Sam Breed", "email": "sam@quickleft.com"},
-    {"name": "Tommy-Carlos Williams", "email": "tommy@devgeeks.org"},
-    {"name": "Rubén Norte", "email": "rubennorte@gmail.com"},
-    {"name": "Germano Gabbianelli", "email": "tyrion.mx@gmail.com"}
+    {
+      "name": "Brian LeRoux",
+      "email": "b@brian.io"
+    },
+    {
+      "name": "Fil Maj",
+      "email": "maj.fil@gmail.com"
+    },
+    {
+      "name": "Mike Reinstein",
+      "email": "reinstein.mike@gmail.com"
+    },
+    {
+      "name": "Darry Pogue",
+      "email": "darryl@dpogue.ca"
+    },
+    {
+      "name": "Michael Brooks",
+      "email": "michael@michaelbrooks.ca"
+    },
+    {
+      "name": "Braden Shepherdson",
+      "email": "braden@chromium.org"
+    },
+    {
+      "name": "Gord Tanner",
+      "email": "gtanner@gmail.com"
+    },
+    {
+      "name": "Tim Kim",
+      "email": "timk@adobe.com"
+    },
+    {
+      "name": "Benn Mapes",
+      "email": "Benn.Mapes@gmail.com"
+    },
+    {
+      "name": "Michael Wolf",
+      "email": "Michael.Wolf@Cynergy.com"
+    },
+    {
+      "name": "Andrew Grieve",
+      "email": "agrieve@chromium.org"
+    },
+    {
+      "name": "Bryan Higgins",
+      "email": "bhiggins@blackberry.com"
+    },
+    {
+      "name": "Don Coleman",
+      "email": "dcoleman@chariotsolutions.com"
+    },
+    {
+      "name": "Germano Gabbianelli",
+      "email": "tyron.mx@gmail.com"
+    },
+    {
+      "name": "Ian Clelland",
+      "email": "iclelland@chromium.org"
+    },
+    {
+      "name": "Lucas Holmqust",
+      "email": "lholmqui@redhat.com"
+    },
+    {
+      "name": "Matt LeGrand",
+      "email": "mlegrand@gmail.com"
+    },
+    {
+      "name": "Michal Mocny",
+      "email": "mmocny@gmail.com"
+    },
+    {
+      "name": "Sam Breed",
+      "email": "sam@quickleft.com"
+    },
+    {
+      "name": "Tommy-Carlos Williams",
+      "email": "tommy@devgeeks.org"
+    },
+    {
+      "name": "Rubén Norte",
+      "email": "rubennorte@gmail.com"
+    },
+    {
+      "name": "Germano Gabbianelli",
+      "email": "tyrion.mx@gmail.com"
+    }
   ],
   "license": "Apache version 2.0"
 }

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/887ee125/src/serve.js
----------------------------------------------------------------------
diff --git a/src/serve.js b/src/serve.js
index 7a2b1d4..e262e12 100644
--- a/src/serve.js
+++ b/src/serve.js
@@ -24,109 +24,104 @@ var cordova_util = require('./util'),
     fs = require('fs'),
     util = require('util'),
     http = require("http"),
-    url = require("url");
-
-function launch_server(www, platform_www, config_xml_path, port) {
-    port = port || 8000;
-
-    // Searches these directories in order looking for the requested file.
-    var searchPath = [platform_www];
+    url = require("url"),
+    mime = require("mime"),
+    zlib = require("zlib");
 
+function launchServer(projectRoot, port) {
     var server = http.createServer(function(request, response) {
-        var uri = url.parse(request.url).pathname;
+        var urlPath = url.parse(request.url).pathname;
+        var firstSegment = /\/(.*?)\//.exec(urlPath);
+        if (!firstSegment) {
+            response.writeHead(404, {"Content-Type": "text/plain"});
+            response.write("404 Not Found\nPlease use URLs in the form /$platformId/www/...");
+            response.end();
+            return;
+        }
+        var platformId = firstSegment[1];
+        // Strip the platform out of the path.
+        urlPath = urlPath.slice(platformId.length + 1);
+
+        var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
+        var filePath = null;
+
+        if (urlPath == '/config.xml') {
+            filePath = parser.config_xml();
+        } else if (urlPath == '/project.json') {
+            processAddRequest(request, response, platformId, projectRoot);
+            return;
+        } else if (/^\/www\//.test(urlPath)) {
+            filePath = path.join(parser.www_dir(), urlPath.slice(5));
+        } else {
+            response.writeHead(404, {"Content-Type": "text/plain"});
+            response.write("404 Not Found\n");
+            response.end();
+        }
 
-        function checkPath(pathIndex) {
-            if (searchPath.length <= pathIndex) {
+        fs.exists(filePath, function(exists) {
+            if (exists) {
+                if (fs.statSync(filePath).isDirectory()) {
+                    response.writeHead(200, {"Content-Type": "text/plain"});
+                    response.write("TODO: show a directory listing.\n");
+                    response.end();
+                } else {
+                    var mimeType = mime.lookup(filePath);
+                    var respHeaders = {
+                      'Content-Type': mimeType
+                    };
+                    var readStream = fs.createReadStream(filePath);
+
+                    var acceptEncoding = request.headers['accept-encoding'] || '';
+                    if (acceptEncoding.match(/\bdeflate\b/)) {
+                        respHeaders['content-encoding'] = 'deflate';
+                        readStream = readStream.pipe(zlib.createDeflate());
+                    } else if (acceptEncoding.match(/\bgzip\b/)) {
+                        respHeaders['content-encoding'] = 'gzip';
+                        readStream = readStream.pipe(zlib.createGzip());
+                    }
+                    response.writeHead(200, respHeaders);
+                    readStream.pipe(response);
+                }
+            } else {
                 response.writeHead(404, {"Content-Type": "text/plain"});
                 response.write("404 Not Found\n");
                 response.end();
-                return;
-            }
-
-            var filename = path.join(searchPath[pathIndex], uri);
-            if(uri === "/config.xml"){
-                filename = config_xml_path;
             }
+        });
 
-            fs.exists(filename, function(exists) {
-                if(!exists) {
-                    checkPath(pathIndex+1);
-                    return;
-                }
-
-                if (fs.statSync(filename).isDirectory()) filename += path.sep + 'index.html';
-
-                fs.readFile(filename, "binary", function(err, file) {
-                    if(err) {
-                        response.writeHead(500, {"Content-Type": "text/plain"});
-                        response.write(err + "\n");
-                        response.end();
-                        return;
-                    }
-
-                    response.writeHead(200);
-                    response.write(file, "binary");
-                    response.end();
-                });
-            });
-        }
-        checkPath(0);
-    }).listen(parseInt(''+port, 10));
+    }).listen(port);
 
-    console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");
+    console.log("Static file server running at\n  => http://0.0.0.0:" + port + "/\nCTRL + C to shutdown");
     return server;
 }
 
-module.exports = function serve (platform, port) {
-    var returnValue = {};
-
-    module.exports.config(platform, port, function (config) {
-        returnValue.server = launch_server(config.paths[0], config.paths[1], config.config_xml_path, port);
+function processAddRequest(request, response, platformId, projectRoot) {
+    var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
+    var wwwDir = parser.www_dir();
+    var payload = {
+        'configPath': '/' + platformId + '/config.xml',
+        'wwwPath': '/' + platformId + '/www',
+        'wwwFileList': shell.find(wwwDir)
+            .filter(function(a) { return !fs.statSync(a).isDirectory(); })
+            .map(function(a) { return a.slice(wwwDir.length); })
+    };
+    response.writeHead(200, {
+        'Content-Type': 'application/json',
+        'Cache-Control': 'no-cache'
     });
+    response.write(JSON.stringify(payload));
+    response.end();
+}
 
-    // Hack for testing despite its async nature.
-    return returnValue;
-};
-
-module.exports.config = function (platform, port, callback) {
+module.exports = function server(port) {
     var projectRoot = cordova_util.isCordova(process.cwd());
+    port = +port || 8000;
 
     if (!projectRoot) {
         throw new Error('Current working directory is not a Cordova-based project.');
     }
 
-    var xml = cordova_util.projectConfig(projectRoot);
-    var cfg = new config_parser(xml);
-
-    // Retrieve the platforms.
-    var platformList = cordova_util.listPlatforms(projectRoot);
-    if (!platform) {
-        throw new Error('You need to specify a platform.');
-    } else if (platformList.length == 0) {
-        throw new Error('No platforms to serve.');
-    } else if (platformList.filter(function(x) { return x == platform }).length == 0) {
-        throw new Error(platform + ' is not an installed platform.');
-    }
-
-    // If we got to this point, the given platform is valid.
-
-    var result = {
-        paths: [],
-        // Config file path
-        config_xml_path : "",
-        // Default port is 8000 if not given. This is also the default of the Python module.
-        port: port || 8000
-    };
-
-    // Top-level www directory.
-    result.paths.push(cordova_util.projectWww(projectRoot));
-
-    var parser = new platforms[platform].parser(path.join(projectRoot, 'platforms', platform));
+    // Return for testing.
+    return launchServer(projectRoot, port);
+};
 
-    // Update the related platform project from the config
-    parser.update_project(cfg, function() {
-        result.paths.push(parser.www_dir());
-        result.config_xml_path = parser.config_xml();
-        callback(result);
-    });
-}