2023-07-29 23:44:21 +02:00
var https = require ( "https" ) ;
var os = require ( "os" ) ;
var http = require ( "http" ) ;
var url = require ( "url" ) ;
var fs = require ( "fs" ) ;
var path = require ( "path" ) ;
2023-07-30 02:24:20 +02:00
var childProcess = require ( "child_process" ) ;
2023-08-27 09:16:58 +02:00
var readline = require ( "readline" ) ;
2023-07-29 23:44:21 +02:00
var version = "UNKNOWN" ;
try {
version = JSON . parse ( fs . readFileSync ( _ _dirname + "/mod.info" ) ) . version ;
2023-07-30 02:24:20 +02:00
} catch ( ex ) {
2023-08-01 23:37:53 +02:00
// Can't determine version
2023-07-29 23:44:21 +02:00
}
2023-12-31 21:25:10 +01:00
var configJSONS = { } ;
try {
configJSONS = JSON . parse ( fs . readFileSync ( _ _dirname + "/../../../config.json" ) ) ; // Read configuration JSON
} catch ( ex ) {
//RedBrick will not care about configJSONS in SVR.JS 3.x and newer
//SVR.JS 2.x and older will fail to start with broken configuration file anyway...
}
2023-08-01 23:37:53 +02:00
2023-11-23 22:45:17 +01:00
var exttointerpreteruser = { } ;
var scriptExts = [ ] ;
try {
exttointerpreteruser = JSON . parse ( fs . readFileSync ( _ _dirname + "/../../../redbrick-interpreters.json" ) ) ;
} catch ( ex ) {
}
try {
scriptExts = JSON . parse ( fs . readFileSync ( _ _dirname + "/../../../redbrick-scriptexts.json" ) ) ;
} catch ( ex ) {
}
2023-12-03 21:12:53 +01:00
var disableModExposeSupported = process . versions . svrjs && process . versions . svrjs . match ( /^(?:Nightly-|(?:[4-9]|[123][0-9])[0-9]*\.|3\.(?:[1-9][0-9]+\.|9\.(?:[1-9])|4\.(?:(?:[3-9]|[12][0-9])[0-9]+|29)))/i ) ;
2023-07-29 23:44:21 +02:00
function Mod ( ) { }
2023-08-01 23:37:53 +02:00
2024-02-07 01:32:16 +01:00
Mod . prototype . callback = function ( req , res , serverconsole , responseEnd , href , ext , uobject , search , defaultpage , users , page404 , head , foot , fd , elseCallback , configJSON , callServerError , getCustomHeaders , origHref , redirect , parsePostData , authUser ) {
2023-07-29 23:44:21 +02:00
return function ( ) {
2023-08-01 23:37:53 +02:00
if ( ! configJSON ) {
configJSON = configJSONS ;
}
2024-02-07 01:32:16 +01:00
function checkIfThereIsA401Rule ( ) {
var actually401 = false ;
function createRegex ( regex ) {
var regexObj = regex . split ( "/" ) ;
if ( regexObj . length == 0 ) throw new Error ( "Invalid regex!" ) ;
var modifiers = regexObj . pop ( ) ;
regexObj . shift ( ) ;
var searchString = regexObj . join ( "/" ) ;
return new RegExp ( searchString , modifiers ) ;
}
if ( configJSON . nonStandardCodes ) {
configJSON . nonStandardCodes . every ( function ( nonscode ) {
if ( nonscode . scode == 401 ) {
if ( nonscode . regex && ( req . url . match ( createRegex ( nonscode . regex ) ) || href . match ( createRegex ( nonscode . regex ) ) ) ) {
actually401 = true ;
return true ;
} else if ( nonscode . url && ( nonStandardCodes [ i ] . url == href || ( os . platform ( ) == "win32" && nonStandardCodes [ i ] . url . toLowerCase ( ) == href . toLowerCase ( ) ) ) ) {
actually401 = true ;
return true ;
}
}
return false ;
} ) ;
}
return actually401 ;
}
2023-07-29 23:44:21 +02:00
if ( ! getCustomHeaders ) {
var bheaders = JSON . parse ( JSON . stringify ( configJSON . customHeaders ) ) ;
} else {
var bheaders = getCustomHeaders ( ) ;
}
2023-08-01 23:37:53 +02:00
bheaders [ "Content-Type" ] = "text/html" ; // HTML output
if ( ! getCustomHeaders ) {
bheaders [ "Server" ] =
"SVR.JS/" +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
")" ; // Add Server header
}
2023-07-30 02:24:20 +02:00
var abheaders = JSON . parse ( JSON . stringify ( bheaders ) ) ;
2023-07-29 23:44:21 +02:00
function executeCGI ( fname , req , res , dh , nEnv ) {
2023-08-01 23:37:53 +02:00
// Function to execute CGI scripts
2023-07-29 23:44:21 +02:00
var env = JSON . parse ( JSON . stringify ( process . env ) ) ;
var nEnvKeys = Object . keys ( nEnv ) ;
2023-07-30 02:24:20 +02:00
for ( var i = 0 ; i < nEnvKeys . length ; i ++ ) {
2023-07-29 23:44:21 +02:00
env [ nEnvKeys [ i ] ] = nEnv [ nEnvKeys [ i ] ] ;
}
var exttointerpreter = {
".pl" : [ "perl" ] ,
".py" : [ "python" ] ,
".sh" : [ "bash" ] ,
".ksh" : [ "ksh" ] ,
".csh" : [ "csh" ] ,
".rb" : [ "ruby" ] ,
".php" : [ "php-cgi" ]
2023-08-01 23:37:53 +02:00
} ;
2023-11-23 22:45:17 +01:00
if ( os . platform ( ) == "win32" ) {
2023-08-30 18:42:53 +02:00
exttointerpreter [ ".exe" ] = [ ] ;
exttointerpreter [ ".bat" ] = [ "cmd" , "/c" ] ;
exttointerpreter [ ".vbs" ] = [ "cscript" ] ;
}
2023-08-27 09:16:58 +02:00
2023-11-23 22:45:17 +01:00
fs . stat ( fname , function ( err , stats ) {
if ( err ) {
if ( ! callServerError ) {
res . writeHead ( 500 , {
"Content-Type" : "text/html" ,
"Server" : "RedBrick/" + version
} ) ;
res . end ( "<html><head></head><body><h1>RedBrick Error!</h1><p>Reason: " + err . message + "</p></body></html>" ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , err ) ;
2023-07-29 23:44:21 +02:00
}
2023-11-23 22:45:17 +01:00
return ;
}
if ( stats . size == 0 ) {
afterShebangCallback ( false ) ;
return ;
}
var s = fs . createReadStream ( fname ) ;
s . on ( "error" , function ( err ) {
if ( ! callServerError ) {
res . writeHead ( 500 , {
"Content-Type" : "text/html" ,
"Server" : "RedBrick/" + version
} ) ;
res . end ( "<html><head></head><body><h1>RedBrick Error!</h1><p>Reason: " + err . message + "</p></body></html>" ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , err ) ;
2023-08-27 09:16:58 +02:00
}
2023-11-23 22:45:17 +01:00
return ;
} ) . on ( "open" , function ( ) {
var rl = readline . createInterface ( {
input : s ,
} ) ;
rl . once ( "line" , function ( line ) {
rl . close ( ) ;
if ( line . substr ( 0 , 2 ) == "#!" ) {
var args = line . substr ( 2 ) . match ( /(?:[^" ]|\\(?:.|$)|"[^"]*(?:"|$))+/g ) ;
if ( ! args ) args = [ ] ;
args = args . map ( function ( arg ) {
return arg . replace ( /"/g , "" ) ;
2023-08-27 09:16:58 +02:00
} ) ;
2023-11-23 22:45:17 +01:00
afterShebangCallback ( args ) ;
} else if ( os . platform ( ) != "win32" && line . substr ( 0 , 4 ) == "\x7fELF" ) {
afterShebangCallback ( "binary" ) ;
2023-08-27 09:16:58 +02:00
} else {
2023-11-23 22:45:17 +01:00
afterShebangCallback ( false ) ;
2023-08-27 09:16:58 +02:00
}
} ) ;
} ) ;
2023-11-23 22:45:17 +01:00
} ) ;
2023-08-27 09:16:58 +02:00
2023-11-23 22:45:17 +01:00
function afterShebangCallback ( passedArgs ) {
var ext = path . extname ( fname ) ;
var args = [ ] ;
var buffer = "" ;
var stderr = "" ;
var headerendline = - 1 ;
var cned = false ;
args . push ( fname ) ;
if ( passedArgs == "binary" ) {
filename = ( process . cwd ( ) + ( os . platform ( ) == "win32" ? "\\" + fname . replace ( /\//g , "\\" ) : "/" + fname ) ) . replace ( os . platform ( ) == "win32" ? /\\+/ : /\/+/ , os . platform ( ) == "win32" ? "\\" : "/" ) ;
args = [ ] ;
} else if ( passedArgs ) {
if ( os . platform ( ) == "win32" ) {
args = passedArgs ;
args . push ( ( process . cwd ( ) + ( "\\" + fname . replace ( /\//g , "\\" ) ) ) . replace ( /\\+/ , "\\" ) ) ;
filename = args . shift ( ) ;
} else {
2023-08-27 09:16:58 +02:00
filename = ( process . cwd ( ) + ( os . platform ( ) == "win32" ? "\\" + fname . replace ( /\//g , "\\" ) : "/" + fname ) ) . replace ( os . platform ( ) == "win32" ? /\\+/ : /\/+/ , os . platform ( ) == "win32" ? "\\" : "/" ) ;
args = [ ] ;
2023-11-23 22:45:17 +01:00
}
} else {
args = exttointerpreteruser [ ext ] ;
if ( args === null ) {
elseCallback ( ) ;
return ;
} else if ( ! args ) {
args = exttointerpreter [ ext ] ;
if ( ! args ) {
2023-08-30 18:42:53 +02:00
elseCallback ( ) ;
return ;
2023-08-01 23:37:53 +02:00
}
2023-07-29 23:44:21 +02:00
}
2023-11-23 22:45:17 +01:00
args . push ( ( process . cwd ( ) + ( os . platform ( ) == "win32" ? "\\" + fname . replace ( /\//g , "\\" ) : "/" + fname ) ) . replace ( os . platform ( ) == "win32" ? /\\+/ : /\/+/ , os . platform ( ) == "win32" ? "\\" : "/" ) ) ;
filename = args . shift ( ) ;
}
2023-07-30 02:24:20 +02:00
2023-11-23 22:45:17 +01:00
var wd = fname . split ( "/" ) ;
wd [ 0 ] = "" ;
wd [ wd . length - 1 ] = "" ;
wd = wd . join ( os . platform ( ) == "win32" ? "\\" : "/" ) ;
var interpreter = childProcess . spawn ( filename , args , {
cwd : ( process . cwd ( ) + wd ) . replace ( os . platform ( ) == "win32" ? /\\+/ : /\/+/ , os . platform ( ) == "win32" ? "\\" : "/" ) ,
env : env
} ) ;
interpreter . on ( "error" , ( error ) => {
if ( ! callServerError ) {
res . writeHead ( 500 , {
"Content-Type" : "text/html" ,
"Server" : "RedBrick/" + version
} ) ;
res . end ( "<html><head></head><body><h1>RedBrick Error!</h1><p>Reason: " + error . message + "</p></body></html>" ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , error ) ;
}
} ) ;
var dataHandler = function ( data ) {
2024-02-16 02:30:11 +01:00
if ( ! cned ) buffer += data . toString ( "latin1" ) ;
2023-11-23 22:45:17 +01:00
var m = null ;
if ( ! cned ) m = buffer . match ( /(?:\r\n\r\n|\n\r\n\r|\n\n|\r\r)/ ) ;
if ( ! cned && m ) {
cned = true ;
eol = m [ 0 ] ;
headerendline = m . index ;
var bheaders = buffer . substr ( 0 , headerendline ) . split ( /(?:\r\n|\n\r|\n|\r)/ ) ;
var bheaderso = { } ;
if ( dh ) bheaderso = dh ;
var code = 200 ;
var msg = "OK" ;
var httpMatch = bheaders [ 0 ] . match ( /^HTTP\/[^ ]+ ([0-9]{3})(?: (.*))?$/ ) ;
if ( httpMatch ) {
bheaders . shift ( ) ;
code = parseInt ( httpMatch [ 1 ] ) ;
if ( httpMatch [ 2 ] ) msg = httpMatch [ 2 ] ;
else msg = http . STATUS _CODES [ code ] ;
} else if ( bheaders [ 0 ] . indexOf ( ":" ) == - 1 ) {
var heada = bheaders . shift ( ) ;
var hso = heada . match ( /^([0-9]{3})(?: (.*))?$/ ) ;
if ( hso ) {
code = parseInt ( hso [ 1 ] ) ;
if ( hso [ 2 ] ) msg = hso [ 2 ] ;
2023-08-30 18:42:53 +02:00
else msg = http . STATUS _CODES [ code ] ;
2023-08-01 23:37:53 +02:00
}
2023-11-23 22:45:17 +01:00
}
2024-02-11 15:05:43 +01:00
var hasLocation = false ;
2023-11-23 22:45:17 +01:00
for ( var i = 0 ; i < bheaders . length ; i ++ ) {
var headerp = bheaders [ i ] . match ( /^([^:]*)(?:: (.*))?/ ) ;
if ( ! headerp ) headerp = [ ] ;
var headern = headerp [ 1 ] ;
var headerv = headerp [ 2 ] ;
if ( headern . toLowerCase ( ) == "status" ) {
var httpMatch = headerv . match ( /^([0-9]{3})(?: (.*))?$/ ) ;
if ( httpMatch ) {
code = parseInt ( httpMatch [ 1 ] ) ;
if ( httpMatch [ 2 ] ) msg = httpMatch [ 2 ] ;
else msg = http . STATUS _CODES [ code ] ;
2023-08-01 23:37:53 +02:00
}
2023-11-23 22:45:17 +01:00
} else if ( headern . toLowerCase ( ) == "set-cookie" ) {
if ( ! bheaderso [ "Set-Cookie" ] ) bheaderso [ "Set-Cookie" ] = [ ] ;
bheaderso [ "Set-Cookie" ] . push ( headerv ) ;
} else {
2024-02-11 15:05:43 +01:00
if ( headern . toLowerCase ( ) == "location" ) hasLocation = true ;
2023-11-23 22:45:17 +01:00
bheaderso [ headern ] = headerv ;
2023-08-01 23:37:53 +02:00
}
2023-11-23 22:45:17 +01:00
}
2023-08-01 23:37:53 +02:00
2024-02-11 15:05:43 +01:00
if ( ( code < 300 || code > 399 ) && hasLocation ) {
2023-11-23 22:45:17 +01:00
code = 302 ;
msg = "Found" ;
}
2023-08-01 23:37:53 +02:00
2023-11-23 22:45:17 +01:00
try {
res . writeHead ( code , msg , bheaderso ) ;
2024-05-03 16:09:55 +02:00
res . write ( Buffer . from ( buffer . substr ( headerendline + eol . length ) , "latin1" ) ) ;
2023-11-23 22:45:17 +01:00
} catch ( ex ) {
2024-02-16 02:30:11 +01:00
interpreter . removeAllListeners ( "exit" ) ;
interpreter . stdout . removeAllListeners ( "data" ) ;
2023-11-23 22:45:17 +01:00
if ( ! callServerError ) {
res . writeHead ( 500 ) ;
res . end ( ex . stack ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , ex ) ;
2023-08-01 23:37:53 +02:00
}
2023-11-23 22:45:17 +01:00
return ;
2023-07-29 23:44:21 +02:00
}
2023-11-23 22:45:17 +01:00
} else {
2024-02-16 02:30:11 +01:00
if ( cned && ! res . finished ) {
res . write ( data ) ;
interpreter . stdout . removeListener ( "data" , dataHandler ) ;
interpreter . stdout . pipe ( res , { end : false } ) ;
2024-03-29 04:09:44 +01:00
dataHandler = function ( ) { } ; //Prevent event listener memory leaks
2024-02-16 02:30:11 +01:00
}
2023-11-23 22:45:17 +01:00
}
} ;
2024-03-29 04:09:44 +01:00
res . prependListener ( "close" , function ( ) {
if ( interpreter . stdout ) interpreter . stdout . unpipe ( res ) ; //Prevent server crashes with write after the end
} ) ;
res . on ( "error" , function ( ) { } ) ; //Suppress response stream errors
2023-11-23 22:45:17 +01:00
if ( interpreter . stdout ) {
interpreter . stdout . on ( "data" , dataHandler ) ;
interpreter . stderr . on ( "data" , function ( data ) {
stderr += data . toString ( ) ;
} ) ;
req . pipe ( interpreter . stdin ) ;
interpreter . on ( "exit" , ( code , signal ) => {
if ( ! cned && ( signal || code !== 0 ) ) {
var ex = new Error ( "Process execution failed!" + ( stderr ? " Reason: " + stderr . trim ( ) : "" ) ) ;
if ( ! callServerError ) {
res . writeHead ( 500 ) ;
res . end ( ex . stack ) ;
2023-08-01 23:37:53 +02:00
} else {
2023-11-23 22:45:17 +01:00
callServerError ( 500 , "RedBrick/" + version , ex ) ;
2023-08-01 23:37:53 +02:00
}
2023-11-23 22:45:17 +01:00
} else {
2024-02-16 02:30:11 +01:00
var preparedStderr = stderr . trim ( )
if ( preparedStderr ) {
serverconsole . errmessage ( "There were CGI application errors:" ) ;
serverconsole . errmessage ( preparedStderr ) ;
}
2024-03-29 04:09:44 +01:00
interpreter . stdout . removeListener ( "data" , dataHandler ) ;
interpreter . stdout . unpipe ( res ) ; //Prevent server crashes with write after the end
if ( ! res . finished ) res . end ( ) ;
2023-11-23 22:45:17 +01:00
}
} ) ;
2023-08-27 09:16:58 +02:00
}
2023-11-23 22:45:17 +01:00
}
2023-07-29 23:44:21 +02:00
}
2024-02-07 01:32:16 +01:00
function executeCGIWithEnv ( a , b , req , res , pubip , port , software , dh , user ) {
2023-08-01 23:37:53 +02:00
// Function to set up environment variables and execute CGI scripts
2023-07-29 23:44:21 +02:00
var nEnv = { } ;
2024-02-07 01:32:16 +01:00
if ( typeof user != "undefined" ) {
if ( user !== null ) {
if ( req . headers . authorization ) nEnv [ "AUTH_TYPE" ] = req . headers . authorization . split ( " " ) [ 0 ] ;
nEnv [ "REMOTE_USER" ] = user ;
}
} else if ( req . headers . authorization && ( typeof checkIfThereIsA401Rule == "undefined" || checkIfThereIsA401Rule ( ) ) ) {
2023-08-01 23:37:53 +02:00
nEnv [ "AUTH_TYPE" ] = req . headers . authorization . split ( " " ) [ 0 ] ;
if ( nEnv [ "AUTH_TYPE" ] == "Basic" ) {
var remoteCred = req . headers . authorization . split ( " " ) [ 1 ] ;
if ( ! remoteCred ) {
nEnv [ "REMOTE_USER" ] = "redbrick_cgi_invalid_user" ;
} else {
var remoteCredDecoded = Buffer . from ( remoteCred , "base64" ) . toString ( "utf8" ) ;
nEnv [ "REMOTE_USER" ] = remoteCredDecoded . split ( ":" ) [ 0 ] ;
}
} else {
nEnv [ "REMOTE_USER" ] = "svrjs_this_property_is_not_yet_supported_by_redbrick_cgi" ;
}
}
2023-07-29 23:44:21 +02:00
nEnv [ "QUERY_STRING" ] = req . url . split ( "?" ) [ 1 ] ;
if ( nEnv [ "QUERY_STRING" ] == undefined || nEnv [ "QUERY_STRING" ] == "undefined" ) nEnv [ "QUERY_STRING" ] = "" ;
nEnv [ "SERVER_SOFTWARE" ] = software ;
nEnv [ "SERVER_PROTOCOL" ] = "HTTP/" + req . httpVersion ;
2023-08-02 14:33:36 +02:00
if ( pubip && ( port !== null && port !== undefined ) ) {
nEnv [ "SERVER_PORT" ] = port ;
nEnv [ "SERVER_ADDR" ] = pubip . replace ( /^::ffff:/i , "" ) ;
if ( nEnv [ "SERVER_ADDR" ] . indexOf ( ":" ) != - 1 ) nEnv [ "SERVER_ADDR" ] = "[" + nEnv [ "SERVER_ADDR" ] + "]" ;
}
2023-11-23 22:45:17 +01:00
if ( configJSON . serverAdministratorEmail && configJSON . serverAdministratorEmail != "[no contact information]" ) {
2023-08-27 09:16:58 +02:00
nEnv [ "SERVER_ADMIN" ] = configJSON . serverAdministratorEmail ;
}
2023-07-29 23:44:21 +02:00
nEnv [ "SERVER_NAME" ] = req . headers . host ;
nEnv [ "DOCUMENT_ROOT" ] = process . cwd ( ) ;
2024-01-29 19:52:47 +01:00
nEnv [ "PATH_INFO" ] = decodeURIComponent ( b ) ;
nEnv [ "PATH_TRANSLATED" ] = b ? ( ( process . cwd ( ) + decodeURIComponent ( require ( "os" ) . platform == "win32" ? b . replace ( /\//g , "\\" ) : b ) ) . replace ( ( require ( "os" ) . platform == "win32" ? /\\\\/g : /\/\//g ) , ( require ( "os" ) . platform == "win32" ? "\\" : "/" ) ) ) : "" ;
2023-07-29 23:44:21 +02:00
nEnv [ "REQUEST_METHOD" ] = req . method ;
nEnv [ "GATEWAY_INTERFACE" ] = "CGI/1.1" ;
2024-11-21 00:19:53 +01:00
nEnv [ "REQUEST_URI" ] = ( ! origHref || origHref == href ) ? req . url : ( origHref + ( uobject . search ? ( ( uobject . search [ 0 ] == "?" ? "" : "?" ) + uobject . search ) : "" ) ) ;
2023-07-30 02:24:20 +02:00
nEnv [ "REMOTE_ADDR" ] = ( req . socket . realRemoteAddress ? req . socket . realRemoteAddress : ( ( req . headers [ "x-forwarded-for" ] && configJSON . enableIPSpoofing ) ? req . headers [ "x-forwarded-for" ] . split ( "," ) [ 0 ] . replace ( / /g , "" ) : req . socket . remoteAddress ) ) . replace ( /^::ffff:/i , "" ) ;
2023-11-23 22:45:17 +01:00
if ( req . socket . realRemoteAddress && req . socket . realRemotePort ) {
2023-09-03 11:32:06 +02:00
nEnv [ "REMOTE_PORT" ] = req . socket . realRemotePort ;
2023-11-23 22:45:17 +01:00
} else if ( ! ( req . socket . realRemoteAddress && ! req . socket . realRemotePort ) ) {
2023-09-03 11:32:06 +02:00
nEnv [ "REMOTE_PORT" ] = req . socket . remotePort ;
}
2023-07-29 23:44:21 +02:00
nEnv [ "SCRIPT_NAME" ] = a ;
nEnv [ "SCRIPT_FILENAME" ] = ( process . cwd ( ) + ( require ( "os" ) . platform == "win32" ? a . replace ( /\//g , "\\" ) : a ) ) . replace ( ( require ( "os" ) . platform == "win32" ? /\\\\/g : /\/\//g ) , ( require ( "os" ) . platform == "win32" ? "\\" : "/" ) ) ;
2023-08-19 20:18:44 +02:00
if ( req . socket . encrypted ) nEnv [ "HTTPS" ] = "ON" ;
2023-07-29 23:44:21 +02:00
if ( req . headers [ "content-type" ] ) nEnv [ "CONTENT_TYPE" ] = req . headers [ "content-type" ] ;
if ( req . headers [ "content-length" ] ) nEnv [ "CONTENT_LENGTH" ] = req . headers [ "content-length" ] ;
var nh = JSON . parse ( JSON . stringify ( req . headers ) ) ;
delete nh [ "content-type" ] ;
delete nh [ "content-length" ] ;
var nhKeys = Object . keys ( nh ) ;
for ( var i = 0 ; i < nhKeys . length ; i ++ ) {
nEnv [ "HTTP_" + nhKeys [ i ] . replace ( /[^0-9A-Za-z]+/g , "_" ) . toUpperCase ( ) ] = req . headers [ nhKeys [ i ] ] ;
}
executeCGI ( "." + a , req , res , dh , nEnv ) ;
}
2023-08-01 23:37:53 +02:00
2024-02-15 20:09:46 +01:00
var isCgiBin = href . match ( new RegExp ( "^/cgi-bin(?:$|[?#/])" , os . platform ( ) == "win32" ? "i" : "" ) ) ;
2023-11-23 22:45:17 +01:00
var isScriptExt = scriptExts . indexOf ( "." + ext ) != - 1 ;
if ( ( href == "/redbrick-interpreters.json" || href == "/redbrick-scriptexts.json" || ( os . platform ( ) == "win32" && ( href . toLowerCase ( ) == "/redbrick-interpreters.json" || href . toLowerCase ( ) == "/redbrick-scriptexts.json" ) ) ) && path . normalize ( _ _dirname + "/../../.." ) == process . cwd ( ) ) {
if ( ! callServerError ) {
res . writeHead ( 403 , "Forbidden" , {
"Content-Type" : "text/html" ,
"Server" : "RedBrick/" + version
} ) ;
res . write (
"<html><head><title>403 Forbidden</title></head><body><h1>403 Forbidden</h1><p>You don't have access to specific page.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version +
" " +
( req . headers . host == undefined ? "" : " on " + req . headers . host ) +
"</p></body></html>"
) ;
res . end ( JSON . stringify ( exttointerpreteruser , null , 2 ) ) ;
} else {
callServerError ( 403 , "RedBrick/" + version ) ;
}
} else {
2024-01-29 19:52:47 +01:00
fs . stat ( "." + decodeURIComponent ( href ) , function ( err , stats ) {
2023-08-02 14:33:36 +02:00
if ( ! err ) {
if ( ! stats . isFile ( ) ) {
2023-11-23 22:45:17 +01:00
if ( isCgiBin || scriptExts . indexOf ( ".php" ) != - 1 ) {
2024-01-29 19:52:47 +01:00
fs . stat ( "." + decodeURIComponent ( href ) + "/index.php" , function ( e2 , s2 ) {
2023-11-23 22:45:17 +01:00
if ( ! e2 && s2 . isFile ( ) ) {
try {
executeCGIWithEnv (
2024-01-29 19:52:47 +01:00
( decodeURIComponent ( href ) + "/index.php" ) . replace ( /\/+/g , "/" ) ,
2023-11-23 22:45:17 +01:00
"" ,
req ,
res ,
req . socket . localAddress ,
req . socket . localPort ,
getCustomHeaders ?
getCustomHeaders ( ) [ "Server" ] +
2023-12-03 21:12:53 +01:00
( disableModExposeSupported && ( configJSON . exposeModsInErrorPages || configJSON . exposeModsInErrorPages === undefined ) ?
2023-11-23 22:45:17 +01:00
" RedBrick/" +
2023-12-03 21:12:53 +01:00
version : "" ) :
2023-11-23 22:45:17 +01:00
"SVR.JS/" +
2023-08-02 14:33:36 +02:00
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
2023-11-23 22:45:17 +01:00
version ,
2024-02-07 01:32:16 +01:00
bheaders ,
authUser
2023-08-02 14:33:36 +02:00
) ;
2023-11-23 22:45:17 +01:00
} catch ( ex ) {
if ( ! callServerError ) {
res . writeHead ( 500 , "Internal Server Error" , abheaders ) ;
res . write (
"<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexpected exception. Below, the stack trace of the error is shown:</p><code>" +
ex . stack . replace ( /\r\n/g , "<br/>" ) . replace ( /\n/g , "<br/>" ) . replace ( /\r/g , "<br/>" ) . replace ( / /g , " " ) +
"</code><p>Please contact the developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
2023-08-19 20:18:44 +02:00
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
2023-11-23 22:45:17 +01:00
version +
" " +
( req . headers . host == undefined ? "" : " on " + req . headers . host ) +
"</p></body></html>"
2023-08-19 20:18:44 +02:00
) ;
2023-11-23 22:45:17 +01:00
res . end ( ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , ex ) ;
}
}
} else if ( isCgiBin || scriptExts . indexOf ( ".cgi" ) != - 1 ) {
2024-01-29 19:52:47 +01:00
fs . stat ( "." + decodeURIComponent ( href ) + "/index.cgi" , function ( e3 , s3 ) {
2023-11-23 22:45:17 +01:00
if ( ! e3 && s3 . isFile ( ) ) {
try {
executeCGIWithEnv (
2024-01-29 19:52:47 +01:00
( decodeURIComponent ( href ) + "/index.cgi" ) . replace ( /\/+/g , "/" ) ,
2023-11-23 22:45:17 +01:00
"" ,
req ,
res ,
req . socket . localAddress ,
req . socket . localPort ,
getCustomHeaders ?
getCustomHeaders ( ) [ "Server" ] +
2023-12-03 21:12:53 +01:00
( disableModExposeSupported && ( configJSON . exposeModsInErrorPages || configJSON . exposeModsInErrorPages === undefined ) ?
2023-11-23 22:45:17 +01:00
" RedBrick/" +
2023-12-03 21:12:53 +01:00
version : "" ) :
2023-11-23 22:45:17 +01:00
"SVR.JS/" +
2023-08-19 20:18:44 +02:00
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
2023-11-23 22:45:17 +01:00
version ,
2024-02-07 01:32:16 +01:00
bheaders ,
authUser
2023-08-19 20:18:44 +02:00
) ;
2023-11-23 22:45:17 +01:00
} catch ( ex ) {
if ( ! callServerError ) {
res . writeHead ( 500 , "Internal Server Error" , abheaders ) ;
res . write (
"<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexpected exception. Below, the stack trace of the error is shown:</p><code>" +
ex . stack . replace ( /\r\n/g , "<br/>" ) . replace ( /\n/g , "<br/>" ) . replace ( /\r/g , "<br/>" ) . replace ( / /g , " " ) +
"</code><p>Please contact the developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version +
" " +
( req . headers . host == undefined ? "" : " on " + req . headers . host ) +
"</p></body></html>"
) ;
res . end ( ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , ex ) ;
}
2023-08-19 20:18:44 +02:00
}
2023-11-23 22:45:17 +01:00
} else {
elseCallback ( ) ;
}
} ) ;
} else {
elseCallback ( ) ;
}
} ) ;
} else if ( scriptExts . indexOf ( ".cgi" ) != - 1 ) {
2024-01-29 19:52:47 +01:00
fs . stat ( "." + decodeURIComponent ( href ) + "/index.cgi" , function ( e3 , s3 ) {
2023-11-23 22:45:17 +01:00
if ( ! e3 && s3 . isFile ( ) ) {
try {
executeCGIWithEnv (
2024-01-29 19:52:47 +01:00
( decodeURIComponent ( href ) + "/index.cgi" ) . replace ( /\/+/g , "/" ) ,
2023-11-23 22:45:17 +01:00
"" ,
req ,
res ,
req . socket . localAddress ,
req . socket . localPort ,
getCustomHeaders ?
getCustomHeaders ( ) [ "Server" ] +
2023-12-03 21:12:53 +01:00
( disableModExposeSupported && ( configJSON . exposeModsInErrorPages || configJSON . exposeModsInErrorPages === undefined ) ?
2023-11-23 22:45:17 +01:00
" RedBrick/" +
2023-12-03 21:12:53 +01:00
version : "" ) :
2023-11-23 22:45:17 +01:00
"SVR.JS/" +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version ,
2024-02-07 01:32:16 +01:00
bheaders ,
authUser
2023-11-23 22:45:17 +01:00
) ;
} catch ( ex ) {
if ( ! callServerError ) {
res . writeHead ( 500 , "Internal Server Error" , abheaders ) ;
res . write (
"<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexpected exception. Below, the stack trace of the error is shown:</p><code>" +
ex . stack . replace ( /\r\n/g , "<br/>" ) . replace ( /\n/g , "<br/>" ) . replace ( /\r/g , "<br/>" ) . replace ( / /g , " " ) +
"</code><p>Please contact the developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version +
" " +
( req . headers . host == undefined ? "" : " on " + req . headers . host ) +
"</p></body></html>"
) ;
res . end ( ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , ex ) ;
2023-08-19 20:18:44 +02:00
}
2023-08-02 14:33:36 +02:00
}
2023-11-23 22:45:17 +01:00
} else {
elseCallback ( ) ;
}
} ) ;
2023-08-01 23:37:53 +02:00
} else {
2023-11-23 22:45:17 +01:00
elseCallback ( ) ;
}
} else {
if ( isCgiBin || isScriptExt ) {
2023-08-01 23:37:53 +02:00
try {
executeCGIWithEnv (
2024-01-29 19:52:47 +01:00
decodeURIComponent ( href ) ,
2023-11-23 22:45:17 +01:00
"" ,
2023-08-01 23:37:53 +02:00
req ,
res ,
req . socket . localAddress ,
req . socket . localPort ,
getCustomHeaders ?
getCustomHeaders ( ) [ "Server" ] +
2023-12-03 21:12:53 +01:00
( disableModExposeSupported && ( configJSON . exposeModsInErrorPages || configJSON . exposeModsInErrorPages === undefined ) ?
2023-08-01 23:37:53 +02:00
" RedBrick/" +
2023-12-03 21:12:53 +01:00
version : "" ) :
2023-08-01 23:37:53 +02:00
"SVR.JS/" +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version ,
2024-02-07 01:32:16 +01:00
bheaders ,
authUser
2023-08-01 23:37:53 +02:00
) ;
} catch ( ex ) {
if ( ! callServerError ) {
res . writeHead ( 500 , "Internal Server Error" , abheaders ) ;
res . write (
"<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexpected exception. Below, the stack trace of the error is shown:</p><code>" +
ex . stack . replace ( /\r\n/g , "<br/>" ) . replace ( /\n/g , "<br/>" ) . replace ( /\r/g , "<br/>" ) . replace ( / /g , " " ) +
"</code><p>Please contact the developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version +
" " +
( req . headers . host == undefined ? "" : " on " + req . headers . host ) +
"</p></body></html>"
) ;
res . end ( ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , ex ) ;
}
2023-07-29 23:44:21 +02:00
}
2023-11-23 22:45:17 +01:00
} else {
elseCallback ( ) ;
}
}
} else if ( err && err . code == "ENOTDIR" ) {
function checkPath ( pth , cb , a ) {
// Function to check the path of the file and execute CGI script
var cpth = pth . split ( "/" ) ;
if ( cpth . length < ( isCgiBin ? 3 : 2 ) ) {
cb ( false ) ;
return ;
}
if ( ! a ) b = [ ] ;
else var b = a . split ( "/" ) ;
var isFile = false ;
fs . stat ( pth , function ( err , stats ) {
if ( ! err && stats . isFile ( ) ) {
cb ( {
fpth : pth ,
rpth : ( a !== undefined ? "/" + a : "" )
} )
} else {
b . unshift ( cpth . pop ( ) ) ;
return checkPath ( cpth . join ( "/" ) , cb , b . join ( "/" ) ) ;
}
} ) ;
}
2024-01-29 19:52:47 +01:00
checkPath ( "." + decodeURIComponent ( href ) , function ( pathp ) {
2023-11-23 22:45:17 +01:00
if ( ! pathp ) {
elseCallback ( ) ;
} else {
var newext = path . extname ( pathp . fpth ) ;
if ( isCgiBin || scriptExts . indexOf ( newext ) != - 1 ) {
try {
executeCGIWithEnv (
pathp . fpth . substr ( 1 ) ,
pathp . rpth ,
req ,
res ,
req . socket . localAddress ,
req . socket . localPort ,
getCustomHeaders ?
getCustomHeaders ( ) [ "Server" ] +
2023-12-03 21:12:53 +01:00
( disableModExposeSupported && ( configJSON . exposeModsInErrorPages || configJSON . exposeModsInErrorPages === undefined ) ?
2023-11-23 22:45:17 +01:00
" RedBrick/" +
2023-12-03 21:12:53 +01:00
version : "" ) :
2023-11-23 22:45:17 +01:00
"SVR.JS/" +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version ,
2024-02-07 01:32:16 +01:00
bheaders ,
authUser
2023-11-23 22:45:17 +01:00
) ;
} catch ( ex ) {
if ( ! callServerError ) {
res . writeHead ( 500 , "Internal Server Error" , abheaders ) ;
res . write (
"<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexpected exception. Below, the stack trace of the error is shown:</p><code>" +
ex . stack . replace ( /\r\n/g , "<br/>" ) . replace ( /\n/g , "<br/>" ) . replace ( /\r/g , "<br/>" ) . replace ( / /g , " " ) +
"</code><p>Please contact the developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON . version +
" (" +
os . platform ( ) [ 0 ] . toUpperCase ( ) +
os . platform ( ) . slice ( 1 ) +
"; Node.JS/" +
process . version +
") RedBrick/" +
version +
" " +
( req . headers . host == undefined ? "" : " on " + req . headers . host ) +
"</p></body></html>"
) ;
res . end ( ) ;
} else {
callServerError ( 500 , "RedBrick/" + version , ex ) ;
}
}
} else {
elseCallback ( ) ;
}
2023-07-29 23:44:21 +02:00
}
2023-08-01 23:37:53 +02:00
} ) ;
2023-12-03 21:12:53 +01:00
} else {
2023-08-02 14:33:36 +02:00
elseCallback ( ) ; //Invoke default error handler
2023-07-29 23:44:21 +02:00
}
2023-08-01 23:37:53 +02:00
} ) ;
2023-07-29 23:44:21 +02:00
}
}
}
2023-08-01 23:37:53 +02:00
2023-07-29 23:44:21 +02:00
module . exports = Mod ;