Permalink
Browse files

factored debugger side and web side into seperate modules

  • Loading branch information...
1 parent 43888d7 commit 6043ef51417234891821087cf786ca43b46cb3f0 @dannycoates dannycoates committed Jul 23, 2010
Showing with 229 additions and 173 deletions.
  1. +96 −0 bin/debugger.js
  2. +15 −173 bin/inspector.js
  3. +118 −0 bin/session.js
View
96 bin/debugger.js
@@ -0,0 +1,96 @@
+var net = require('net'),
+ events = require('events'),
+ sys = require('sys');
+
+function makeMessage() {
+ return {
+ headersDone: false,
+ headers: null,
+ contentLength: 0
+ };
+}
+
+///////////////////////////////////////////////////////////
+// exports
+
+exports.attachDebugger = function(port) {
+ var connected = false;
+ var buffer = '';
+ var msg = false;
+ var conn = net.createConnection(port);
+ conn.setEncoding('ascii');
+
+ function parse() {
+ if (msg && msg.headersDone) {
+ //parse body
+ if (buffer.length >= msg.contentLength) {
+ msg.body = buffer.slice(0, msg.contentLength);
+ buffer = buffer.slice(msg.contentLength);
+ if (msg.body.length > 0) {
+ var obj = JSON.parse(msg.body);
+ debugr.emit('data', obj);
+ }
+ msg = false;
+ parse();
+ }
+ return;
+ }
+ if (!msg) msg = makeMessage();
+
+ var offset = buffer.indexOf('\r\n\r\n');
+ if (offset > 0) {
+ msg.headersDone = true;
+ msg.headers = buffer.substr(0, offset+4);
+ var m = /Content-Length: (\d+)/.exec(msg.headers);
+ if (m[1]) {
+ msg.contentLength = parseInt(m[1], 10);
+ }
+ else {
+ sys.debug('no Content-Length');
+ }
+ buffer = buffer.slice(offset+4);
+ parse();
+ }
+ }
+
+ var debugr = Object.create(events.EventEmitter.prototype, {
+ request: {
+ value: function(data)
+ {
+ if (connected) {
+ var message = 'Content-Length: ' + data.length + '\r\n\r\n' + data;
+ conn.write(message);
+ }
+ }},
+ close: {
+ value: function()
+ {
+ conn.end();
+ }}
+ });
+
+ debugr.__defineGetter__('connected', function() { return connected; });
+
+ conn.on('connect', function() {
+ connected = true;
+ debugr.emit('connect');
+ });
+
+ conn.on('data', function(data) {
+ buffer += data;
+ parse();
+ });
+
+ conn.on('end', function() {
+ debugr.close();
+ });
+
+ conn.on('close', function() {
+ connected = false;
+ debugr.emit('close');
+ });
+
+ return debugr;
+};
+
+
View
188 bin/inspector.js
@@ -1,161 +1,35 @@
#!/usr/bin/env node
-var net = require('net'),
- http = require('http'),
- sys = require('sys'),
- path = require('path'),
- ws = require('../lib/ws'),
- paperboy = require('../lib/paperboy'),
- spawn = require('child_process').spawn;
+var sys = require('sys'),
+ session = require('./session');
-//////////////////////////////////////////////////////////
-// Node side
-
-var seq = 0;
-var buffer = '';
-var current = false;
-
-function request(data) {
- var message = 'Content-Length: ' + data.length + '\r\n\r\n' + data;
- debug.write(message);
-}
-
-function makeMessage() {
- return {
- headersDone: false,
- headers: null,
- contentLength: 0,
- body: ''
- };
-}
-
-function parseBody() {
- if (buffer.length >= current.contentLength) {
- current.body = buffer.slice(0, current.contentLength);
- buffer = buffer.slice(current.contentLength);
- if (current.body.length > 0 && wsServer) {
- if (wsServer.manager.length === 0) {
- var msg = JSON.parse(current.body);
- if (msg.type === 'event' && msg.event === 'break') {
- request('{"seq":0,"type":"request","command":"continue"}');
- }
- }
- else {
- wsServer.broadcast(current.body);
- }
- }
- current = false;
- parse();
- }
-}
-
-function parse() {
- if (current && current.headersDone) {
- parseBody();
- return;
- }
-
- if (!current) current = makeMessage();
-
- var offset = buffer.indexOf('\r\n\r\n');
- if (offset > 0) {
- current.headersDone = true;
- current.headers = buffer.substr(0, offset+4);
- var m = /Content-Length: (\d+)/.exec(current.headers);
- if (m[1]) {
- current.contentLength = parseInt(m[1], 10);
- }
- else {
- sys.debug('no Content-Length');
- }
- buffer = buffer.slice(offset+4);
- parse();
- }
-}
-
-function attachDebugger() {
- var conn = conn = net.createConnection(debugPort);
- conn.setEncoding('ascii');
-
- conn.on('data', function(data) {
- buffer += data;
- parse();
- });
-
- conn.on('end', function() {
- process.exit();
- });
- return conn;
-}
-
-var debug = null;
-
-///////////////////////////////////////////////////////////
-// Browser side
-
-var WEBROOT = path.join(path.dirname(__filename), '../front-end');
-
-function staticFile(req, res) {
- paperboy
- .deliver(WEBROOT, req, res)
- .error(function(statCode,msg) {
- res.writeHead(statCode, {'Content-Type': 'text/plain'});
- res.end("Error: " + statCode);
- })
- .otherwise(function(err) {
- var statCode = 404;
- res.writeHead(statCode, {'Content-Type': 'text/plain'});
- res.end();
- });
-}
-
-var httpServer = http.createServer(staticFile);
-
-var wsServer = ws.createServer({ debug: false }, httpServer);
-
-wsServer.on('connection', function(conn) {
- if (debug == null) {
- debug = attachDebugger();
- }
- conn.on('message', function(msg) {
- request(msg);
- });
-});
-
-////////////////////////////////////////////////////////
-// Startup
-
-var fileToDebug = null;
-var port = 8080;
-var flag = '--debug=';
-var debugPort = 5858;
-var fwd = false;
+var options = {};
process.argv.forEach(function(arg) {
if (arg.indexOf('--') > -1) {
var parts = arg.split('=');
if (parts.length > 1) {
switch(parts[0]) {
case '--start':
- fileToDebug = parts[1];
+ options.file = parts[1];
break;
case '--start-brk':
- fileToDebug = parts[1];
- flag = '--debug-brk=';
+ options.file = parts[1];
+ brk = true;
break;
case '--agent-port':
- port = parseInt(parts[1], 10);
+ options.webPort = parseInt(parts[1], 10);
break;
case '--debug-port':
- debugPort = parseInt(parts[1], 10);
+ options.debugPort = parseInt(parts[1], 10);
break;
default:
console.log('unknown option: ' + parts[0]);
break;
}
}
else if (parts[0] === '--fwd-io') {
- fwd = true;
+ options.fwdio = true;
}
else if (parts[0] === '--help') {
console.log('Usage: node [node_options] debug-agent.js [options]');
@@ -170,42 +44,10 @@ process.argv.forEach(function(arg) {
}
});
-// spawn the process to debug
-if (fileToDebug != null) {
- console.log('starting ' + fileToDebug);
-
- flag = flag + debugPort;
- var debugProcess = spawn('node_g', [flag, fileToDebug]);
-
- if (fwd) {
- debugProcess.stdout.setEncoding('utf8');
- debugProcess.stdout.on('data', function(data) {
- sys.print(data);
- wsServer.broadcast(JSON.stringify({
- seq: 0,
- type: 'event',
- event: 'stdout',
- body: data
- }));
- });
+var ds = session.createSession(options);
- debugProcess.stderr.setEncoding('utf8');
- debugProcess.stderr.on('data', function(data) {
- console.error(data);
- wsServer.broadcast(JSON.stringify({
- seq: 0,
- type: 'event',
- event: 'stderr',
- body: data
- }));
- });
- }
-
- debugProcess.on('exit', function(code) {
- console.log(fileToDebug + ' exited with code ' + code);
- });
-}
-
-// listen for clients
-console.log('visit http://localhost:' + port + ' to start debugging');
-wsServer.listen(port);
+ds.on('close', function() {
+ console.log('session closed');
+ process.exit();
+});
+console.log('visit http://127.0.0.1:' + ds.webPort + ' to start debugging');
View
118 bin/session.js
@@ -0,0 +1,118 @@
+var http = require('http'),
+ events = require('events'),
+ sys = require('sys'),
+ path = require('path'),
+ ws = require('../lib/ws'),
+ paperboy = require('../lib/paperboy'),
+ spawn = require('child_process').spawn,
+ debugr = require('./debugger');
+
+var WEBROOT = path.join(path.dirname(__filename), '../front-end');
+
+function staticFile(req, res) {
+ paperboy
+ .deliver(WEBROOT, req, res)
+ .error(function(statCode,msg) {
+ res.writeHead(statCode, {'Content-Type': 'text/plain'});
+ res.end("Error: " + statCode);
+ })
+ .otherwise(function(err) {
+ var statCode = 404;
+ res.writeHead(statCode, {'Content-Type': 'text/plain'});
+ res.end();
+ });
+}
+
+function override(options, defaults) {
+ var result = {};
+ Object.keys(defaults).forEach(function(key) {
+ result[key] = options[key] || defaults[key];
+ });
+ return result;
+}
+
+///////////////////////////////////////////////////////////
+// exports
+
+exports.createSession = function(options) {
+ var defaults = {
+ debugPort: 5858,
+ webPort: 8080,
+ fwdio: false,
+ brk: false,
+ file: null
+ };
+ var settings = override(options || {}, defaults);
+ var httpServer = http.createServer(staticFile);
+ var wsServer = ws.createServer(null, httpServer);
+ var debug = null;
+
+ wsServer.on('connection', function(conn) {
+ if (!debug) {
+ // first connection
+ debug = debugr.attachDebugger(settings.debugPort);
+ debug.on('data', function(data) {
+ wsServer.broadcast(JSON.stringify(data));
+ });
+ debug.on('close', function() {
+ debug = null;
+ session.close();
+ });
+ }
+ conn.on('message', function(msg) {
+ debug.request(msg);
+ });
+ });
+
+ wsServer.on('close', function() {
+ wsServer = null;
+ session.close();
+ });
+
+ if (settings.file) {
+ var flag = '--debug=';
+ if (options.brk) flag = '--debug-brk=';
+ flag += settings.debugPort;
+ var proc = spawn('node_g', [flag, settings.file]);
+ proc.on('exit', function(code, signal) {
+ proc = null;
+ console.log('proc exited with code: ' + code + ' signal: ' + signal);
+ });
+ if (settings.fwdio) {
+ function sendIo(event, data) {
+ wsServer.broadcast(JSON.stringify({
+ seq: 0,
+ type: 'event',
+ event: event,
+ body: data
+ }));
+ }
+ proc.stdout.setEncoding('utf8');
+ proc.stdout.on('data', function(data) {
+ sys.print(data);
+ sendIo('stdout', data);
+ });
+
+ proc.stderr.setEncoding('utf8');
+ proc.stderr.on('data', function(data) {
+ console.error(data);
+ sendIo('stderr', data);
+ });
+ }
+ }
+ wsServer.listen(settings.webPort);
+
+ var session = Object.create(events.EventEmitter.prototype, {
+ close: {
+ value: function()
+ {
+ if (proc) proc.kill();
+ if (debug && debug.connected) debug.close();
+ if (wsServer) wsServer.close();
+ session.emit('close');
+ }}});
+ session.__defineGetter__('webPort', function() { return settings.webPort; });
+ session.__defineGetter__('debugPort', function() { return settings.debugPort; });
+
+ return session;
+};

0 comments on commit 6043ef5

Please sign in to comment.