172 lines
5.0 KiB
JavaScript
172 lines
5.0 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])
|
|
let targetPath = dist + cleanPath
|
|
if (!fs.existsSync(targetPath)) {
|
|
const mappedPath = dist + cleanPath.replace(/^\/(src\/public|public|src)/, '')
|
|
if (fs.existsSync(mappedPath)) {
|
|
targetPath = mappedPath
|
|
}
|
|
}
|
|
fs.readFile(targetPath, (err, file) => {
|
|
if (!err) {
|
|
const mimetype = getMimeType(cleanPath)
|
|
const responseHeaders = {
|
|
'Content-Type': mimetype,
|
|
'Access-Control-Allow-Origin': '*'
|
|
}
|
|
if (cleanPath.endsWith("-sw.js")) {
|
|
responseHeaders["Service-Worker-Allowed"] = '/'
|
|
}
|
|
response.writeHead(httpOk, responseHeaders)
|
|
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',
|
|
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
'Pragma': 'no-cache',
|
|
'Expires': '0',
|
|
'Access-Control-Allow-Origin': '*'
|
|
})
|
|
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,
|
|
}
|