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