diff --git a/lib/server.js b/lib/server.js index 1adc664..ab0571a 100644 --- a/lib/server.js +++ b/lib/server.js @@ -39,7 +39,12 @@ function getArguments(fun) { m3 = /\s+/g; var names = fun.toString().match(m1)[1].replace(m2, '').replace(m3, '').split(','); - return names.length == 1 && !names[0] ? [] : names; + var args = names.length == 1 && !names[0] ? [] : names; + + //Remove the last argument from the args becase it is the callback + args.pop(); + + return args; } //Extracts the public methods (and their arguments) of a context. @@ -54,60 +59,72 @@ function publicMethods(context) { //Ignore members that start with an underscore or are not functions for(var name in context) { if(!/^_/.test(name) && typeof(context[name]) == 'function') { - var args = getArguments(context[name]); - - //Remove the last argument from the args becase it is the callback - args.pop(); - - methods[name] = args; + methods[name] = getArguments(context[name]); } } return methods; } -//Adds the new-school introspector function to a context -//context : Object -// The object to be exposed -//methods : Object -// The set public methods of the exposed object -function addIntrospector(context, methods) { +// Creates a new server +// context : Object +// The object to expose +function Server(context) { + var self = this; + + self._socket = socket.server(); + util.eventProxy(self._socket, self, "error"); + + self._methods = publicMethods(context); + + var newInspector = self._createIntrospector(); + var oldInspector = self._createLegacyIntrospector(); + + context._zpc_inspect = newInspector; + self._methods._zpc_inspect = getArguments(newInspector); + + context._zerorpc_inspect = oldInspector; + self._methods._zerorpc_inspect = getArguments(oldInspector); + + self._socket.on("multiplexing-socket/receive", function(event) { + if(event.name in self._methods) self._recv(event, context); + }); +} + +nodeUtil.inherits(Server, events.EventEmitter); + +//Creates the new-school introspector +Server.prototype._createIntrospector = function() { var results = {}; - for(var name in methods) { + for(var name in this._methods) { results[name] = { doc: "", - args: _.map(methods[name], function(arg) { + args: _.map(this._methods[name], function(arg) { return { name: arg }; }) }; } - methods._zpc_inspect = true; - - context._zpc_inspect = function(reply) { + return function(reply) { reply(results); }; } -//Adds the old-school introspector function to a context -//context : Object -// The object to be exposed -//methods : Object -// The set public methods of the exposed object -function addLegacyIntrospector(context, methods) { - methods._zerorpc_inspect = true; +//Creates the old-school introspector +Server.prototype._createLegacyIntrospector = function() { + var self = this; - context._zerorpc_inspect = function(method, longDoc, reply) { + return function(method, longDoc, reply) { if(method) { var key = "method"; - var filteredMethods = _.filter(methods, function(args, name) { + var filteredMethods = _.filter(self._methods, function(args, name) { return name === method; }); } else { var key = "methods"; - var filteredMethods = methods; + var filteredMethods = self._methods; } var results = {}; @@ -120,26 +137,6 @@ function addLegacyIntrospector(context, methods) { }; } -// Creates a new server -// context : Object -// The object to expose -function Server(context) { - var self = this; - - self._socket = socket.server(); - util.eventProxy(self._socket, self, "error"); - - var methods = publicMethods(context); - addIntrospector(context, methods); - addLegacyIntrospector(context, methods); - - self._socket.on("multiplexing-socket/receive", function(event) { - if(event.name in methods) self._recv(event, context); - }); -} - -nodeUtil.inherits(Server, events.EventEmitter); - //Called when a method call event is received //event : Object // The ZeroRPC event @@ -204,6 +201,8 @@ Server.prototype._recv = function(event, context) { if(!(event.args instanceof Array)) { self.emit("error", "Invalid event: Bad args"); return ch.close(); + } else if(event.args.length != self._methods[event.name].length) { + return sendError(new Error("Invalid number of arguments")); } //Call the method diff --git a/test/invocation.js b/test/invocation.js index c7d1155..e325400 100644 --- a/test/invocation.js +++ b/test/invocation.js @@ -241,10 +241,11 @@ exports.testIntrospector = function(test) { }; exports.testIncorrectArgumentCount = function(test) { - test.expect(3); + test.expect(4); - rpcClient.invoke("addMan", function(error, res, more) { + rpcClient.invoke("lazyIter", function(error, res, more) { test.ok(error); + test.equal(error.message, "Invalid number of arguments"); test.equal(res, null); test.equal(more, false); test.done();