uplink-gopher/index.js
2022-01-07 22:36:22 +01:00

123 lines
5.9 KiB
JavaScript

const net = require('net');
const fs = require('fs');
const url = require('url');
const settings_json = fs.readFileSync('settings.json');
const settings = JSON.parse(settings_json);
function getPage(path, next) {
var index;
fs.readFile(settings.root + path, 'utf8', function(err, data) {
if(err) {
console.log('ERROR: ' + err);
return;
} else {
index = data.split(/\r?\n/);
next(index);
}
});
}
function fileExist(path) {
return fs.existsSync(settings.root + path);
}
function isDirectory(path) {
return fs.statSync(settings.root + path).isDirectory();
}
const server = new net.createServer(function(c) {
//console.log('Server Connected');
c.on('end', function() {
//console.log('Server Disconnected');
});
c.on('data', function(data) {
var datetime = new Date();
if(data.toString().trim() == '') data = settings.index;
console.log(data);
data = decodeURIComponent(data.toString());
var gopherSelector = data.toString().trimEnd();
console.log('selector: <' + gopherSelector + '>');
var gopherItems = gopherSelector.split('\t');
console.log(gopherItems);
if(fileExist(gopherItems[0]) && (gopherItems[0].indexOf('..') == -1)) {
if(isDirectory(gopherItems[0])) {
if(gopherItems[0][gopherItems[0].length - 1] != '/') {
gopherItems[0] = gopherItems[0] + '/' + settings.index;
} else gopherItems[0] = gopherItems[0] + settings.index;
}
getPage(gopherItems[0], function(index) {
console.log(datetime.toISOString() + ' - ' + c.remoteAddress + ':' + c.remotePort + ' - <' + gopherItems[0] + '>');
for(var i = 0; i < index.length; i++) {
if(index[i].startsWith('=> ')) {
var selector = index[i];
selector = selector.replace('=>', '').trimStart();
var address = selector.split(' ');
selector = selector.replace(address[0], '').trimStart();
var server = 'noserver.host';
var path = 'nopath';
var protocol = 'gopher';
var type = '1';
var port = '70';
// gopher://uplink.si:1985/1index.gop
if(address[0].includes('://')) {
var myUrl = new url.URL(address[0]); // gopher://uplink.si:1985/1index.gop
protocol = myUrl.protocol; // gopher
if(protocol == 'gopher:') {
server = myUrl.hostname; // uplink.si
path = myUrl.pathname; // /1index.gop
path = path.substring(1, path.length); // 1index.gop
if(path.startsWith('/'))
path = path.substring(1, path.length - 1); // 1index.gop
type = path.substring(0, 1); // 1
path = path.substring(1, path.length - 1); // 1index.gop
if(type.trim() == '') type = '1'; //
if(path.startsWith('/'))
path = path.substring(1, path.length - 1); // 1index.gop
if(myUrl.port) port = myUrl.port; // 1985
c.write(type + selector + '\t' + path + '\t' + server + '\t' + port + '\t+\r\n');
} else if((protocol == 'http:') || (protocol == 'https:') || (protocol == 'gemini:')) {
type = 'h';
path = 'URL:' + address[0];
server = settings.domain;
port = settings.port;
c.write(type + selector + '\t' + path + '\t' + server + '\t' + port + '\r\n');
}
}
} else {
if(gopherItems[1] == '$') {
c.write('+INFO: i' + index[i] +
'\tfake.selector' +
'\tfake.serv' +
'\t70' +
'\t+\r\n' +
'+ADMIN:\r\n' +
' Admin: ' + settings.admin + '\r\n' +
' Mod-Date: Wed Jul 28 17:02:01 1993 <19930728170201>\r\n' +
'+VIEWS:\r\n' +
' Text/plain: <10k>\r\n' +
' application/postscript: <100k>\r\n' +
' Text/plain De_DE: <15k>\r\n' +
' application/MacWriteII: <45K>\r\n' +
'+ABSTRACT:\r\n' +
' This is a short (but multi-line) abstract about the\r\n' +
' item. Two or three lines ought to be enough\r\n');
} else {
c.write('i' + index[i] + '\tfake.selector\tfake.serv\t70\t+\r\n');
}
}
}
c.write('.\r\n');
c.end();
});
} else {
console.log(datetime.toISOString() + ' - ' + c.remoteAddress + ':' + c.remotePort + ' - <' + gopherItems[0] + '>' + ' - ERROR');
c.write('iError: ' + gopherItems[0] + ' not found.\terror.serv\terror.serv\t70\r\n.\r\n');
c.end();
}
});
});
server.listen(settings.listen_port, function() {
console.log('Server Bound');
});