flaunt-web/service/core/router/index.cjs

156 lines
4.5 KiB
JavaScript

const logger = require('../utils/log.cjs')
const routes = require('./routes.cjs')
const httpProxy = require('http-proxy')
const proxy = httpProxy.createProxyServer({})
const fs = require('fs')
const dist = 'dist'
let mime
import('mime').then((res) => {
mime = res.default
})
let proxys = require('../../../src/proxy.cjs')
const { Exception } = require("sass");
const httpOk = 200
const httpBadRequest = 400
const matchProxy = (request, response) => {
const match = request.url.split('/')[1]
const proxyInfo = proxys['/' + match]
if (proxyInfo) {
const host = request.headers.host;
delete request.headers.host
if (typeof proxyInfo.rewrite === 'function') {
request.url = proxyInfo.rewrite(request.url)
}
proxy.web(request, response, {
target: proxyInfo.target || ("http://" + host),
changeOrigin: proxyInfo.changeOrigin
})
logger.info(`${request.method} ${httpOk} ${request.url}`)
return true
} else {
return null
}
}
const matchRouter = async (request, response) => {
let [url] = request.url.split('?')
let route = routes
let url_sp = url.split('/')
for (let p of url_sp) {
if (!p) {
continue
}
if (route[p]) {
route = route[p]
} else {
return false
}
}
if (typeof route === 'function') {
await route(request, response)
// response.writeHead(httpOk, { 'Content-Type': 'application/json' })
// response.end(JSON.stringify(res))
logger.info(`${request.method} ${httpOk} ${request.url}`)
return true
} else {
return false
}
}
function getMimeType(filePath) {
const ext = filePath.split('.').pop()?.toLowerCase()
const defaultMimes = {
png: 'image/png',
jpg: 'image/jpeg',
jpeg: 'image/jpeg',
gif: 'image/gif',
webp: 'image/webp',
svg: 'image/svg+xml',
ico: 'image/x-icon',
js: 'text/javascript',
css: 'text/css',
html: 'text/html',
json: 'application/json',
woff: 'font/woff',
woff2: 'font/woff2',
ttf: 'font/ttf',
otf: 'font/otf'
}
if (ext && defaultMimes[ext]) {
return defaultMimes[ext]
}
if (mime && typeof mime.getType === 'function') {
return mime.getType(filePath) || 'application/octet-stream'
}
return 'application/octet-stream'
}
const matchFile = async (request, response) => {
return new Promise((resolve) => {
const cleanPath = decodeURIComponent(request.url.split('?')[0])
fs.readFile(dist + cleanPath, (err, file) => {
if (!err) {
const mimetype = getMimeType(cleanPath)
const responseHdeaders = { 'Content-Type': mimetype }
if (cleanPath.endsWith("-sw.js")) {
responseHdeaders["Service-Worker-Allowed"] = '/'
}
response.writeHead(httpOk, responseHdeaders)
response.end(file)
// logger.info(`${request.method} ${httpOk} ${request.url}`)
resolve(true)
} else {
resolve(false)
}
})
})
}
const endIndex = async (request, response) => {
console.log(dist + '/index.html')
fs.readFile(dist + '/index.html', (err, html) => {
if (!err) {
response.writeHead(httpOk, { 'Content-type': 'text/html;charset=utf-8' })
response.end(html)
logger.info(`${request.method} ${httpOk} ${request.url}`)
}
})
}
const matchType = async (request, response) => {
const isRouter = await matchRouter(request, response)
if (isRouter) {
return
}
let isFile = await matchFile(request, response)
if (isFile) {
return
}
let isProxy = matchProxy(request, response)
if (isProxy) {
return
}
await endIndex(request, response)
}
const httpService = async (request, response) => {
try {
await matchType(request, response)
} catch (e) {
response.writeHead(httpBadRequest, { 'Content-Type': 'application/json' })
response.end(
JSON.stringify({
code: -1,
message: String(e)
})
)
logger.info(`${request.method} ${httpBadRequest} ${request.url}`)
}
}
module.exports = {
httpService,
matchType,
matchRouter,
matchFile,
endIndex,
matchProxy,
}