Gopher server revamp!

* gophermap support
* More generic and flexible server
This commit is contained in:
Bryan Ashby 2020-11-27 00:54:56 -07:00
parent 228cd79989
commit f7e4b57763
No known key found for this signature in database
GPG key ID: B49EB437951D2542
8 changed files with 98 additions and 29 deletions

View file

@ -27,6 +27,7 @@ const _ = require('lodash');
const fs = require('graceful-fs');
const paths = require('path');
const moment = require('moment');
const async = require('async');
const ModuleInfo = exports.moduleInfo = {
name : 'Gopher',
@ -81,8 +82,8 @@ exports.getModule = class GopherModule extends ServerModule {
this.publicHostname = config.contentServers.gopher.publicHostname;
this.publicPort = config.contentServers.gopher.publicPort;
this.addRoute(/^\/?\r\n$/, this.defaultGenerator);
this.addRoute(/^\/msgarea(\/[a-z0-9_-]+(\/[a-z0-9_-]+)?(\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(_raw)?)?)?\/?\r\n$/, this.messageAreaGenerator);
this.addRoute(/^\/?msgarea(\/[a-z0-9_-]+(\/[a-z0-9_-]+)?(\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(_raw)?)?)?\/?\r\n$/, this.messageAreaGenerator);
this.addRoute(/^(\/?[^\t\r\n]*)\r\n$/, this.staticGenerator);
this.server = net.createServer( socket => {
socket.setEncoding('ascii');
@ -161,22 +162,56 @@ exports.getModule = class GopherModule extends ServerModule {
return `${itemType}${text}\t${selector}\t${hostname}\t${port}\r\n`;
}
defaultGenerator(selectorMatch, cb) {
this.log.debug( { selector : selectorMatch[0] }, 'Serving default content');
staticGenerator(selectorMatch, cb) {
this.log.debug( { selector : selectorMatch[1] || '(gophermap)' }, 'Serving static content');
let bannerFile = _.get(Config(), 'contentServers.gopher.bannerFile', 'gopher_banner.asc');
bannerFile = paths.isAbsolute(bannerFile) ? bannerFile : paths.join(__dirname, '../../../misc', bannerFile);
fs.readFile(bannerFile, 'utf8', (err, banner) => {
if(err) {
return cb('You have reached an ENiGMA½ Gopher server!');
const requestedPath = selectorMatch[1];
let path = this.resolveContentPath(requestedPath);
if (!path) {
return cb('Not found');
}
fs.stat(path, (err, stats) => {
if (err) {
return cb('Not found');
}
banner = splitTextAtTerms(banner).map(l => this.makeItem(ItemTypes.InfoMessage, l)).join('');
banner += this.makeItem(ItemTypes.SubMenu, 'Public Message Area', '/msgarea');
return cb(banner);
let isGopherMap = false;
if (stats.isDirectory()) {
path = paths.join(path, 'gophermap');
isGopherMap = true;
}
fs.readFile(path, isGopherMap ? 'utf8' : null, (err, content) => {
if (err) {
let content = 'You have reached an ENiGMA½ Gopher server!\r\n';
content += this.makeItem(ItemTypes.SubMenu, 'Public Message Area', '/msgarea');
return cb(content);
}
if (isGopherMap) {
// Convert any UNIX style LF's to DOS CRLF's
content = content.replace(/\r?\n/g, '\r\n');
// variable support
content = content
.replace(/{publicHostname}/g, this.publicHostname)
.replace(/{publicPort}/g, this.publicPort);
}
return cb(content);
});
});
}
resolveContentPath(requestPath) {
const staticRoot = _.get(Config(), 'contentServers.gopher.staticRoot');
const path = paths.resolve(staticRoot, `.${requestPath}`);
if (path.startsWith(staticRoot)) {
return path;
}
}
notFoundGenerator(selector, cb) {
this.log.debug( { selector }, 'Serving not found content');
return cb('Not found');