1 var fs = require('fs');
  2 var nowUtil = require('./nowUtil').nowUtil;
  3 
  4 var fileCache = {};
  5 var nowFileCache = {};
  6 
  7 var defaultListeners;
  8 var server;
  9 var options;
 10 
 11 var handleResponse, serveFile, generateClientLibs;
 12 
 13 exports.wrapServer = function (httpServer, serverOptions) {
 14   server = httpServer;
 15   options = serverOptions || {client: {}};
 16   options.client = JSON.stringify(options.client);
 17 
 18   defaultListeners = server.listeners('request');
 19   if (serverOptions.autoHost) {
 20     server.removeAllListeners('request');
 21     server.on('request', handleResponse);
 22   }
 23 };
 24 
 25 // Called upon http server request
 26 handleResponse = function (request, response) {
 27   // Handle only GET requests for /nowjs/* files. Pass all other requests through
 28   var i;
 29   if (request.method === 'GET') {
 30 
 31     // Detect if request involves the now.js file
 32     if (request.url.split('?')[0] === '/nowjs/now.js') {
 33       serveFile(__dirname + '/client/now.js', request, response, options);
 34     } else {
 35       // Make sure default listeners are still handled
 36       for (i in defaultListeners) {
 37         if (nowUtil.hasProperty(defaultListeners, i)) {
 38           defaultListeners[i].call(server, request, response);
 39         }
 40       }
 41     }
 42   } else {
 43     for (i in defaultListeners) {
 44       // Make sure default listeners are still handled
 45       if (nowUtil.hasProperty(defaultListeners, i)) {
 46         defaultListeners[i].call(server, request, response);
 47       }
 48     }
 49   }
 50 };
 51 
 52 // Actually serve the file
 53 serveFile = function (filename, request, response, options) {
 54   // Write file from cache if possible
 55   if (nowUtil.hasProperty(fileCache, filename)) {
 56     response.writeHead(200);
 57     response.write(fileCache[filename]);
 58     response.end();
 59   } else {
 60     if (filename.indexOf('/now.js') !== -1) {
 61 
 62       // Write file from cache if possible
 63       if (nowUtil.hasProperty(nowFileCache, request.headers.host)) {
 64 
 65         // Write file from cache
 66         response.writeHead(200, {'Content-Type': 'text/javascript'});
 67         response.write(nowFileCache[request.headers.host].now);
 68         response.end();
 69       } else {
 70         // Determine hostname / port if not given in options
 71         var host = request.headers.host.split(':');
 72         var hostServer = options['host'] || host[0];
 73         var hostPort =  options['port'] || host[1] || '80';
 74 
 75         // Call generate client libs, which takes the desired host/port and executes callback with two parts of now.js as parameters
 76         generateClientLibs(hostServer, hostPort, function (nowText) {
 77 
 78           // Write to client
 79           response.writeHead(200, {'Content-Type': 'text/javascript'});
 80           response.write(nowText);
 81           response.end();
 82 
 83           // Add to cache
 84           nowFileCache[request.headers.host] = {now: nowText};
 85         });
 86       }
 87     } else {
 88       // For any other filename, read file and server (not cached)
 89       fs.readFile(filename, function (err, data) {
 90         var text = data.toString();
 91         response.writeHead(200);
 92         response.write(text);
 93         response.end();
 94         fileCache[filename] = text;
 95       });
 96     }
 97   }
 98 };
 99 
100 // Takes host and port and call callback with now.js as parameter
101 generateClientLibs = function (hostServer, hostPort, callback) {
102   fs.readFile(__dirname + '/client/now.js', function (err, data) {
103     var nowText = data.toString();
104     var initString = options.scope + '.now = nowInitialize("' +
105           (options.protocol !==  undefined ? options.protocol + ':' : '') +
106           '//' + hostServer + ':' + hostPort + '", ' + options.client + ');\n';
107     nowText += initString;
108 
109     callback(nowText);
110   });
111 };
112 
113 exports.generateClientLibs = generateClientLibs;
114