Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated to be compatible with nodejs 0.4.7

  - process.mixin has been removed, use extend instead
  - process.promise has been removed, use last arg callbacks instead
  - http module interface changed
  • Loading branch information...
commit c78c2415f41728ea33ea4daf8f730b5269f6ce2c 1 parent d16da4e
@blanu blanu authored
Showing with 73 additions and 53 deletions.
  1. +73 −53 src/jsonrpc.js
View
126 src/jsonrpc.js
@@ -1,6 +1,21 @@
var sys = require('sys');
var http = require('http');
+var extend=function(a,b)
+{
+ var prop;
+
+ for(prop in b)
+ {
+ if(b.hasOwnProperty(prop))
+ {
+ a[prop] = b[prop];
+ }
+ }
+
+ return a;
+};
+
var functions = {};
var METHOD_NOT_ALLOWED = "Method Not Allowed\n";
@@ -9,10 +24,8 @@ var INVALID_REQUEST = "Invalid Request\n";
var JSONRPCClient = function(port, host) {
this.port = port;
this.host = host;
-
+
this.call = function(method, params, callback, errback, path) {
- var client = http.createClient(port, host);
-
// First we encode the request into JSON
var requestJSON = JSON.stringify({
'id': '' + (new Date()).getTime(),
@@ -23,47 +36,54 @@ var JSONRPCClient = function(port, host) {
var headers = {
'host': host,
'Content-Length': requestJSON.length
+ };
+
+ if(path===null)
+ {
+ path='/';
}
- // We will be returning a Promise for when this result completes, so
- // we first need to instantiate it.
- var promise = new process.Promise();
- // Now we'll make a request to the server
- var request = client.post(path || '/', headers);
- request.sendBody(requestJSON);
- request.finish(function(response) {
- // We need to buffer the response chunks in a nonblocking way.
- var buffer = '';
- response.addListener('body', function(chunk) {
- buffer = buffer + chunk;
- });
- // When all the responses are finished, we decode the JSON and
- // depending on whether it's got a result or an error, we call
- // emitSuccess or emitError on the promise.
- response.addListener('complete', function() {
- var decoded = JSON.parse(buffer);
- if(decoded.hasOwnProperty('result')) {
- promise.emitSuccess(decoded.result);
- }
- else {
- promise.emitError(decoded.error);
- }
- });
- });
- // If a callback was passed, we politely attach it to the promise.
- if(callback) {
- promise.addCallback(callback);
- }
- if(errback) {
- promise.addErrback(errback);
+
+ var options={
+ host: host,
+ port: port,
+ path: path,
+ headers: headers,
+ method: 'POST'
}
- return promise;
+
+ var buffer = '';
+
+ var req = http.request(options, function(res) {
+ res.on('data', function(chunk) {
+ buffer = buffer + chunk;
+ });
+
+ res.on('end', function() {
+ var decoded = JSON.parse(buffer);
+ if(decoded.hasOwnProperty('result'))
+ {
+ callback(null, decoded.result);
+ }
+ else
+ {
+ callback(decoded.error, null);
+ }
+ });
+
+ res.on('error', function(err) {
+ callback(err, null);
+ });
+ });
+
+ req.write(requestJSON);
+ req.end();
};
}
var JSONRPC = {
-
+
functions: functions,
-
+
exposeModule: function(mod, object) {
var funcs = [];
for(var funcName in object) {
@@ -76,35 +96,35 @@ var JSONRPC = {
JSONRPC.trace('***', 'exposing module: ' + mod + ' [funs: ' + funcs.join(', ') + ']');
return object;
},
-
+
expose: function(name, func) {
JSONRPC.trace('***', 'exposing: ' + name);
functions[name] = func;
},
-
+
trace: function(direction, message) {
sys.puts(' ' + direction + ' ' + message);
},
-
+
listen: function(port, host) {
JSONRPC.server.listen(port, host);
JSONRPC.trace('***', 'Server listening on http://' + (host || '127.0.0.1') + ':' + port + '/');
},
-
+
handleInvalidRequest: function(req, res) {
res.sendHeader(400, [['Content-Type', 'text/plain'],
['Content-Length', INVALID_REQUEST.length]]);
res.sendBody(INVALID_REQUEST);
res.finish();
},
-
+
handlePOST: function(req, res) {
var buffer = '';
var promise = new process.Promise();
promise.addCallback(function(buf) {
var decoded = JSON.parse(buf);
-
+
// Check for the required fields, and if they aren't there, then
// dispatch to the handleInvalidRequest function.
if(!(decoded.method && decoded.params && decoded.id)) {
@@ -113,7 +133,7 @@ var JSONRPC = {
if(!JSONRPC.functions.hasOwnProperty(decoded.method)) {
return JSONRPC.handleInvalidRequest(req, res);
}
-
+
// Build our success handler
var onSuccess = function(funcResp) {
JSONRPC.trace('-->', 'response (id ' + decoded.id + '): ' + JSON.stringify(funcResp));
@@ -127,7 +147,7 @@ var JSONRPC = {
res.sendBody(encoded);
res.finish();
};
-
+
// Build our failure handler (note that error must not be null)
var onFailure = function(failure) {
JSONRPC.trace('-->', 'failure: ' + JSON.stringify(failure));
@@ -141,9 +161,9 @@ var JSONRPC = {
res.sendBody(encoded);
res.finish();
};
-
+
JSONRPC.trace('<--', 'request (id ' + decoded.id + '): ' + decoded.method + '(' + decoded.params.join(', ') + ')');
-
+
// Try to call the method, but intercept errors and call our
// onFailure handler.
var method = JSONRPC.functions[decoded.method];
@@ -154,7 +174,7 @@ var JSONRPC = {
catch(err) {
return onFailure(err);
}
-
+
// If it's a promise, we should add callbacks and errbacks,
// but if it's not, we can just go ahead and call the callback.
if(resp instanceof process.Promise) {
@@ -172,7 +192,7 @@ var JSONRPC = {
promise.emitSuccess(buffer);
});
},
-
+
handleNonPOST: function(req, res) {
res.sendHeader(405, [['Content-Type', 'text/plain'],
['Content-Length', METHOD_NOT_ALLOWED.length],
@@ -180,7 +200,7 @@ var JSONRPC = {
res.sendBody(METHOD_NOT_ALLOWED);
res.finish();
},
-
+
handleRequest: function(req, res) {
JSONRPC.trace('<--', 'accepted request');
if(req.method === 'POST') {
@@ -190,15 +210,15 @@ var JSONRPC = {
JSONRPC.handleNonPOST(req, res);
}
},
-
+
server: http.createServer(function(req, res) {
// TODO: Get rid of this extraneous extra function call.
JSONRPC.handleRequest(req, res);
}),
-
+
getClient: function(port, host) {
return new JSONRPCClient(port, host);
}
};
-process.mixin(exports, JSONRPC);
+extend(exports, JSONRPC);
Please sign in to comment.
Something went wrong with that request. Please try again.