Skip to content

Commit

Permalink
Merge pull request marccampbell#3 from georgeye/master
Browse files Browse the repository at this point in the history
server code
  • Loading branch information
marccampbell committed Sep 9, 2011
2 parents 8c28de7 + b726354 commit c2288d1
Show file tree
Hide file tree
Showing 3 changed files with 288 additions and 1 deletion.
10 changes: 10 additions & 0 deletions config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
var config = {};

config.maxFiles = 1;
config.filePrefix = "confFile";
config.fileSuffix = ".conf";
config.fileLocation = "./";
config.logFile = './trace.log';
config.logLevel = 3;

module.exports = config;
176 changes: 175 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,175 @@
module.exports = require('./lib/autocomplete');
var net = require('net'), sys = require('sys'), fs = require('fs'), lazy = require('lazy');
var winston = require('winston');
var parser = require("./lib/message");
var autocomplete = require('./lib/autocomplete');
var config = require('./config');

//initialized logging (winston)
winston.add(winston.transports.File, { filename: config.logFile});
winston.remove(winston.transports.Console);
var a = autocomplete.connectAutocomplete();

initServer(config, a);

var server = net.createServer(function (stream) {
stream.setEncoding("utf8");
stream.on("connect", initStream);
stream.on("data", handleReceive);
stream.on("end", function () {
stream.end();
logInfo('stream end, closing');
});

stream.on("error", function(error) {
logError(error);
stream.end();
});
});
server.listen(5050, "127.0.0.1");
// });

function handleReceive(data) {
// console.log('received ' + data.length + ' bytes of data');
this.myRequest.inBuffer = this.myRequest.inBuffer + data;
// console.log('total length=' + this.myRequest.inBuffer.length);
for(; ;) {
var rc = parser.parse(this.myRequest);
if(rc) {
logDebug('read a request, start to handle');
// start to handle payload
var payload = this.myRequest.inBuffer.substr(this.myRequest.headerLength+4, this.myRequest.contentLength);
//logDebug('received content:' + payload);
var jPayload = JSON.parse(payload);
if(jPayload.method === 'add') {
//handle add
processAdd(jPayload);
}
else if(jPayload.method === 'remove') {
//handle remove
processRemove(jPayload);
}
else if(jPayload.method === 'search') {
processSearch(jPayload, this);
}
resetStream(this.myRequest);
}
else if(this.myRequest.needRead) {
break;
}
else {
logError("in error, close the stream");
this.end();
break;
}
}
}

function initStream() {
this.myRequest = new Object;
this.myRequest.inBuffer = "";
this.myRequest.contentLength = 0;
this.myRequest.needRead = true;
this.myRequest.headerReceived = false;
this.myRequest.headerLength = 0;
this.myRequest.requestId = "";
//console.log("a new connection\n");
// sys.puts(sys.inspect(socket, false));
}

function processAdd(data) {
logInfo('in add operation');
var items = data.data;
for(var i = 0; i < items.length; i++) {
if(items[i].key.length > 0 && items[i].value) {
// console.log('add item:' + items[i]);
a.addElement(items[i]);
}
else if(item[i].key.length > 0 && !items[i].value) {
// console.log('add item:' + items[i].key);
a.addElement(items[i].key);
}
}
}

function processRemove(data) {
logInfo('in remove operation');
var items = data.data;
for(var i = 0; i < items.length; i++) {
if(items[i].key.length > 0) {
logInfo('remove item:' + items[i].key);
a.removeElement(items[i].key);
}
}
}

function processSearch(data, socket ) {
logInfo('in search operation');
var results = [];
var items = data.data;
if(items.length > 0) {
results = a.search(data.data[0].key);
}
// send resutls back
var response = new Object();
response.method = 'search';
response.data = results.slice(0,20); //only return 20 items
var jresp = JSON.stringify(response);
var wire ='Content-Length:' + jresp.length + '\r\n';
wire = wire + 'Request-Id:' + socket.myRequest.requestId + '\r\n\r\n' + jresp;
//logDebug("total lenght is:" + wire.length);
//logDebug(wire);
socket.write(wire);
}

function resetStream(request) {
// move remaining data to the front
request.inBuffer = request.inBuffer.substr(request.headerLength+4 + request.contentLength);
request.headerLength = 0;
request.contentLength = 0;
request.needRead = true;
request.headerReceived = false;
request.requestId = "";
}

function initServer(config, AutoComplete) {
for(var i = 0; i < config.maxFiles; i++) {
var fileName = config.fileLocation + config.filePrefix + i + config.fileSuffix;
// console.log('file name=' + fileName);
new lazy(fs.createReadStream(fileName))
.lines
.forEach(function(line) {
var kv = line.toString().split(':');
//console.log('add key/value: ' + kv);
if(kv.length > 1) {
var item = new Object();
item.key = kv[0];
item.value = kv[1];
AutoComplete.addElement(item);
}
else {
AutoComplete.addElement(kv[0]);
}
}
);
}
}

function logInfo(log) {
if(config.logLevel >= 4) {
var current = new Date();
winston.info(current + ': ' + log);
}
}
function logDebug(log) {
if(config.logLevel >=5) {
var current = new Date();
winston.debug(current + ': ' + log);
}
}
function logError(log) {
if(config.logLevel >= 2) {
var current = new Date();
winston.error(current + ': ' + log);
}
}

103 changes: 103 additions & 0 deletions lib/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@

exports.parse = function(request) {
var MAXHEADERLENGTH = 100;
//check if request header is received
var rc = false;
//console.log('in parser');
if(request.headerReceived) { // to get the content then
if(request.inBuffer.length >= (request.headerLength + request.contentLength + 4)) {
rc = true;
request.needRead = false;
}
else {
request.needRead = true;
}
}
else {
var index = -1;
// console.log('try to get header');
index = request.inBuffer.indexOf("\r\n\r\n");
if(index != -1) {
// console.log('header received');
request.headerReceived = true;
request.headerLength = index;
var rc1 = parseHeader(request);
// check if content is received
if(rc1) {
// console.log('contentLenght=' + request.contentLength + ' requestId=' + request.requestId);
// console.log('total message Len:' + request.inBuffer.length + ' contentLenght=' + request.contentLength + ' requestHeaderLength=' + request.headerLength);
if(request.inBuffer.length >= (request.headerLength + request.contentLength + 4)) {
rc = true;
request.needRead = false;
}
else {
request.needRead = true;
}
}
else { // something wrong in header
request.needRead = false;
rc = false;
}
}
else {
if(request.inBuffer.length > MAXHEADERLENGTH) { // must be bad request
rc = false;
request.needRead = false;
}
else {
request.needRead = true;
}
// console.log('need to read more');
}
}
return rc;
};

function parseHeader(request) {
var rc = true;
var subHeaders = request.inBuffer.split("\r\n");
request.contentLength = getContentLength(subHeaders);
request.requestId = getRequestId(subHeaders);
if(request.contentLength == 0 || request.requestId == "") {
rc = false;
}
return rc;
}

function getContentLength(headers) {
var index = -1, i =0;
var length = 0;
for(i = 0; i < headers.length; i++) {
if(headers[i].indexOf("Content-Length") != -1) {
var subString = headers[i].split(":");
if(subString.length == 2) {
length = parseInt(subString[1]);
if(isNaN(length)) {
length = 0;
}
}
break;
}
}
//console.log('contentLength:' + length);
return length;
}

function getRequestId(headers) {
var i =0;
var requestId = "";
for(i = 0; i < headers.length; i++) {
if(headers[i].indexOf("Request-Id") != -1) {
var subString = headers[i].split(":");
if(subString.length == 2) {
//remove leading and trailing whitespace
requestId = subString[1].replace(/^\s+|\s+$/g, '') ;
}
break;
}
}
//console.log('requestid:' + requestId);
return requestId;
}


0 comments on commit c2288d1

Please sign in to comment.