Index: Dev/trunk/src/.jshintrc
===================================================================
--- Dev/trunk/src/.jshintrc	(revision 463)
+++ Dev/trunk/src/.jshintrc	(revision 464)
@@ -11,4 +11,5 @@
     "unused": false,
     "strict": false,
+    "laxcomma": true,
 
     "loopfunc": true,
Index: Dev/trunk/src/client/qed-client/store/request.js
===================================================================
--- Dev/trunk/src/client/qed-client/store/request.js	(revision 463)
+++ Dev/trunk/src/client/qed-client/store/request.js	(revision 464)
@@ -10,7 +10,14 @@
         var dfd = new Deferred();
         if ( authenticated ) {
-            request(url,options).response.then(function(response){
-                console.log(response);
-            }, function(error){
+            var req = request(url,options);
+
+            // forward successfull response
+            req.then(function(data){
+                dfd.resolve(data);
+            });
+            
+            req.response.then(function(response){
+                // if we are recovering, launch other requests
+            }, function(error) {
                 if ( error.response.status === 401 ) {
                     queue.push({
Index: Dev/trunk/src/package.json
===================================================================
--- Dev/trunk/src/package.json	(revision 463)
+++ Dev/trunk/src/package.json	(revision 464)
@@ -4,9 +4,10 @@
   "description": "QED Server",
   "dependencies": {
-    "simple-http-proxy": "~0.5.2",
     "express": "~3.2.3",
     "underscore": "~1.4.4",
     "passport": "~0.1.17",
-    "passport-local": "~0.1.6"
+    "passport-local": "~0.1.6",
+    "q": "~0.9.6",
+    "q-io": "~1.9.1"
   },
   "engines": {
Index: Dev/trunk/src/server/app.js
===================================================================
--- Dev/trunk/src/server/app.js	(revision 463)
+++ Dev/trunk/src/server/app.js	(revision 464)
@@ -4,5 +4,5 @@
 var fs = require("fs");
 var path = require("path");
-var proxy = require("simple-http-proxy");
+var proxy = require("./simple-http-proxy");
 var _ = require("underscore");
 
@@ -58,8 +58,8 @@
     // url to login (might work on others as well?)
     // you should then have a session to work with
-    app.post('/api/login', passport.authenticate('local'));
+    app.post('/api/login');
 
     // forward to couch
-    app.use('/data/couch', passport.authenticate('local'), proxy(settings.couchDbURL));
+    app.use('/data/couch', proxy(settings.couchDbURL));
 
     return app;
Index: Dev/trunk/src/server/config/config-couchdb.js
===================================================================
--- Dev/trunk/src/server/config/config-couchdb.js	(revision 463)
+++ Dev/trunk/src/server/config/config-couchdb.js	(revision 464)
@@ -1,104 +1,121 @@
 var q = require('q');
-var http = require('q-io/http');
-var fs = require('q-io/fs');
+var HTTP = require('q-io/http');
+var URL = require('url');
 var _ = require('underscore');
+var util = require('util');
 
-var dbURL = "http://localhost:5984/";
 var designDocs = require('./couchdb-design-docs');
 
-function stringifyFunctions(value) {
-    if ( value === null ) {
-        return null;
-    } else if ( _.isArray(value) ) {
-        return value;
-    } else if ( _.isFunction(value) ) {
-        return value.toString();
-    } else if ( _.isObject(value) ) {
-        value = _.clone(value);
-        _.each(value, function(propValue, propName){
-            value[propName] = stringifyFunctions(propValue);
+module.exports = function(couchDbURL) {
+
+    function stringifyFunctions(value) {
+        if ( value === null ) {
+            return null;
+        } else if ( _.isArray(value) ) {
+            return value;
+        } else if ( _.isFunction(value) ) {
+            return value.toString();
+        } else if ( _.isObject(value) ) {
+            value = _.clone(value);
+            _.each(value, function(propValue, propName){
+                value[propName] = stringifyFunctions(propValue);
+            });
+            return value;
+        } else {
+            return value;
+        }
+    }
+
+    function request(method,path,content) {
+        var url = couchDbURL+path;
+        var parsedURL = URL.parse(url);
+        var options = {
+            url: url,
+            method: method,
+            headers: {
+                'content-type': 'application/json; charset=utf-8',
+                'accept': 'application/json'
+            },
+            body: {
+                forEach: function(callback) {
+                    callback(JSON.stringify(content || {}));
+                }
+            }
+        };
+        // because q-io doesn't support auth properly, we have to
+        // build the f*ing wheel again.
+        if ( parsedURL.auth ) {
+            var auth = new Buffer(parsedURL.auth).toString("base64");
+            options.headers.authorization = 'Basic '+auth;
+        }
+        return HTTP.request(options)
+        .then(function(res){
+            return res.body.read().then(function(content){
+                return JSON.parse(content.toString() || "{}");
+            });
+        },function(res){
+            return res.body.read().then(function(error){
+                console.warn(error); // q.all doesn't do errors, so let's show them here
+                return JSON.parse(error.toString() || "{}");
+            });
         });
-        return value;
-    } else {
-        return value;
     }
-}
 
-function request(method,path,content) {
-    var url = dbURL+path;
-    return http.request({
-        url: url,
-        method: method,
-        headers: {
-            'content-type': 'application/json; charset=utf-8',
-            'accept': 'application/json'
-        },
-        body: {
-            forEach: function(callback) {
-                callback(JSON.stringify(content || {}));
-            }
+    console.log("Configuring CouchDB for QED");
+    console.log("Checking CouchDB version");
+    return request('GET','')
+    .then(function(res){
+        if (res.version !== "1.2.0" ) {
+            console.log("Found "+res.version+", only tested with CouchDB 1.2.0");
+        } else {
+            console.log("CouchDB 1.2.0 found");
         }
     }).then(function(res){
-        return res.body.read().then(function(content){
-            return JSON.parse(content);
+        console.log("Checking database 'qed'");
+        return request('GET','qed')
+        .then(function(res){
+            console.log("Database 'qed' found.");
+        },function(err){
+            console.log("Creating database 'qed'");
+            return request('PUT','qed');
         });
-    },function(res){
-        return res.body.read().then(function(error){
-            return JSON.parse(error);
-        });
+    }).then(function(){
+        console.log("Putting documents in database.");
+        designDocs = stringifyFunctions(designDocs);
+        return q.all(_.map(designDocs, function(doc,docUrl){
+            var configAction = doc.__configAction;
+            delete doc.__configAction;
+            switch (configAction) {
+                case "ignore":
+                    console.log(docUrl+" ignored.");
+                break;
+                case "update":
+                    console.log(docUrl+" updating.");
+                    return request('GET',docUrl)
+                    .then(function(oldDoc){
+                        _.extend(oldDoc,doc);
+                        return request('PUT',docUrl,oldDoc);
+                    },function(){
+                        return request('PUT',docUrl,doc);
+                    });
+                break;
+                case "replace":
+                default:
+                    console.log(docUrl+" replacing.");
+                    return request('GET',docUrl)
+                    .then(function(oldDoc){
+                        _.extend(doc,_.pick(oldDoc,'_id','_rev'));
+                        return request('PUT',docUrl,doc);
+                    },function(){
+                        return request('PUT',docUrl,doc);
+                    });
+                break;
+            }
+        }));
+    }).then(function(){
+        console.log("Done!");
+    },function(err){
+        console.error("ERROR",err,err.stack);
     });
-}
 
-console.log("Configuring CouchDB for QED");
-console.log("Checking CouchDB version");
-request('GET','')
-.then(function(res){
-    if (res.version !== "1.2.0" ) {
-        console.log("Found "+res.version+", only tested with CouchDB 1.2.0");
-    } else {
-        console.log("CouchDB 1.2.0 found");
-    }
-    console.log("Checking database 'qed'");
-}).then(function(res){
-    return request('GET','qed')
-    .then(function(res){
-        console.log("Database 'qed' found.");
-    },function(err){
-        console.log("Creating database 'qed'");
-        return request('PUT','qed');
-    });
-}).then(function(){
-    console.log("Putting documents in database.");
-    designDocs = stringifyFunctions(designDocs);
-    return q.all(_.map(designDocs, function(doc,docUrl){
-        var configAction = doc.__configAction;
-        delete doc.__configAction;
-        switch (configAction) {
-            case "ignore":
-                console.log(docUrl+" ignored.");
-            case "update":
-                console.log(docUrl+" updating.");
-                return request('GET',docUrl)
-                .then(function(oldDoc){
-                    _.extend(oldDoc,doc);
-                    return request('PUT',docUrl,oldDoc);
-                },function(){
-                    return request('PUT',docUrl,doc);
-                });
-            case "replace":
-            default:
-                console.log(docUrl+" replacing.");
-                return request('GET',docUrl)
-                .then(function(oldDoc){
-                    _.extend(doc,_.pick(oldDoc,'_id','_rev'));
-                    return request('PUT',docUrl,doc);
-                },function(){
-                    return request('PUT',docUrl,doc);
-                });
-        }
-    }));
-}).then(function(){
-    console.log("Done!");
-},function(err){
-    console.error("ERROR",err);
-});
+};
Index: Dev/trunk/src/server/config/couchdb-design-docs.js
===================================================================
--- Dev/trunk/src/server/config/couchdb-design-docs.js	(revision 463)
+++ Dev/trunk/src/server/config/couchdb-design-docs.js	(revision 464)
@@ -1,3 +1,4 @@
 module.exports = {
+
     "_users/qed_admin": {
         __configAction: "ignore",
@@ -8,4 +9,5 @@
         type: "user"
     },
+
     "qed/_security": {
         __configAction: "ignore",
@@ -19,4 +21,5 @@
         }
     },
+
     "qed/_design/default": {
         __configAction: "replace",
@@ -34,4 +37,5 @@
         }
     },
+
     "qed/_design/questions": {
         __configAction: "replace",
@@ -81,4 +85,5 @@
         }
     },
+
     "qed/_design/surveys": {
         __configAction: "replace",
@@ -100,4 +105,5 @@
         }
     },
+
     "qed/_design/responses": {
         __configAction: "replace",
@@ -113,3 +119,4 @@
         }
     }
+
 };
Index: Dev/trunk/src/server/heroku.js
===================================================================
--- Dev/trunk/src/server/heroku.js	(revision 463)
+++ Dev/trunk/src/server/heroku.js	(revision 464)
@@ -1,8 +1,15 @@
-var app = require('./app').App({
-    couchDbURL: 'http://localhost:5984/qed'
+var port = process.env.PORT || 5000;
+var couchDbURL = (process.env.CLOUDANT_URL || 'http://localhost:5984')+'/';
+
+var configCouch = require('./config/config-couchdb');
+
+configCouch(couchDbURL)
+.then(function(){
+    var app = require('./app').App({
+        couchDbURL: couchDbURL+'qed'
+    });
+
+    app.listen(port, function() {
+        console.log('Listening on port',port);
+    });
 });
-
-var port = process.env.PORT || 5000;
-app.listen(port, function() {
-    console.log('Listening on port',port);
-});
Index: Dev/trunk/src/server/simple-http-proxy.js
===================================================================
--- Dev/trunk/src/server/simple-http-proxy.js	(revision 464)
+++ Dev/trunk/src/server/simple-http-proxy.js	(revision 464)
@@ -0,0 +1,106 @@
+
+/**
+ * Module dependencies
+ */
+var url = require('url')
+    , join = require('path').join
+    , protocols = {
+        http: require('http'),
+        https: require('https')
+    };
+
+module.exports = function(endpoint, opts) {
+    opts = opts || {};
+
+    var parsedUrl = url.parse(endpoint);
+
+    return function simpleHttpProxy(req, res, next) {
+        // Get our forwarding info
+        var hostInfo = req.headers.host.split(":");
+
+        // Remove the host header
+        delete req.headers.host;
+
+        // Optionally delete cookie
+        if (opts.cookies === false) {
+            delete req.headers.cookie;
+        }
+
+        // Should we keep the trailing slash?
+        var trailingSlash = req.originalUrl[req.originalUrl.length-1] === "/";
+
+        // Setup the options
+        var options = {
+            hostname: parsedUrl.hostname,
+            auth: parsedUrl.auth,
+            port: parsedUrl.port,
+            headers: req.headers,
+            path: join(parsedUrl.pathname, trailingSlash ? req.url : req.url.substring(1)),
+            method: req.method
+        };
+
+        // Enable forwarding headers
+        if(opts.xforward) {
+            // Get the path at which the middleware is mounted
+            var resPath = req.originalUrl.replace(req.url, "");
+
+            // We'll need to add a / if it's not on there
+            if (resPath.indexOf("/") !== 0) {
+                resPath = join("/", resPath);
+            }
+
+            // Pass along our headers
+            options.headers[opts.xforward.proto || "x-forwarded-proto"] = req.connection.encrypted ? "https" : "http";
+            options.headers[opts.xforward.host || "x-forwarded-host"] = hostInfo[0];
+            options.headers[opts.xforward.path || "x-forwarded-path"] = resPath;
+
+            if (hostInfo[1]) {
+                options.headers[opts.xforward.port || "x-forwarded-port"] = hostInfo[1];
+            }
+        }
+
+        /**
+         * Hack for nginx backends where node, by default, sends no 'content-length'
+         * header if no data is sent with the request and sets the 'transfer-encoding'
+         * to 'chunked'. Nginx will then send a 411 because the body contains a '0'
+         * which is the length of the chunk
+         *
+         *     GET /proxy
+         *     transfer-encoding: chunked
+         *     
+         *     0
+         *
+         */
+        if( ["POST", "DELETE"].indexOf(req.method) !== -1 && options.headers['transfer-encoding'] !== 'chunked') {
+            options.headers['content-length'] = options.headers['content-length'] || '0';
+        }
+
+        // Make the request with the correct protocol
+        var request = protocols[(parsedUrl.protocol || 'http').replace(":", "")].request(options, function(response) {
+
+            // Send down the statusCode and headers
+            res.writeHead(response.statusCode, response.headers);
+
+            // Pipe the response
+            response.pipe(res);
+        });
+
+        // Handle any timeouts that occur
+        request.setTimeout(opts.timeout || 10000, function() {
+            // Clean up the socket
+            // TODO is there a better way to do this? There's a 'socket hang up' error being emitted...
+            request.setSocketKeepAlive(false);
+            request.socket.destroy();
+
+            // Pass down the error
+            var err = new Error("Proxy to '"+endpoint+"' timed out");
+            request.emit("error", err);
+        });
+
+        // Pipe the client request upstream
+        req.pipe(request);
+
+        // Pass on our errors
+        request.on('error', next);
+    };
+};
Index: Dev/trunk/src/server/standalone.js
===================================================================
--- Dev/trunk/src/server/standalone.js	(revision 463)
+++ Dev/trunk/src/server/standalone.js	(revision 464)
@@ -2,5 +2,4 @@
 var https = require("https");
 var os = require("os");
-var path = require("path");
 var _ = require("underscore");
 
@@ -10,6 +9,6 @@
 
 var httpsOptions = {
-    key: fs.readFileSync(path.resolve('../qed-server.key')),
-    cert: fs.readFileSync(path.resolve('../qed-server.pem'))
+    key: fs.readFileSync(__dirname+'/../qed-server.key'),
+    cert: fs.readFileSync(__dirname+'/../qed-server.pem')
 };
 
