wo-base-webserver/server.js

212 lines
7.5 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 Config = Object.assign(
{
commanderOptions: [
// 命令行里可以接受的参数。将传给 config.js 里的 commander。每个参数的定义格式是 [参数名,参数键,描述]后两者用于传给commander取值后覆盖掉Config里的同名变量。
['protocol', '-P, --protocol <string>', 'Web Server protocol: http|https|httpall.'],
['host', '-h, --host <string>', 'Host IP or domain name, default to localhost.'],
['port', '-p, --port <number>', 'HTTP port number.'],
['from', '-f, --from <string>', 'Seed list such as \'["http://ip_or_dn:port"]\' or "noseed" to disable seeding.'],
['env', '-e, --env <string>', 'Runtime environment: production | development.'],
],
// 最基础的必须的默认配置,如果用户什么也没有提供
protocol: 'http',
host: 'localhost',
from: './dist', // local path to serve as webroot
// 如果使用虚拟主机
/*
vhosts: [
{ webroot: 'dist', webindex: 'index.html', domainList: ['']}
],
*/
},
require('so.sysconfig')
)
if (typeof Config.ssl === 'string') {
Config.ssl = eval(`(${Config.ssl})`)
}
;(function serve() {
console.log('★★★★★★★★ Starting Server ★★★★★★★★')
const express = require('express')
const server = express()
const webtoken = require('so.webtoken')
/*** 通用中间件 ***/
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')())
const Multer = require('multer')
server.use(
Multer({
//dest:'./File/', // 这样,不能自定义文件名。
storage: Multer.diskStorage({
destination: function (req, file, cb) {
// 如果直接提供字符串Multer会负责创建该目录。如果提供函数你要负责确保该目录存在。
let folder = './upload/' // 目录是相对于本应用的入口js的即相对于 server.js 的位置。
cb(null, folder)
},
filename: function (req, file, cb) {
// 注意req.body 也许还没有信息因为这取决于客户端发送body和file的顺序。
let ext = file.originalname.replace(/^.*\.(\w+)$/, '$1')
let _passtokenSource = webtoken.verifyToken(req.headers._passtoken, Config.tokenKey) || {}
let filename = `${req.path.replace(/^\/api\d*/, '')}_${_passtokenSource.uuid}_${Date.now()}.${ext}`
cb(null, filename)
},
}),
//fileFilter:function(req, file, cb) {},
limits: { fileSize: 10485760 },
}).single('file')
)
/*** 路由 ***/
// vhost 匹配了域名就执行不匹配就next()
// express.static 找到了具体文件就返回找不到就next()
// 所以,如果 vhost匹配了域名且static找到了文件就结束了。如果 vhost 匹配了域名但static找不到文件就继续往下。
if (!Config.vhosts) {
server.use(
express.static(path.join(process.cwd(), Config.from), {
index: 'index.html',
})
)
// server.use(require('serve-favicon')(path.join(process.cwd(), 'public', 'favicon.ico'))) // uncomment after placing your favicon in /public
} else {
let vhost = require('vhost')
for (let h of Config.vhosts) {
for (let domain of h.domainList) {
server.use(
vhost(
domain,
express.static(path.join(process.cwd(), h.webroot), {
index: h.webindex,
})
)
)
}
}
}
/*** 路由 ***/
//var router = express.Router()
//router.get('/path', function(req,res) { res.redirect('target') })
//server.use(router)
/*** 启动 Web 服务 ***/
let webServer
let ipv4 = getMyIp()
let portHttp = Config.port || 80
let portHttps = Config.port || 443
if ('http' === Config.protocol) {
webServer = require('http')
.createServer(server)
.listen(portHttp, function (err) {
if (err) console.log(err)
else
console.log(
`[${new Date().toJSON()}] Server listening on ${Config.protocol}://${Config.host}:${portHttp} with IPv4=${ipv4} for ${
server.settings.env
} environment`
)
})
} else if ('https' === Config.protocol) {
webServer = require('https')
.createServer(
{
key: fs.readFileSync(Config.ssl.file.key),
cert: fs.readFileSync(Config.ssl.file.cert),
// ca: [ fs.readFileSync(Config.ssl.file.ca) ] // 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(
`[${new Date().toJSON()}] Server listening on ${Config.protocol}://${Config.host}:${portHttps} with IPv4=${ipv4} for ${
server.settings.env
} environment`
)
})
} else if ('httpall' === Config.protocol) {
portHttp = 80
require('http')
.createServer(
server.all('*', function (ask, reply) {
reply.redirect(`https://${Config.host}:${portHttps}`)
})
)
.listen(portHttp, function (err) {
if (err) console.log(err)
else
console.log(
`[${new Date().toJSON()}] Server redirecting from [${Config.protocol}] http://${Config.host}:${portHttp} with IPv4=${ipv4} for ${
server.settings.env
} environment`
)
})
webServer = require('https')
.createServer(
{
key: fs.readFileSync(Config.ssl.file.key),
cert: fs.readFileSync(Config.ssl.file.cert),
// ca: [ fs.readFileSync(Config.ssl.file.ca) ] // 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(
`[${new Date().toJSON()}] Server listening on [${Config.protocol}] https://${Config.host}:${portHttps} with IPv4=${ipv4} for ${
server.settings.env
} environment`
)
})
} else if ('http2https' === Config.protocol) {
webServer = require('http')
.createServer(
server.all('*', function (ask, reply) {
/* 错误的API调用进入这里。*/ reply.redirect(`https://${Config.host}`)
})
)
.listen(portHttp, function (err) {
if (err) console.log(err)
else
console.log(
`[${new Date().toJSON()}] Server listening on ${Config.protocol}://${Config.host}:${portHttp} with IPv4=${ipv4} for ${
server.settings.env
} environment`
)
})
}
return webServer
})()
// ====================
function getMyIp() {
const os = require('os')
let ipv4 = null
try {
let 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
}