master
Dave Winer 10 years ago
parent 2afb640c24
commit 548caaee5c

@ -1,459 +1,518 @@
var myVersion = "0.42", myProductName = "pagePark"; var myVersion = "0.45", myProductName = "pagePark";
//The MIT License (MIT) //The MIT License (MIT)
//Copyright (c) 2014 Dave Winer //Copyright (c) 2014 Dave Winer
//Permission is hereby granted, free of charge, to any person obtaining a copy //Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal //of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights //in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is //copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions: //furnished to do so, subject to the following conditions:
//The above copyright notice and this permission notice shall be included in all //The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software. //copies or substantial portions of the Software.
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE. //SOFTWARE.
var fs = require ("fs"); var fs = require ("fs");
var request = require ("request"); var request = require ("request");
var urlpack = require ("url"); var urlpack = require ("url");
var http = require ("http"); var http = require ("http");
var marked = require ("marked"); var marked = require ("marked");
var dns = require ("dns");
var pageParkPrefs = {
myPort: 80, var pageParkPrefs = {
indexFilename: "index" myPort: 80,
}; indexFilename: "index"
var fnamePrefs = "prefs/prefs.json"; };
var fnamePrefs = "prefs/prefs.json";
var pageParkStats = {
ctStarts: 0, var pageParkStats = {
whenLastStart: new Date (0) ctStarts: 0,
}; whenLastStart: new Date (0),
var fnameStats = "prefs/stats.json"; ctHits: 0, ctHitsToday: 0,
whenLastHit: new Date (0),
var domainsPath = "domains/"; hitsByDomain: {}
};
var mdTemplatePath = "prefs/mdTemplate.txt"; var fnameStats = "prefs/stats.json", flStatsDirty = false;
var urlDefaultTemplate = "http://fargo.io/code/noderunner/defaultmarkdowntemplate.txt";
var domainsPath = "domains/";
//routines from utils.js, fs.js
function getBoolean (val) { var mdTemplatePath = "prefs/mdTemplate.txt";
switch (typeof (val)) { var urlDefaultTemplate = "http://fargo.io/code/pagepark/defaultmarkdowntemplate.txt";
case "string":
if (val.toLowerCase () == "true") { //routines from utils.js, fs.js
return (true); function getBoolean (val) {
} switch (typeof (val)) {
break; case "string":
case "boolean": if (val.toLowerCase () == "true") {
return (val); return (true);
break; }
case "number": break;
if (val != 0) { case "boolean":
return (true); return (val);
} break;
break; case "number":
} if (val != 0) {
return (false); return (true);
} }
function isAlpha (ch) { break;
return (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))); }
} return (false);
function isNumeric (ch) { }
return ((ch >= '0') && (ch <= '9')); function isAlpha (ch) {
} return (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')));
function jsonStringify (jstruct) { }
return (JSON.stringify (jstruct, undefined, 4)); function isNumeric (ch) {
} return ((ch >= '0') && (ch <= '9'));
function secondsSince (when) { }
var now = new Date (); function jsonStringify (jstruct) {
when = new Date (when); return (JSON.stringify (jstruct, undefined, 4));
return ((now - when) / 1000); }
} function secondsSince (when) {
function endsWith (s, possibleEnding, flUnicase) { var now = new Date ();
if ((s == undefined) || (s.length == 0)) { when = new Date (when);
return (false); return ((now - when) / 1000);
} }
var ixstring = s.length - 1; function sameDay (d1, d2) { //returns true if the two dates are on the same day
if (flUnicase == undefined) { d1 = new Date (d1);
flUnicase = true; d2 = new Date (d2);
} return ((d1.getFullYear () == d2.getFullYear ()) && (d1.getMonth () == d2.getMonth ()) && (d1.getDate () == d2.getDate ()));
if (flUnicase) { }
for (var i = possibleEnding.length - 1; i >= 0; i--) { function endsWith (s, possibleEnding, flUnicase) {
if (s [ixstring--].toLowerCase () != possibleEnding [i].toLowerCase ()) { if ((s == undefined) || (s.length == 0)) {
return (false); return (false);
} }
} var ixstring = s.length - 1;
} if (flUnicase == undefined) {
else { flUnicase = true;
for (var i = possibleEnding.length - 1; i >= 0; i--) { }
if (s [ixstring--] != possibleEnding [i]) { if (flUnicase) {
return (false); for (var i = possibleEnding.length - 1; i >= 0; i--) {
} if (s [ixstring--].toLowerCase () != possibleEnding [i].toLowerCase ()) {
} return (false);
} }
return (true); }
} }
function stringContains (s, whatItMightContain, flUnicase) { else {
if (flUnicase == undefined) { for (var i = possibleEnding.length - 1; i >= 0; i--) {
flUnicase = true; if (s [ixstring--] != possibleEnding [i]) {
} return (false);
if (flUnicase) { }
s = s.toLowerCase (); }
whatItMightContain = whatItMightContain.toLowerCase (); }
} return (true);
return (s.indexOf (whatItMightContain) != -1); }
} function stringContains (s, whatItMightContain, flUnicase) {
function stringCountFields (s, chdelim) { if (flUnicase == undefined) {
var ct = 1; flUnicase = true;
if (s.length == 0) { }
return (0); if (flUnicase) {
} s = s.toLowerCase ();
for (var i = 0; i < s.length; i++) { whatItMightContain = whatItMightContain.toLowerCase ();
if (s [i] == chdelim) { }
ct++; return (s.indexOf (whatItMightContain) != -1);
} }
} function stringCountFields (s, chdelim) {
return (ct) var ct = 1;
} if (s.length == 0) {
function stringNthField (s, chdelim, n) { return (0);
var splits = s.split (chdelim); }
if (splits.length >= n) { for (var i = 0; i < s.length; i++) {
return splits [n-1]; if (s [i] == chdelim) {
} ct++;
return (""); }
} }
function stringLastField (s, chdelim) { return (ct)
var ct = stringCountFields (s, chdelim); }
if (ct == 0) { //8/31/14 by DW function stringNthField (s, chdelim, n) {
return (s); var splits = s.split (chdelim);
} if (splits.length >= n) {
return (stringNthField (s, chdelim, ct)); return splits [n-1];
} }
function multipleReplaceAll (s, adrTable, flCaseSensitive, startCharacters, endCharacters) { return ("");
if(flCaseSensitive===undefined){ }
flCaseSensitive = false; function stringLastField (s, chdelim) {
} var ct = stringCountFields (s, chdelim);
if(startCharacters===undefined){ if (ct == 0) { //8/31/14 by DW
startCharacters=""; return (s);
} }
if(endCharacters===undefined){ return (stringNthField (s, chdelim, ct));
endCharacters=""; }
} function multipleReplaceAll (s, adrTable, flCaseSensitive, startCharacters, endCharacters) {
for( var item in adrTable){ if(flCaseSensitive===undefined){
var replacementValue = adrTable[item]; flCaseSensitive = false;
var regularExpressionModifier = "g"; }
if(!flCaseSensitive){ if(startCharacters===undefined){
regularExpressionModifier = "gi"; startCharacters="";
} }
var regularExpressionString = (startCharacters+item+endCharacters).replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); if(endCharacters===undefined){
var regularExpression = new RegExp(regularExpressionString, regularExpressionModifier); endCharacters="";
s = s.replace(regularExpression, replacementValue); }
} for( var item in adrTable){
return s; var replacementValue = adrTable[item];
} var regularExpressionModifier = "g";
function httpExt2MIME (ext) { //12/24/14 by DW if(!flCaseSensitive){
var lowerext = ext.toLowerCase (); regularExpressionModifier = "gi";
var map = { }
"au": "audio/basic", var regularExpressionString = (startCharacters+item+endCharacters).replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
"avi": "application/x-msvideo", var regularExpression = new RegExp(regularExpressionString, regularExpressionModifier);
"bin": "application/x-macbinary", s = s.replace(regularExpression, replacementValue);
"css": "text/css", }
"dcr": "application/x-director", return s;
"dir": "application/x-director", }
"dll": "application/octet-stream", function httpExt2MIME (ext) { //12/24/14 by DW
"doc": "application/msword", var lowerext = ext.toLowerCase ();
"dtd": "text/dtd", var map = {
"dxr": "application/x-director", "au": "audio/basic",
"exe": "application/octet-stream", "avi": "application/x-msvideo",
"fatp": "text/html", "bin": "application/x-macbinary",
"ftsc": "text/html", "css": "text/css",
"fttb": "text/html", "dcr": "application/x-director",
"gif": "image/gif", "dir": "application/x-director",
"gz": "application/x-gzip", "dll": "application/octet-stream",
"hqx": "application/mac-binhex40", "doc": "application/msword",
"htm": "text/html", "dtd": "text/dtd",
"html": "text/html", "dxr": "application/x-director",
"jpeg": "image/jpeg", "exe": "application/octet-stream",
"jpg": "image/jpeg", "fatp": "text/html",
"js": "application/javascript", "ftsc": "text/html",
"mid": "audio/x-midi", "fttb": "text/html",
"midi": "audio/x-midi", "gif": "image/gif",
"mov": "video/quicktime", "gz": "application/x-gzip",
"mp3": "audio/mpeg", "hqx": "application/mac-binhex40",
"pdf": "application/pdf", "htm": "text/html",
"png": "image/png", "html": "text/html",
"ppt": "application/mspowerpoint", "jpeg": "image/jpeg",
"ps": "application/postscript", "jpg": "image/jpeg",
"ra": "audio/x-pn-realaudio", "js": "application/javascript",
"ram": "audio/x-pn-realaudio", "mid": "audio/x-midi",
"sit": "application/x-stuffit", "midi": "audio/x-midi",
"sys": "application/octet-stream", "mov": "video/quicktime",
"tar": "application/x-tar", "mp3": "audio/mpeg",
"text": "text/plain", "pdf": "application/pdf",
"txt": "text/plain", "png": "image/png",
"wav": "audio/x-wav", "ppt": "application/mspowerpoint",
"wrl": "x-world/x-vrml", "ps": "application/postscript",
"xml": "text/xml", "ra": "audio/x-pn-realaudio",
"zip": "application/zip" "ram": "audio/x-pn-realaudio",
}; "sit": "application/x-stuffit",
for (x in map) { "sys": "application/octet-stream",
if (x.toLowerCase () == lowerext) { "tar": "application/x-tar",
return (map [x]); "text": "text/plain",
} "txt": "text/plain",
} "wav": "audio/x-wav",
return ("text/plain"); "wrl": "x-world/x-vrml",
} "xml": "text/xml",
function httpReadUrl (url, callback) { "zip": "application/zip"
request (url, function (error, response, body) { };
if (!error && (response.statusCode == 200)) { for (x in map) {
callback (body) if (x.toLowerCase () == lowerext) {
} return (map [x]);
}); }
} }
function fsSureFilePath (path, callback) { return ("text/plain");
var splits = path.split ("/"), path = ""; }
if (splits.length > 0) { function httpReadUrl (url, callback) {
function doLevel (levelnum) { request (url, function (error, response, body) {
if (levelnum < (splits.length - 1)) { if (!error && (response.statusCode == 200)) {
path += splits [levelnum] + "/"; callback (body)
fs.exists (path, function (flExists) { }
if (flExists) { });
doLevel (levelnum + 1); }
} function fsSureFilePath (path, callback) {
else { var splits = path.split ("/"), path = "";
fs.mkdir (path, undefined, function () { if (splits.length > 0) {
doLevel (levelnum + 1); function doLevel (levelnum) {
}); if (levelnum < (splits.length - 1)) {
} path += splits [levelnum] + "/";
}); fs.exists (path, function (flExists) {
} if (flExists) {
else { doLevel (levelnum + 1);
if (callback != undefined) { }
callback (); else {
} fs.mkdir (path, undefined, function () {
} doLevel (levelnum + 1);
} });
doLevel (0); }
} });
else { }
if (callback != undefined) { else {
callback (); if (callback != undefined) {
} callback ();
} }
} }
}
function writeStats (fname, stats) { doLevel (0);
fsSureFilePath (fname, function () { }
fs.writeFile (fname, jsonStringify (stats), function (err) { else {
if (err) { if (callback != undefined) {
console.log ("writeStats: error == " + err.message); callback ();
} }
}); }
}); }
}
function readStats (f, stats, callback) { function writeStats (fname, stats) {
fs.exists (f, function (flExists) { fsSureFilePath (fname, function () {
if (flExists) { fs.writeFile (fname, jsonStringify (stats), function (err) {
fs.readFile (f, function (err, data) { if (err) {
if (err) { console.log ("writeStats: error == " + err.message);
console.log ("readStats: error reading file " + f + " == " + err.message) }
} });
else { });
var storedStats = JSON.parse (data.toString ()); }
for (var x in storedStats) { function readStats (f, stats, callback) {
stats [x] = storedStats [x]; fs.exists (f, function (flExists) {
} if (flExists) {
writeStats (f, stats); fs.readFile (f, function (err, data) {
} if (err) {
if (callback != undefined) { console.log ("readStats: error reading file " + f + " == " + err.message)
callback (); }
} else {
}); var storedStats = JSON.parse (data.toString ());
} for (var x in storedStats) {
else { stats [x] = storedStats [x];
writeStats (f, stats); }
if (callback != undefined) { writeStats (f, stats);
callback (); }
} if (callback != undefined) {
} callback ();
}); }
} });
function getMarkdownTemplate (callback) { }
fs.readFile (mdTemplatePath, function (err, data) { else {
if (err) { writeStats (f, stats);
httpReadUrl (urlDefaultTemplate, function (s) { if (callback != undefined) {
fs.writeFile (mdTemplatePath, s, function (err) { callback ();
if (callback != undefined) { }
callback (s); }
} });
}); }
}); function getMarkdownTemplate (callback) {
} fs.readFile (mdTemplatePath, function (err, data) {
else { if (err) {
if (callback != undefined) { httpReadUrl (urlDefaultTemplate, function (s) {
callback (data.toString ()); fs.writeFile (mdTemplatePath, s, function (err) {
} if (callback != undefined) {
} callback (s);
}); }
} });
function checkPathForIllegalChars (path) { });
function isIllegal (ch) { }
if (isAlpha (ch) || isNumeric (ch)) { else {
return (false); if (callback != undefined) {
} callback (data.toString ());
switch (ch) { }
case "/": case "_": case "-": case ".": case " ": }
return (false); });
} }
return (true); function checkPathForIllegalChars (path) {
} function isIllegal (ch) {
for (var i = 0; i < path.length; i++) { if (isAlpha (ch) || isNumeric (ch)) {
if (isIllegal (path [i])) { return (false);
return (false); }
} switch (ch) {
} case "/": case "_": case "-": case ".": case " ":
if (stringContains (path, "./")) { return (false);
return (false); }
} return (true);
return (true); }
} for (var i = 0; i < path.length; i++) {
if (isIllegal (path [i])) {
function handleHttpRequest (httpRequest, httpResponse) { return (false);
function return404 () { }
httpResponse.writeHead (404, {"Content-Type": "text/plain"}); }
httpResponse.end ("The file was not found."); if (stringContains (path, "./")) {
} return (false);
}
function findIndexFile (folder, callback) { return (true);
fs.readdir (folder, function (err, list) { }
for (var i = 0; i < list.length; i++) {
var fname = list [i]; function everySecond () {
if (stringCountFields (fname, ".") == 2) { //something like xxx.yyy if (flStatsDirty) {
if (stringNthField (fname, ".", 1).toLowerCase () == pageParkPrefs.indexFilename) { //something like index.wtf writeStats (fnameStats, pageParkStats);
callback (folder + fname); flStatsDirty = false;
return; }
} }
}
} function handleHttpRequest (httpRequest, httpResponse) {
return404 (); function return404 () {
}); httpResponse.writeHead (404, {"Content-Type": "text/plain"});
} httpResponse.end ("The file was not found.");
function serveFile (f) { }
fs.readFile (f, function (err, data) {
if (err) { function findIndexFile (folder, callback) {
return404 (); fs.readdir (folder, function (err, list) {
} for (var i = 0; i < list.length; i++) {
else { var fname = list [i];
var ext = stringLastField (f, ".").toLowerCase (), type = httpExt2MIME (ext); if (stringCountFields (fname, ".") == 2) { //something like xxx.yyy
switch (ext) { if (stringNthField (fname, ".", 1).toLowerCase () == pageParkPrefs.indexFilename) { //something like index.wtf
case "js": callback (folder + fname);
try { return;
var val = eval (data.toString ()); }
httpResponse.writeHead (200, {"Content-Type": "text/html"}); }
httpResponse.end (val.toString ()); }
} return404 ();
catch (err) { });
httpResponse.writeHead (500, {"Content-Type": "text/plain"}); }
httpResponse.end ("Error running " + parsedUrl.pathname + ": \"" + err.message + "\""); function serveFile (f) {
} fs.readFile (f, function (err, data) {
break; if (err) {
case "md": return404 ();
getMarkdownTemplate (function (theTemplate) { }
var mdtext = data.toString (), pagetable = new Object (); else {
pagetable.bodytext = marked (mdtext); var ext = stringLastField (f, ".").toLowerCase (), type = httpExt2MIME (ext);
pagetable.title = stringLastField (f, "/"); switch (ext) {
var s = multipleReplaceAll (theTemplate, pagetable, false, "[%", "%]"); case "js":
httpResponse.writeHead (200, {"Content-Type": "text/html"}); try {
httpResponse.end (s); var val = eval (data.toString ());
}); httpResponse.writeHead (200, {"Content-Type": "text/html"});
break; httpResponse.end (val.toString ());
default: }
httpResponse.writeHead (200, {"Content-Type": type}); catch (err) {
httpResponse.end (data); httpResponse.writeHead (500, {"Content-Type": "text/plain"});
break; httpResponse.end ("Error running " + parsedUrl.pathname + ": \"" + err.message + "\"");
} }
} break;
}); case "md":
} getMarkdownTemplate (function (theTemplate) {
var mdtext = data.toString (), pagetable = new Object ();
try { pagetable.bodytext = marked (mdtext);
var parsedUrl = urlpack.parse (httpRequest.url, true), host, port; pagetable.title = stringLastField (f, "/");
var lowerpath = parsedUrl.pathname.toLowerCase (), now = new Date (); var s = multipleReplaceAll (theTemplate, pagetable, false, "[%", "%]");
//set host, port httpResponse.writeHead (200, {"Content-Type": "text/html"});
host = httpRequest.headers.host; httpResponse.end (s);
if (stringContains (host, ":")) { });
port = stringNthField (host, ":", 2); break;
host = stringNthField (host, ":", 1); default:
} httpResponse.writeHead (200, {"Content-Type": type});
else { httpResponse.end (data);
port = 80; break;
} }
console.log (now.toLocaleTimeString () + " " + httpRequest.method + " " + host + ":" + port + " " + lowerpath); }
switch (lowerpath) { });
case "/version": }
httpResponse.writeHead (200, {"Content-Type": "text/plain"});
httpResponse.end (myVersion); try {
break; var parsedUrl = urlpack.parse (httpRequest.url, true), host, lowerhost, port, referrer;
case "/now": var lowerpath = parsedUrl.pathname.toLowerCase (), now = new Date ();
httpResponse.writeHead (200, {"Content-Type": "text/plain"}); //set host, port
httpResponse.end (now.toString ()); host = httpRequest.headers.host;
break; if (stringContains (host, ":")) {
default: //see if it's a path in the domains folder, if not 404 port = stringNthField (host, ":", 2);
var f = domainsPath + host + parsedUrl.pathname; host = stringNthField (host, ":", 1);
if (checkPathForIllegalChars (f)) { }
fsSureFilePath (f, function () { //make sure domains folder exists else {
fs.stat (f, function (err, stats) { port = 80;
if (err) { }
return404 (); lowerhost = host.toLowerCase ();
} //set referrer
else { referrer = httpRequest.headers.referer;
if (stats.isDirectory ()) { if (referrer == undefined) {
if (!endsWith (f, "/")) { referrer = "";
f += "/"; }
}
findIndexFile (f, function (findex) { //stats
serveFile (findex); //hits by domain
}); if (pageParkStats.hitsByDomain [lowerhost] == undefined) {
} pageParkStats.hitsByDomain [lowerhost] = 1;
else { }
serveFile (f); else {
} pageParkStats.hitsByDomain [lowerhost]++;
} }
}); //hits today
}); if (!sameDay (now, pageParkStats.whenLastHit)) { //day rollover
} pageParkStats.ctHitsToday = 0;
else { }
httpResponse.writeHead (500, {"Content-Type": "text/plain"}); pageParkStats.ctHits++;
httpResponse.end ("The file name contains illegal characters."); pageParkStats.ctHitsToday++;
} pageParkStats.whenLastHit = now;
break; flStatsDirty = true;
}
} //log the request
catch (tryError) { dns.reverse (httpRequest.connection.remoteAddress, function (err, domains) {
httpResponse.writeHead (500, {"Content-Type": "text/plain"}); var client = httpRequest.connection.remoteAddress;
httpResponse.end (tryError.message); if (!err) {
} if (domains.length > 0) {
} client = domains [0];
}
function startup () { }
readStats (fnamePrefs, pageParkPrefs, function () { console.log (now.toLocaleTimeString () + " " + httpRequest.method + " " + host + ":" + port + " " + lowerpath + " " + referrer + " " + client);
readStats (fnameStats, pageParkStats, function () { });
var now = new Date ();
console.log (myProductName + " v" + myVersion + "."); switch (lowerpath) {
pageParkStats.ctStarts++; case "/version":
pageParkStats.whenLastStart = now; httpResponse.writeHead (200, {"Content-Type": "text/plain"});
writeStats (fnameStats, pageParkStats); httpResponse.end (myVersion);
http.createServer (handleHttpRequest).listen (pageParkPrefs.myPort); break;
}); case "/now":
}); httpResponse.writeHead (200, {"Content-Type": "text/plain"});
} httpResponse.end (now.toString ());
startup (); break;
case "/status":
var status = {
prefs: pageParkPrefs,
status: pageParkStats
}
httpResponse.writeHead (200, {"Content-Type": "text/plain"});
httpResponse.end (jsonStringify (status));
break;
default: //see if it's a path in the domains folder, if not 404
var f = domainsPath + host + parsedUrl.pathname;
if (checkPathForIllegalChars (f)) {
fsSureFilePath (domainsPath, function () { //make sure domains folder exists
fs.stat (f, function (err, stats) {
if (err) {
return404 ();
}
else {
if (stats.isDirectory ()) {
if (!endsWith (f, "/")) {
f += "/";
}
findIndexFile (f, function (findex) {
serveFile (findex);
});
}
else {
serveFile (f);
}
}
});
});
}
else {
httpResponse.writeHead (500, {"Content-Type": "text/plain"});
httpResponse.end ("The file name contains illegal characters.");
}
break;
}
}
catch (tryError) {
httpResponse.writeHead (500, {"Content-Type": "text/plain"});
httpResponse.end (tryError.message);
}
}
function startup () {
readStats (fnamePrefs, pageParkPrefs, function () {
readStats (fnameStats, pageParkStats, function () {
var now = new Date ();
console.log (myProductName + " v" + myVersion + ".");
pageParkStats.ctStarts++;
pageParkStats.whenLastStart = now;
flStatsDirty = true;
http.createServer (handleHttpRequest).listen (pageParkPrefs.myPort);
setInterval (everySecond, 1000);
});
});
}
startup ();

Loading…
Cancel
Save