wo-base-webserver/server.js
2019-10-24 14:46:53 +08:00

159 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const fs = require('fs')
const path = require('path')
const os = require('os')
function config(){
const commander = require('commander')
const deepmerge = require('deepmerge')
var Config={}
// 读取配置文件
try {
if (fs.existsSync(path.join(process.cwd(), './ConfigBasic.js'))) {
Config=require(path.join(process.cwd(), './ConfigBasic.js'))
console.info('ConfigBasic loaded')
}
if (fs.existsSync(path.join(process.cwd(), './ConfigCustom.js'))) { // 如果存在,覆盖掉 ConfigBasic 里的默认参数
Config=deepmerge(Config, require(path.join(process.cwd(), './ConfigCustom.js'))) // 注意objectMerge后产生了一个新的对象而不是在原来的Config里添加
console.info('ConfigCustom loaded')
}
if (fs.existsSync(path.join(process.cwd(), './ConfigSecret.js'))) { // 如果存在,覆盖掉 ConfigBasic 和 ConfigCustom 里的参数
Config=deepmerge(Config, require(path.join(process.cwd(), './ConfigSecret.js')))
console.info('ConfigSecret loaded')
}
}catch(err){
console.error('Loading config files failed: '+err.message)
}
// 载入命令行参数
commander
.version(Config.VERSION, '-v, --version') // 默认是 -V。如果要 -v就要加 '-v --version'
.option('-H, --host <host>', `Host ip or domain name. Default to ${Config.host}`)
.option('-P, --protocol <protocol>', `Web server protocol http|https|httpall|http2https. Default to ${Config.protocol}`)
.option('-p, --port <port>', `Server port. Default to ${Config.port?Config.port:'80|443'}`)
.option('--sslType <type>', `SSL provider type. Default to ${Config.sslType}`)
.option('--sslCert <cert>', `SSL certificate file. Default to ${Config.sslCert}`)
.option('--sslKey <key>', `SSL private key file. Default to ${Config.sslKey}`)
.option('--sslCA <ca>', 'SSL ca bundle file')
.parse(process.argv)
// 把命令行参数 合并入配置。
Config.host=commander.host || Config.host
Config.protocol=commander.protocol || Config.protocol || 'http'
Config.port=parseInt(commander.port) || parseInt(Config.port) || (Config.protocol==='http'?80:Config.protocol==='https'?443:undefined) // 端口默认为 http:80, https:443, httpall: 80|443
Config.sslType = commander.sslType || Config.sslType
Config.sslCert=commander.sslCert || Config.sslCert
Config.sslKey=commander.sslKey || Config.sslKey
Config.sslCA=commander.sslCA || Config.sslCA
console.info('Configuration is ready.')
return Config
}
async function init(){ /*** 设置全局对象 ***/
global.wo={} // wo 代表 world或是当前的命名空间把各种类都放在这里防止和其他库的冲突。
wo.Config=config() // 依次载入系统默认配置、用户配置文件、命令行参数
}
(async function start(){
await init()
const server = require('express')()
const greenlock = (wo.Config.sslType === 'greenlock') ? require('greenlock-express').create({
version: 'draft-11',
server: 'https://acme-v02.api.letsencrypt.org/directory', // for test: acme-staging-v02
agreeTos: true,
communityMember: false,
store: require('greenlock-store-fs'),
email: 'ssl@faronear.org',
approvedDomains: wo.Config.sslDomainList,
configDir: path.resolve(__dirname, 'ssl'),
app: server,
}) : null
/*** 通用中间件 ***/
server.use(require('morgan')('development'===server.get('env')?'dev':'combined'))
server.use(require('body-parser').json())
server.use(require('body-parser').urlencoded({ extended: false }))
server.use(require('cookie-parser')())
server.use(require('compression')())
/*** 路由 ***/
server.use(require('express').static(path.join(__dirname, 'dist'), {index: 'index.html'}))
// server.use(require('serve-favicon')(path.join(__dirname, 'public', 'favicon.ico'))) // uncomment after placing your favicon in /public
let ipv4 = getMyIp()
/*** 启动 Web 服务 ***/
if ('http' === wo.Config.protocol) {
webServer = require('http').createServer(server).listen(wo.Config.port, function (err) {
if (err) console.log(err)
else console.log(`Server listening on ${wo.Config.protocol}://${wo.Config.host}:${wo.Config.port} with IPv4=${ipv4} for ${server.settings.env} environment`)
})
} else if ('https' === wo.Config.protocol) {
webServer = require('https').createServer(wo.Config.sslType === 'greenlock' ? greenlock.httpsOptions : {
key: fs.readFileSync(wo.Config.sslKey),
cert: fs.readFileSync(wo.Config.sslCert),
// ca: [ fs.readFileSync(wo.Config.sslCA) ] // only for self-signed certificate: https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
}, server).listen(wo.Config.port, function (err) {
if (err) console.log(err)
else console.log(`Server listening on ${wo.Config.protocol}://${wo.Config.host}:${wo.Config.port} with IPv4=${ipv4} for ${server.settings.env} environment`)
})
} else if ('httpall' === wo.Config.protocol) {
let portHttp = wo.Config.port ? wo.Config.port : 80 // 如果port参数已设置使用它否则默认为80
let portHttps = (wo.Config.port && wo.Config.port !== 80) ? wo.Config.port + 443 : 443 // 如果port参数已设置使用它+443否则默认为443
if (wo.Config.sslType === 'greenlock') {
webServer = greenlock.listen(portHttp, portHttps, function (err) {
if (err) console.log(err)
else console.log(`Server listening on [${wo.Config.protocol}] http=>https://${wo.Config.host}:${portHttp}=>${portHttps} with IPv4=${ipv4} for ${server.settings.env} environment`)
})
} else {
require('http').createServer(server.all('*', function (ask, reply) {
reply.redirect(`https://${wo.Config.host}:${portHttps}`)
})).listen(portHttp, function(err) {
if (err) console.log(err)
else console.log(`Server listening on [${wo.Config.protocol}] http://${wo.Config.host}:${portHttp} with IPv4=${ipv4} for ${server.settings.env} environment`)
})
webServer = require('https').createServer({
key: fs.readFileSync(wo.Config.sslKey),
cert: fs.readFileSync(wo.Config.sslCert),
// ca: [ fs.readFileSync(wo.Config.sslCA) ] // only for self-signed certificate: https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
}, server).listen(portHttps, function (err) {
if (err) console.log(err)
else console.log(`Server listening on [${wo.Config.protocol}] https://${wo.Config.host}:${portHttps} with IPv4=${ipv4} for ${server.settings.env} environment`)
})
}
} else if ('http2https' === wo.Config.protocol) {
wo.Config.port = wo.Config.port || 80
webServer = require('http').createServer(server.all('*', function (ask, reply) { /* 错误的API调用进入这里。*/
reply.redirect(`https://${wo.Config.host}`)
})).listen(wo.Config.port, function (err) {
if (err) console.log(err)
else console.log(`Server listening on ${wo.Config.protocol}://${wo.Config.host}:${wo.Config.port} with IPv4=${ipv4} for ${server.settings.env} environment`)
})
}
})()
// ====================
function getMyIp() {
var ipv4=null
try {
var ifaces = os.networkInterfaces()
Object.keys(ifaces).forEach(function (ifname) {
ifaces[ifname].forEach(function (iface) {
if ('IPv4' === iface.family && iface.internal === false) {
// console.log('ip='+iface.address)
ipv4=iface.address
}
})
})
} catch (e) {
console.log('ERROR in getMyIP(): '+e.message)
}
return ipv4
}