2024-08-23 19:58:15 +02:00
const http = require ( "http" ) ;
const fs = require ( "fs" ) ;
2024-08-23 20:43:09 +02:00
//const generateErrorStack = require("./utils/generateErrorStack.js");
2024-08-23 19:58:15 +02:00
const getOS = require ( "./utils/getOS.js" ) ;
const svrjsInfo = require ( "../svrjs.json" ) ;
const version = svrjsInfo . version ;
//const parseURL = require("./utils/urlParser.js");
//const fixNodeMojibakeURL = require("./utils/urlMojibakeFixer.js");
2024-08-23 21:58:26 +02:00
let inspector = undefined ;
try {
inspector = require ( "inspector" ) ;
} catch ( err ) {
// Don't use inspector
}
2024-08-23 19:58:15 +02:00
// Create log, mods and temp directories, if they don't exist.
if ( ! fs . existsSync ( _ _dirname + "/log" ) ) fs . mkdirSync ( _ _dirname + "/log" ) ;
if ( ! fs . existsSync ( _ _dirname + "/mods" ) ) fs . mkdirSync ( _ _dirname + "/mods" ) ;
if ( ! fs . existsSync ( _ _dirname + "/temp" ) ) fs . mkdirSync ( _ _dirname + "/temp" ) ;
2024-08-24 16:54:28 +02:00
// TODO: process.singleThreaded flag
process . singleThreaded = true ;
const cluster = require ( "./utils/clusterBunShim.js" ) ; // Cluster module with shim for Bun
2024-08-24 16:55:44 +02:00
process . serverConfig = { } ;
// TODO: configuration from config.json
if ( process . serverConfig . users === undefined ) process . serverConfig . users = [ ] ;
if ( process . serverConfig . secure ) {
if ( process . serverConfig . key === undefined ) process . serverConfig . key = "cert/key.key" ;
if ( process . serverConfig . cert === undefined ) process . serverConfig . cert = "cert/cert.crt" ;
if ( process . serverConfig . sport === undefined ) process . serverConfig . sport = 443 ;
if ( process . serverConfig . spubport === undefined ) process . serverConfig . spubport = 443 ;
if ( process . serverConfig . sni === undefined ) process . serverConfig . sni = { } ;
if ( process . serverConfig . enableOCSPStapling === undefined ) process . serverConfig . enableOCSPStapling = false ;
}
if ( process . serverConfig . port === undefined ) process . serverConfig . port = 80 ;
if ( process . serverConfig . pubport === undefined ) process . serverConfig . pubport = 80 ;
if ( process . serverConfig . domain === undefined && process . serverConfig . domian !== undefined ) process . serverConfig . domain = process . serverConfig . domian ;
delete process . serverConfig . domian ;
if ( process . serverConfig . page404 === undefined ) process . serverConfig . page404 = "404.html" ;
//process.serverConfig.timestamp = timestamp; //TODO
//process.serverConfig.blacklist = blocklist.raw; //TODO
if ( process . serverConfig . nonStandardCodes === undefined ) process . serverConfig . nonStandardCodes = [ ] ;
if ( process . serverConfig . enableCompression === undefined ) process . serverConfig . enableCompression = true ;
if ( process . serverConfig . customHeaders === undefined ) process . serverConfig . customHeaders = { } ;
if ( process . serverConfig . enableHTTP2 === undefined ) process . serverConfig . enableHTTP2 = false ;
if ( process . serverConfig . enableLogging === undefined ) process . serverConfig . enableLogging = true ;
if ( process . serverConfig . enableDirectoryListing === undefined ) process . serverConfig . enableDirectoryListing = true ;
if ( process . serverConfig . enableDirectoryListingWithDefaultHead === undefined ) process . serverConfig . enableDirectoryListingWithDefaultHead = false ;
if ( process . serverConfig . serverAdministratorEmail === undefined ) process . serverConfig . serverAdministratorEmail = "[no contact information]" ;
if ( process . serverConfig . stackHidden === undefined ) process . serverConfig . stackHidden = false ;
if ( process . serverConfig . enableRemoteLogBrowsing === undefined ) process . serverConfig . enableRemoteLogBrowsing = false ;
if ( process . serverConfig . exposeServerVersion === undefined ) process . serverConfig . exposeServerVersion = true ;
if ( process . serverConfig . disableServerSideScriptExpose === undefined ) process . serverConfig . disableServerSideScriptExpose = true ;
if ( process . serverConfig . allowStatus === undefined ) process . serverConfig . allowStatus = true ;
if ( process . serverConfig . rewriteMap === undefined ) process . serverConfig . rewriteMap = [ ] ;
if ( process . serverConfig . dontCompress === undefined ) process . serverConfig . dontCompress = [ "/.*\\.ipxe$/" , "/.*\\.(?:jpe?g|png|bmp|tiff|jfif|gif|webp)$/" , "/.*\\.(?:[id]mg|iso|flp)$/" , "/.*\\.(?:zip|rar|bz2|[gb7x]z|lzma|tar)$/" , "/.*\\.(?:mp[34]|mov|wm[av]|avi|webm|og[gv]|mk[va])$/" ] ;
if ( process . serverConfig . enableIPSpoofing === undefined ) process . serverConfig . enableIPSpoofing = false ;
if ( process . serverConfig . secure === undefined ) process . serverConfig . secure = false ;
if ( process . serverConfig . disableNonEncryptedServer === undefined ) process . serverConfig . disableNonEncryptedServer = false ;
if ( process . serverConfig . disableToHTTPSRedirect === undefined ) process . serverConfig . disableToHTTPSRedirect = false ;
if ( process . serverConfig . enableETag === undefined ) process . serverConfig . enableETag = true ;
if ( process . serverConfig . disableUnusedWorkerTermination === undefined ) process . serverConfig . disableUnusedWorkerTermination = false ;
if ( process . serverConfig . rewriteDirtyURLs === undefined ) process . serverConfig . rewriteDirtyURLs = false ;
if ( process . serverConfig . errorPages === undefined ) process . serverConfig . errorPages = [ ] ;
if ( process . serverConfig . useWebRootServerSideScript === undefined ) process . serverConfig . useWebRootServerSideScript = true ;
if ( process . serverConfig . exposeModsInErrorPages === undefined ) process . serverConfig . exposeModsInErrorPages = true ;
if ( process . serverConfig . disableTrailingSlashRedirects === undefined ) process . serverConfig . disableTrailingSlashRedirects = false ;
if ( process . serverConfig . environmentVariables === undefined ) process . serverConfig . environmentVariables = { } ;
if ( process . serverConfig . wwwrootPostfixesVHost === undefined ) process . serverConfig . wwwrootPostfixesVHost = [ ] ;
if ( process . serverConfig . wwwrootPostfixPrefixesVHost === undefined ) process . serverConfig . wwwrootPostfixPrefixesVHost = [ ] ;
if ( process . serverConfig . allowDoubleSlashes === undefined ) process . serverConfig . allowDoubleSlashes = false ;
if ( process . serverConfig . allowPostfixDoubleSlashes === undefined ) process . serverConfig . allowPostfixDoubleSlashes = false ;
if ( process . serverConfig . optOutOfStatisticsServer === undefined ) process . serverConfig . optOutOfStatisticsServer = false ;
process . serverConfig . version = version ; // Compatiblity for very old SVR.JS mods
2024-08-23 19:58:15 +02:00
const serverconsoleConstructor = require ( "./utils/serverconsole.js" ) ;
2024-08-23 21:58:26 +02:00
let inspectorURL = undefined ;
try {
if ( inspector ) {
inspectorURL = inspector . url ( ) ;
}
} catch ( err ) {
// Failed to get inspector URL
}
if ( ! process . stdout . isTTY && ! inspectorURL ) {
// When stdout is not a terminal and not attached to an Node.JS inspector, disable it to improve performance of SVR.JS
console . log = function ( ) { } ;
process . stdout . write = function ( ) { } ;
process . stdout . _write = function ( ) { } ;
process . stdout . _writev = function ( ) { } ;
}
2024-08-23 21:33:26 +02:00
var wwwrootError = null ;
try {
2024-08-24 16:55:44 +02:00
if ( cluster . isPrimary || cluster . isPrimary === undefined ) process . chdir ( process . serverConfig . wwwroot != undefined ? process . serverConfig . wwwroot : _ _dirname ) ;
2024-08-23 21:33:26 +02:00
} catch ( err ) {
wwwrootError = err ;
}
2024-08-23 20:43:09 +02:00
2024-08-24 16:55:44 +02:00
const serverconsole = serverconsoleConstructor ( process . serverConfig . enableLogging ) ;
2024-08-23 20:43:09 +02:00
let middleware = [
2024-08-23 21:25:23 +02:00
require ( "./middleware/core.js" ) ,
2024-08-23 22:13:58 +02:00
require ( "./middleware/urlSanitizer.js" ) ,
2024-08-24 08:02:11 +02:00
require ( "./middleware/redirects.js" ) ,
2024-08-24 08:22:49 +02:00
require ( "./middleware/webRootPostfixes.js" ) ,
require ( "./middleware/rewriteURL.js" )
2024-08-23 20:43:09 +02:00
] ;
function addMiddleware ( mw ) {
middleware . push ( mw ) ;
2024-08-23 19:58:15 +02:00
}
function requestHandler ( req , res ) {
let reqIdInt = Math . floor ( Math . random ( ) * 16777216 ) ;
if ( reqIdInt == 16777216 ) reqIdInt = 0 ;
const reqId = "0" . repeat ( 6 - reqIdInt . toString ( 16 ) . length ) + reqIdInt . toString ( 16 ) ;
// SVR.JS log facilities
const logFacilities = {
climessage : ( msg ) => serverconsole . climessage ( msg , reqId ) ,
reqmessage : ( msg ) => serverconsole . reqmessage ( msg , reqId ) ,
resmessage : ( msg ) => serverconsole . resmessage ( msg , reqId ) ,
errmessage : ( msg ) => serverconsole . errmessage ( msg , reqId ) ,
locerrmessage : ( msg ) => serverconsole . locerrmessage ( msg , reqId ) ,
locwarnmessage : ( msg ) => serverconsole . locwarnmessage ( msg , reqId ) ,
locmessage : ( msg ) => serverconsole . locmessage ( msg , reqId )
} ;
2024-08-23 20:43:09 +02:00
// SVR.JS configuration object (modified)
2024-08-24 16:55:44 +02:00
const config = Object . assign ( process . serverConfig ) ;
2024-08-23 19:58:15 +02:00
2024-08-23 20:43:09 +02:00
let index = 0 ;
2024-08-23 19:58:15 +02:00
2024-08-23 20:43:09 +02:00
// Call the next middleware function
const next = ( ) => {
const currentMiddleware = middleware [ index ++ ] ;
if ( currentMiddleware ) {
try {
currentMiddleware ( req , res , logFacilities , config , next ) ;
} catch ( err ) {
2024-08-23 21:25:23 +02:00
if ( res . error ) res . error ( 500 , err ) ;
2024-08-23 19:58:15 +02:00
else {
2024-08-23 21:25:23 +02:00
logFacilities . errmessage ( "There was an error while processing the request!" ) ;
logFacilities . errmessage ( "Stack:" ) ;
logFacilities . errmessage ( err . stack ) ;
2024-08-23 20:43:09 +02:00
res . writeHead ( 500 , "Internal Server Error" , {
Server : ( config . exposeServerVersion ? "SVR.JS/" + version + " (" + getOS ( ) + "; " + ( process . isBun ? ( "Bun/v" + process . versions . bun + "; like Node.JS/" + process . version ) : ( "Node.JS/" + process . version ) ) + ")" : "SVR.JS" )
} ) ;
res . end ( "Error while executing the request handler" ) ;
2024-08-23 19:58:15 +02:00
}
}
2024-08-23 20:43:09 +02:00
} else {
if ( res . error ) res . error ( 404 ) ;
else {
res . writeHead ( 404 , "Not Found" , {
Server : ( config . exposeServerVersion ? "SVR.JS/" + version + " (" + getOS ( ) + "; " + ( process . isBun ? ( "Bun/v" + process . versions . bun + "; like Node.JS/" + process . version ) : ( "Node.JS/" + process . version ) ) + ")" : "SVR.JS" )
2024-08-23 19:58:15 +02:00
} ) ;
2024-08-23 20:43:09 +02:00
res . end ( "Request handler missing" ) ;
2024-08-23 19:58:15 +02:00
}
}
}
2024-08-23 20:43:09 +02:00
// Handle middleware
next ( ) ;
2024-08-23 19:58:15 +02:00
}
// Create HTTP server
http . createServer ( requestHandler ) . listen ( 3000 ) ;
2024-08-23 21:34:58 +02:00
2024-08-23 21:35:58 +02:00
if ( wwwrootError ) throw wwwrootError ;