restofthings/directory_server/index.js

115 строки
3.7 KiB
JavaScript

const http = require("http")
const fs = require("fs")
const url = require("url")
const utf8 = require("utf8")
var config = JSON.parse(fs.readFileSync(process.argv[2]))
// {ip:{uuid1: {expiryTime:unix, payload:{handlePing payload buffer}}}}
var things = {}
// make sure errors are not cached
function fail(response, code, message) {
response.writeHead(code, {"Content-Type": "text/plain",
"Content-Length": message.length,
});
response.write(message);
console.log("fail", code, message, things);
response.end();
}
function ok(response, message) {
response.writeHead(200, {"Content-Type": "text/plain",
"Content-Length": message.length
});
response.write(message);
response.end();
}
function putPing(uuid, remoteAddress, payload) {
var network = things[remoteAddress];
if (!network) {
things[remoteAddress] = network = {};
}
var thing = network[uuid];
if (!thing) {
console.log("got no thing :(");
network[uuid] = thing = {};
console.log("network is ", network);
}
thing.expiryTime = Date.now();
thing.payload = payload.toString('utf8');
}
/** put json to /thing/stable-uuid
{'uuid':x, 'localurl':y, 'tags':["tag1", ..], 'description':"raspberry pi"}
repeat calls here should just PUT an empty body...Server will 404 if body not already present
*/
function handlePing(uuid, request, response) {
if (!('content-length' in request.headers)) {
return fail(response, 500, "Missing content-length header");
}
var content_length = request.headers['content-length'] * 1
var buf = new Buffer(content_length);
var pos = 0;
request.on('data', function(chunk) {
chunk.copy(buf, pos);
pos += chunk.length;
console.log("got data for uuid ", uuid, "data", chunk.toString('utf8'));
})
request.on('end', function() {
var remoteAddress = request.connection.remoteAddress;
console.log("request.connection.remoteAddress", request.connection.remoteAddress)
putPing(uuid, remoteAddress, buf);
ok(response, "OK");
});
}
function handleGet(request, response) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET,POST"); //?put
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
var pathname = url.parse(request.url).pathname;
var remoteAddress = request.connection.remoteAddress;
console.log("my remote address is ------", remoteAddress);
var network = things[remoteAddress];
if (!network)
network = {};
if (pathname == "/ls") {
return ok(response, JSON.stringify(network));
} if (pathname.substr(0, 7) == "/thing/") {
var uuid = pathname.substr(7);
var thing = network[uuid];
if (!thing)
return fail(response, 404, "No thing " + uuid + " in " + remoteAddress + " network");
return ok(response, thing.payload);
} else {
return fail(response, 404, pathname + " not found");
}
}
function handlePut(request, response) {
var pathname = url.parse(request.url).pathname;
if (pathname.substr(0,7) == "/thing/") {
return handlePing(pathname.substr(7), request, response);
}
response.write(pathname);
response.end();
}
http.createServer(function(request, response) {
var pathname = url.parse(request.url).pathname;
if (request.method == "GET" || request.method == "HEAD") {
return handleGet(request, response);
} else if (request.method == "PUT") {
return handlePut(request, response);
} else {
fail(response, 500, "what is this method:"+request.method);
}
//also handle CONNECT for proxying
}).listen(config.port, config.host);
console.log("Server running at\n =>"+config.host+":" + config.port + "/\nCTRL + C to shutdown");