<commit_before>#!/usr/bin/env node
/*!
 * XCGI
 * Copyright (c) 2017-2018 <NAME>
 * GNU AGPLv3 Licensed
 */
var os = require('os')
var http = require('http')
var https = require('https')
var querystring = require('querystring')
var spawn = require('child_process').spawn
var execFileSync = require('child_process').execFileSync
var fs = require('fs')
var path = require('path')
var multiparty = require('multiparty')
var EventEmitter = require('events').EventEmitter
/// HELP MESSAGE ////////////////
function PRINTHELP() {
	var msg = [
		'xcgi <options...> <sites path>',
		'Options:',
		'    -p <port>   Specify different port number. You have to choose',
		'                either http or https only. Default is 80 and 443.',
		'    -h          Http only.',
		'    -s          Https only.',
		'    -r          Redirect http to https. Off by default.',
		'    -m <int>    Max instances of spawned process.'
	]
	for(var i=0;i<msg.length;i++)
		console.log(msg[i])
}
/////////////////////////////////
var SITES_PATH = '.'
var PORT = 80
var QUEUE = []
var INSTANCE_COUNT = 0
var PGIDS = {}
// IN WINDOWS, WE CAN KILL PGID (USING KILL PROGRAM) WITHOUT
// DETACHING THE PROCESS. IN UNIX, WE NEED TO DETACH THE PROCESS
// SO THAT WE CAN KILL PGID USING `process.kill(-pgid)` FUNCTION.
var DETACH_PROCESS = process.platform == 'win32' ? false : true
/// CONFIGURE ///////////////////
var CONFIG = {
	http: true,
	https: true,
	redirect: false,
	httpsOption: {
		key: '',
		cert: ''
	},
	maxInstances: os.cpus().length * 16
}
getopt(process.argv.splice(2), function(option, value) {
	switch(option) {
		case 'p':
			PORT = parseInt(value)
			return true
		case 'h':
			CONFIG.http = true
			CONFIG.https = false
			return false
		case 's':
			CONFIG.http = false
			CONFIG.https = true
			return false
		case 'r':
			CONFIG.http = true
			CONFIG.https = true
			CONFIG.redirect = true
			return false
		case 'm':
			CONFIG.maxInstances = parseInt(value)
			return true
		case 'help':
			PRINTHELP()
			process.exit(0)
			return false
		default:
			if (SITES_PATH == '.')
				SITES_PATH = value
			return false
	}
})
if (CONFIG.https) {
	var key = process.env['XCGI_HTTPS_KEY']
	var cert = process.env['XCGI_HTTPS_CERT']
	if (fs.existsSync(key) && fs.existsSync(cert)) {
		CONFIG.httpsOption.key = fs.readFileSync(key)
		CONFIG.httpsOption.cert = fs.readFileSync(cert)
	} else {
		if (CONFIG.http) {
			console.error('WARNING:', 'XCGI_HTTPS_KEY or XCGI_HTTPS_CERT is not configured. Turning HTTPS off instead.')
			CONFIG.https = false
		} else {
			console.error('ERROR:', 'XCGI_HTTPS_KEY or XCGI_HTTPS_CERT is not configured.')
			process.exit(1)
		}
	}
}
/////////////////////////////////
// console.log(SITES_PATH, PORT)
// console.log(CONFIG)
// process.exit(0)
/////////////////////////////////
var SHELL = 'bash'
var ROOTS = null
var ROOTDIR_DELIMITER = '_'
var ASSET_TYPES = {
	'.js': 'application/javascript',
	'.json': 'application/json',
	'.css': 'text/css',
	'.jpg': 'image/jpeg',
	'.png': 'image/png',
	'.gif': 'image/gif',
	'.pdf': 'application/pdf'
}
var DEFAULT_SCRIPT = 'default.sh'
var SCRIPT_STATUS_CODES = [200, 400, 404]
/////////////////////////////////
var KillProcess 	= GetProcessKiller()
var KillProcessSync = GetProcessKiller(true)
/////////////////////////////////
function Root() {
	this.dir 		= null
	this.domain 	= null
	this.namespace 	= null
	this.emitter 	= new EventEmitter()
}
/////////////////////////////////
function EnvValue(env, prefix, name, a) {
	name = name.toUpperCase()
	if (Array.isArray(a)) {
		if (a.length == 0)
			return
		if (name.length > 2 && name.substr(-2) == '[]') {
			var values = []
			for(var i=0;i<a.length;i++)
				values.push(encodeURI(a[i]))
			env[prefix + name.substr(0, name.length-2)] = values.join(' ')
		} else {
			env[prefix + name] = a[0]
		}
	} else {
		env[prefix + name] = a
	}
}
function CreateEnv(req, url, qs, objects, rootdir) {
	var env = {}
	////////////////////////////////////
	env['REQUEST_URL'] = url
	for(var key in qs)
		EnvValue(env, 'QUERY_', key, qs[key])
	////////////////////////////////////
	env['REQUEST_METHOD'] = req.method
	////////////////////////////////////
	env['HTTP_VERSION'] = req.httpVersion
	for(var key in req.headers)
		env['HTTP_' + key.replace(/-/g, '_').toUpperCase()] = req.headers[key]
	////////////////////////////////////
	env['DOCUMENT_ROOT'] = rootdir
	////////////////////////////////////
	for(var i=0; i<objects.length;i++) {
		env['QUERY_' + objects[i][0].toUpperCase() + '_ID'] = objects[i][1] || ''
	}
	if (objects.length > 0)
		env['QUERY_ID'] = objects[objects.length-1][1] || ''
	////////////////////////////////////
	env['STATUS_OK'] 			= 0
	env['STATUS_BADREQUEST'] 	= 1
	env['STATUS_NOTFOUND'] 	 	= 2
	////////////////////////////////////
	return env
}
function ConsumeQueue() {
	if (INSTANCE_COUNT < CONFIG.maxInstances && QUEUE.length > 0) {<commit_msg>Inherit PATH to child process.<commit_after>#!/usr/bin/env node
/*!
 * XCGI
 * Copyright (c) 2017-2018 <NAME>
 * GNU AGPLv3 Licensed
 */
var os = require('os')
var http = require('http')
var https = require('https')
var querystring = require('querystring')
var spawn = require('child_process').spawn
var execFileSync = require('child_process').execFileSync
var fs = require('fs')
var path = require('path')
var multiparty = require('multiparty')
var EventEmitter = require('events').EventEmitter
/// HELP MESSAGE ////////////////
function PRINTHELP() {
	var msg = [
		'xcgi <options...> <sites path>',
		'Options:',
		'    -p <port>   Specify different port number. You have to choose',
		'                either http or https only. Default is 80 and 443.',
		'    -h          Http only.',
		'    -s          Https only.',
		'    -r          Redirect http to https. Off by default.',
		'    -m <int>    Max instances of spawned process.'
	]
	for(var i=0;i<msg.length;i++)
		console.log(msg[i])
}
/////////////////////////////////
var SITES_PATH = '.'
var PORT = 80
var QUEUE = []
var INSTANCE_COUNT = 0
var PGIDS = {}
// IN WINDOWS, WE CAN KILL PGID (USING KILL PROGRAM) WITHOUT
// DETACHING THE PROCESS. IN UNIX, WE NEED TO DETACH THE PROCESS
// SO THAT WE CAN KILL PGID USING `process.kill(-pgid)` FUNCTION.
var DETACH_PROCESS = process.platform == 'win32' ? false : true
/// CONFIGURE ///////////////////
var CONFIG = {
	http: true,
	https: true,
	redirect: false,
	httpsOption: {
		key: '',
		cert: ''
	},
	maxInstances: os.cpus().length * 16
}
getopt(process.argv.splice(2), function(option, value) {
	switch(option) {
		case 'p':
			PORT = parseInt(value)
			return true
		case 'h':
			CONFIG.http = true
			CONFIG.https = false
			return false
		case 's':
			CONFIG.http = false
			CONFIG.https = true
			return false
		case 'r':
			CONFIG.http = true
			CONFIG.https = true
			CONFIG.redirect = true
			return false
		case 'm':
			CONFIG.maxInstances = parseInt(value)
			return true
		case 'help':
			PRINTHELP()
			process.exit(0)
			return false
		default:
			if (SITES_PATH == '.')
				SITES_PATH = value
			return false
	}
})
if (CONFIG.https) {
	var key = process.env['XCGI_HTTPS_KEY']
	var cert = process.env['XCGI_HTTPS_CERT']
	if (fs.existsSync(key) && fs.existsSync(cert)) {
		CONFIG.httpsOption.key = fs.readFileSync(key)
		CONFIG.httpsOption.cert = fs.readFileSync(cert)
	} else {
		if (CONFIG.http) {
			console.error('WARNING:', 'XCGI_HTTPS_KEY or XCGI_HTTPS_CERT is not configured. Turning HTTPS off instead.')
			CONFIG.https = false
		} else {
			console.error('ERROR:', 'XCGI_HTTPS_KEY or XCGI_HTTPS_CERT is not configured.')
			process.exit(1)
		}
	}
}
/////////////////////////////////
// console.log(SITES_PATH, PORT)
// console.log(CONFIG)
// process.exit(0)
/////////////////////////////////
var SHELL = 'bash'
var ROOTS = null
var ROOTDIR_DELIMITER = '_'
var ASSET_TYPES = {
	'.js': 'application/javascript',
	'.json': 'application/json',
	'.css': 'text/css',
	'.jpg': 'image/jpeg',
	'.png': 'image/png',
	'.gif': 'image/gif',
	'.pdf': 'application/pdf'
}
var DEFAULT_SCRIPT = 'default.sh'
var SCRIPT_STATUS_CODES = [200, 400, 404]
/////////////////////////////////
var KillProcess 	= GetProcessKiller()
var KillProcessSync = GetProcessKiller(true)
/////////////////////////////////
function Root() {
	this.dir 		= null
	this.domain 	= null
	this.namespace 	= null
	this.emitter 	= new EventEmitter()
}
/////////////////////////////////
function EnvValue(env, prefix, name, a) {
	name = name.toUpperCase()
	if (Array.isArray(a)) {
		if (a.length == 0)
			return
		if (name.length > 2 && name.substr(-2) == '[]') {
			var values = []
			for(var i=0;i<a.length;i++)
				values.push(encodeURI(a[i]))
			env[prefix + name.substr(0, name.length-2)] = values.join(' ')
		} else {
			env[prefix + name] = a[0]
		}
	} else {
		env[prefix + name] = a
	}
}
function CreateEnv(req, url, qs, objects, rootdir) {
	var env = {}
	////////////////////////////////////
	env['REQUEST_URL'] = url
	for(var key in qs)
		EnvValue(env, 'QUERY_', key, qs[key])
	////////////////////////////////////
	env['REQUEST_METHOD'] = req.method
	////////////////////////////////////
	env['HTTP_VERSION'] = req.httpVersion
	for(var key in req.headers)
		env['HTTP_' + key.replace(/-/g, '_').toUpperCase()] = req.headers[key]
	////////////////////////////////////
	env['DOCUMENT_ROOT'] = rootdir
	////////////////////////////////////
	for(var i=0; i<objects.length;i++) {
		env['QUERY_' + objects[i][0].toUpperCase() + '_ID'] = objects[i][1] || ''
	}
	if (objects.length > 0)
		env['QUERY_ID'] = objects[objects.length-1][1] || ''
	////////////////////////////////////
	env['STATUS_OK'] 			= 0
	env['STATUS_BADREQUEST'] 	= 1
	env['STATUS_NOTFOUND'] 	 	= 2
	////////////////////////////////////
	// INHERITS FROM PROCESS.ENV
	env['PATH'] = process.env['PATH']
	////////////////////////////////////
	return env
}
function ConsumeQueue() {
	if (INSTANCE_COUNT < CONFIG.maxInstances && QUEUE.length > 0) {
{'fraction_non_alphanumeric': 0.24625354394491697, 'fraction_numerical': 0.010530579181855002, 'mean_word_length': 2.2803055463301227, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5148344', 'n_tokens_mistral': 3651, 'n_tokens_neox': 3363, 'n_words': 807}