Skip to content

Instantly share code, notes, and snippets.

@mcroydon
Created February 2, 2011 05:45
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mcroydon/807303 to your computer and use it in GitHub Desktop.
Save mcroydon/807303 to your computer and use it in GitHub Desktop.
A minimal NNTP implementation in node.js
var net = require('net');
var END = '\r\n';
var groups = ['nodejs.test'];
var articles = {
'<1@127.0.0.1>' : {body : 'An article.'},
'<2@127.0.0.1>' : {body : 'Another article.'},
};
var messages = {
'nodejs.test' : ['<1@127.0.0.1>', '<1@127.0.0.1>'],
};
var startswith = function(string, substring) {
if (string.indexOf(substring) == 0) {
return true;
}
else {
return false;
}
}
net.createServer(function (socket) {
// Party like it's 1986
socket.setEncoding("ascii");
socket.on('connect', function() {
this.client = {socket : socket, group : null, article_index : null};
socket.write('201 nntpd.js server ready (no posting allowed)' + END);
});
socket.on('data', function(data) {
command = data.toLowerCase();
if (startswith(command, 'help')) {
console.log('HELP');
socket.write('100 help text follows' + END);
socket.write('nntpd.js is a minimal implementation of NNTP in node.js.' + END);
socket.write('Available commends:' + END);
socket.write('HELP' + END);
socket.write('.' + END);
}
else if (startswith(command, 'list')) {
console.log('LIST');
socket.write('215 list of newsgroups follows' + END);
groups.forEach(function(group) {
socket.write(group + ' ' + messages[group].length + ' ' + '1' + ' ' + 'n' + END);
});
socket.write('.' + END);
}
else if (startswith(command, 'group')) {
var group = command.replace(/^group\s/, '').replace(/\r\n$/, '');
console.log('GROUP ' + group)
if (messages[group]) {
this.client.group = group;
console.log('group set to ' + this.client.group);
// 1 should be repalced with the first article number
socket.write('211' + ' ' + messages[group].length + ' ' + 1 + messages[group].length + group + END);
}
else {
socket.write('411 no such news group' + END);
}
}
else if (startswith(command, 'article')) {
if (command.indexOf('<') != -1) {
// Accessing article by id
var id = command.replace(/^article\s/, '').replace(/\r\n$/, '');
console.log('retrieving article ' + id);
if (articles[id] !== undefined) {
// 1 should be replaced with the article number.
socket.write('220 ' + 1 + ' ' + id + ' article retrieved - head and body follow' + END);
socket.write(articles[id]['body'] + END);
socket.write('.' + END);
}
else {
socket.write('430 no such article found' + END);
}
}
else {
if (this.client.group === null) {
socket.write('412 no newsgroup has been selected' + END);
}
else {
article = messages[group][int(id)];
socket.write('220 ' + 1 + article.id + 'article retrieved - head and body follow' + END);
socket.write(articles[id]['body'] + END);
socket.write('.' + END);
}
}
}
else {
console.log('command ' + command + ' not recognized');
socket.write('500 command not recognized.' + END);
}
});
}).listen(119, "127.0.0.1")
console.log('nntpd.js running.');
$ python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from nntplib import NNTP
>>> nntp = NNTP('127.0.0.1')
>>> nntp.help()
('100 help text follows', ['nntpd.js is a minimal implementation of NNTP in node.js.', 'Available commends:', 'HELP'])
>>> nntp.list()
('215 list of newsgroups follows', [('nodejs.test', '2', '1', 'n')])
>>> nntp.article('<1@127.0.0.1>')
('220 1 <1@127.0.0.1> article retrieved - head and body follow', '1', '<1@127.0.0.1>', ['An article.'])
$ sudo node nntpd.js
nntpd.js running.
HELP
LIST
retrieving article <1@127.0.0.1>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment