Skip to content
Browse files

Introduce a /sysinfo/ URL which displays the version number of NXB an…

…d other pieces of information. Make sure that the URL is password protected by a non-empty password. Use pre-compiled ejs-templates instead of hand-crafting HTML pages (separate logic and presentation). Bump up version to 0.7.0.
  • Loading branch information...
1 parent d2d6d09 commit 3e5cd8ca52a4202e397438bd8889cee59bad9634 @dhruvbird committed Nov 3, 2012
Showing with 167 additions and 35 deletions.
  1. +3 −1 bosh.conf.example.js
  2. +4 −4 package.json
  3. +47 −26 src/bosh.js
  4. +49 −4 src/http-server.js
  5. +2 −0 src/options.js
  6. +22 −0 templates/stats.html
  7. +40 −0 templates/sysinfo.html
View
4 bosh.conf.example.js
@@ -61,6 +61,8 @@ exports.config = {
// The maximum length of an XML stanza to be printed. Set to -1
// for unlimited line length.
- trim_default_length: 256
+ trim_default_length: 256,
+ // Set the password here to limit access to the /PATH/sysinfo/ URL.
+ system_info_password: ''
};
View
8 package.json
@@ -1,8 +1,8 @@
{
"name": "node-xmpp-bosh",
- "version": "0.6.4",
+ "version": "0.7.0",
"main": "./src/main",
- "bin": {
+ "bin": {
"bosh-server": "./run-server.js"
},
"description": "An XMPP BOSH server written for node.js in javascript",
@@ -16,9 +16,9 @@
"eventpipe": "~0.0.5",
"dns-srv": "~0.0.6",
"semver": "~1.0.8",
- "ws": "~0.4.19",
+ "ws": "= 0.4.19",
"node-lumberjack": "= 0.0.4",
- "ws": "= 0.4.19"
+ "ejs": "~0.8.3"
},
"devDependencies": {
"jsdom": "~0.2.15",
View
73 src/bosh.js
@@ -26,13 +26,16 @@
var ltx = require('ltx');
var dutil = require('./dutil.js');
var us = require('underscore');
+var fs = require('fs');
+var os = require('os');
var sess = require('./session.js');
var strm = require('./stream.js');
var helper = require('./helper.js');
var opt = require('./options.js');
var path = require('path');
var bee = require('./bosh-event-emitter.js');
var http = require('./http-server.js');
+var ejs = require('ejs');
var toNumber = us.toNumber;
var sprintf = dutil.sprintf;
@@ -82,38 +85,55 @@ exports.createServer = function (options) {
// (and only) place of reference for object structure.
//
- var started;
+ var started = new Date(); // When was this server started?
var session_store;
var stream_store;
var bep;
var bosh_options;
var server;
-
- started = new Date(); // When was this server started?
+ var stats_template = ejs.compile(fs.readFileSync(require.resolve('../templates/stats.html'), 'utf8'));
+ var sysinfo_template = ejs.compile(fs.readFileSync(require.resolve('../templates/sysinfo.html'), 'utf8'));
+ var pkgJSON = JSON.parse(fs.readFileSync(require.resolve('../package.json')));
+
+ function get_system_info() {
+ // Use a pre-compiled ejs template here.
+ var opt_keys = us.without(Object.keys(options), 'system_info_password');
+ var opts = opt_keys.map(function(opt_key) {
+ var v = options[opt_key];
+ if (v instanceof RegExp) {
+ v = String(v);
+ } else {
+ v = JSON.stringify(v);
+ }
+ return {
+ key: opt_key,
+ value: v
+ };
+ });
+ var content = sysinfo_template({
+ hostname: os.hostname(),
+ uptime: dutil.time_diff(started, new Date()),
+ version: pkgJSON.version,
+ active_sessions: session_store.get_active_no(),
+ total_sessions: session_store.get_total_no(),
+ active_streams: stream_store.get_active_no(),
+ total_streams: stream_store.get_total_no(),
+ options: opts
+ });
+ return content;
+ }
function get_statistics() {
- var stats = [ ];
- var content = new ltx.Element('html')
- .c('head')
- .c('title').t('node-xmpp-bosh').up()
- .up()
- .c('body')
- .c('h1')
- .c('a', {'href': 'http://dhruvbird.com/p/node-xmpp-bosh'})
- .t('node-xmpp-bosh')
- .up()
- .up()
- .c('h3').t('Bidirectional-streams Over Synchronous HTTP').up()
- .c('p').t(sprintf('Uptime: %s', dutil.time_diff(started, new Date()))).up()
- .c('p').t(sprintf('%s/%s active %s', session_store.get_active_no(),
- session_store.get_total_no(),
- dutil.pluralize(session_store.get_total_no(), 'session'))).up()
- .c('p').t(sprintf('%s/%s active %s', stream_store.get_active_no(),
- stream_store.get_total_no(),
- dutil.pluralize(stream_store.get_total_no(), 'stream'))).up()
- .tree();
- stats.push(content.toString());
- return stats.join('\n');
+ // Use a pre-compiled ejs template here.
+ var content = stats_template({
+ hostname: os.hostname(),
+ uptime: dutil.time_diff(started, new Date()),
+ active_sessions: session_store.get_active_no(),
+ total_sessions: session_store.get_total_no(),
+ active_streams: stream_store.get_active_no(),
+ total_streams: stream_store.get_total_no()
+ });
+ return content;
}
function process_bosh_request(res, node) {
@@ -267,7 +287,8 @@ exports.createServer = function (options) {
bosh_options = new opt.BOSH_Options(options);
server = new http.HTTPServer(options.port, options.host, get_statistics,
- bosh_request_handler, http_error_handler, bosh_options);
+ get_system_info, bosh_request_handler,
+ http_error_handler, bosh_options);
// The BOSH event emitter. People outside will subscribe to
// events from this guy. We return an instance of BoshEventPipe
// to the outside world when anyone calls createServer()
View
53 src/http-server.js
@@ -36,7 +36,8 @@ var log = require('./log.js').getLogger(filename);
var BoshRequestParser = require('./bosh-request-parser').BoshRequestParser;
-function HTTPServer(port, host, stat_func, bosh_request_handler, http_error_handler,
+function HTTPServer(port, host, stat_func, system_info_func,
+ bosh_request_handler, http_error_handler,
bosh_options) {
var bosh_request_parser = new BoshRequestParser();
@@ -206,6 +207,7 @@ function HTTPServer(port, host, stat_func, bosh_request_handler, http_error_hand
var _headers = { };
dutil.copy(_headers, bosh_options.HTTP_GET_RESPONSE_HEADERS);
_headers['Content-Type'] = 'text/html; charset=utf-8';
+
res.writeHead(200, _headers);
var stats = stat_func();
@@ -214,6 +216,48 @@ function HTTPServer(port, host, stat_func, bosh_request_handler, http_error_hand
}
}
+ function handle_get_system_info(req, res, u) {
+ var ppos = path.dirname(u.pathname).search(bosh_options.path);
+ if (ppos == -1) {
+ // Try matching both with and without the trailing slash.
+ ppos = (path.dirname(u.pathname) + "/").search(bosh_options.path);
+ }
+ var spos = path.basename(u.pathname).search("sysinfo");
+
+ if (req.method === 'GET' && ppos !== -1 && spos === 0) {
+ var _headers = { };
+ dutil.copy(_headers, bosh_options.HTTP_GET_RESPONSE_HEADERS);
+ _headers['Content-Type'] = 'text/html; charset=utf-8';
+
+ if (bosh_options.SYSTEM_INFO_PASSWORD.length === 0) {
+ res.writeHead(403, _headers);
+
+ res.end("No Password set or default password is being used. " +
+ "Please set/change the password in the config file.");
+ return false;
+ }
+
+ // Check if we got the password back.
+ var auth_header = req.headers.authorization;
+ if (auth_header) {
+ auth_header = auth_header.split(' ')[1];
+ var auth_str = new Buffer(auth_header, 'base64').toString();
+ var real_auth_str = 'admin:' + bosh_options.SYSTEM_INFO_PASSWORD;
+ if (auth_str === real_auth_str) {
+ res.writeHead(200, _headers);
+ var sysinfo = system_info_func();
+ res.end(sysinfo);
+ return false;
+ }
+ }
+
+ _headers['WWW-Authenticate'] = 'Basic realm="System Information"';
+ res.writeHead(401, _headers);
+ res.end();
+ return false;
+ }
+ }
+
//
// http://code.google.com/p/node-xmpp-bosh/issues/detail?id=22
// Supporting cross-domain requests through the addition of flash. This will be necessary
@@ -260,9 +304,10 @@ function HTTPServer(port, host, stat_func, bosh_request_handler, http_error_hand
.on('request', handle_get_bosh_request, 2)
.on('request', handle_options, 3)
.on('request', handle_get_favicon, 4)
- .on('request', handle_get_statistics, 5)
- .on('request', handle_get_crossdomainXML, 6)
- .on('request', handle_unhandled_request, 7);
+ .on('request', handle_get_system_info, 5)
+ .on('request', handle_get_statistics, 6)
+ .on('request', handle_get_crossdomainXML, 7)
+ .on('request', handle_unhandled_request, 8);
function http_request_handler(req, res) {
var u = url.parse(req.url, true);
View
2 src/options.js
@@ -84,6 +84,8 @@ function BOSH_Options(opts) {
this.MAX_STREAMS_PER_SESSION = _opts.max_streams_per_session || 8;
this.PIDGIN_COMPATIBLE = _opts.pidgin_compatible || false;
+
+ this.SYSTEM_INFO_PASSWORD = _opts.system_info_password || '';
}
exports.BOSH_Options = BOSH_Options;
View
22 templates/stats.html
@@ -0,0 +1,22 @@
+<html>
+<head>
+ <title>node-xmpp-bosh on <%= hostname %></title>
+ <style type="text/css">
+ body {
+ font-family: Helvetica Neue, Helvetica, Arial;
+ padding-left: 20px;
+ padding-top: 10px;
+ }
+ </style>
+</head>
+
+<body>
+ <h1>
+ <a href="http://dhruvbird.com/p/node-xmpp-bosh">node-xmpp-bosh</a> on <%= hostname %>
+ </h1>
+ <h3>Bidirectional-streams Over Synchronous HTTP</h3>
+ <p>Uptime: <%= uptime %></p>
+ <p><%= active_sessions %>/<%= total_sessions %> active sessions</p>
+ <p><%= active_streams %>/<%= total_streams %> active streams</p>
+</body>
+</html>
View
40 templates/sysinfo.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+ <title>node-xmpp-bosh version <%= version %> on <%= hostname %></title>
+ <style type="text/css">
+ body {
+ font-family: Helvetica Neue, Helvetica, Arial;
+ padding-left: 20px;
+ padding-top: 10px;
+ }
+ </style>
+</head>
+
+<body>
+ <h1>
+ <a href="http://dhruvbird.com/p/node-xmpp-bosh">node-xmpp-bosh</a>
+ version <%= version %> on <%= hostname %>
+ </h1>
+ <h3>Bidirectional-streams Over Synchronous HTTP</h3>
+ <p>Uptime: <%= uptime %></p>
+ <p><%= active_sessions %>/<%= total_sessions %> active sessions</p>
+ <p><%= active_streams %>/<%= total_streams %> active streams</p>
+
+ <h3>Configuration Options</h3>
+ <table border="1" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Option</th>
+ <th>Value</th>
+ </tr>
+
+ <% options.forEach(function(option) { %>
+ <tr>
+ <td><%= option.key %></td>
+ <td><%= option.value %></td>
+ </tr>
+ <% }); %>
+
+ </table>
+
+</body>
+</html>

0 comments on commit 3e5cd8c

Please sign in to comment.
Something went wrong with that request. Please try again.