119 lines
3.7 KiB
JavaScript
119 lines
3.7 KiB
JavaScript
import {createReadStream} from 'fs';
|
|
import {createServer, ServerResponse} from 'http';
|
|
import {dirname, join} from 'path';
|
|
|
|
import {arrayFlatten, Latus} from '@latus/core';
|
|
import express from 'express';
|
|
import httpProxy from 'http-proxy';
|
|
|
|
import clientPlugins from './build/client-plugins';
|
|
import configMiddleware from './config-middleware';
|
|
|
|
const {
|
|
HTTP_HOST,
|
|
HTTP_PORT,
|
|
} = process.env;
|
|
|
|
export const createHttpServer = async (latus) => {
|
|
const {
|
|
config: {
|
|
'@latus/http/server': {
|
|
build,
|
|
devPort,
|
|
host,
|
|
port,
|
|
trust,
|
|
},
|
|
},
|
|
} = latus;
|
|
const app = express();
|
|
app.set('trust proxy', trust);
|
|
const httpServer = createServer(app);
|
|
latus.set('%http', httpServer);
|
|
httpServer.app = app;
|
|
const requestMiddleware = (req, res, next) => {
|
|
latus.invokeMiddleware('@latus/http/server/request', req, res, next);
|
|
};
|
|
const routes = arrayFlatten(latus.invokeFlat('@latus/http/routes'));
|
|
routes.forEach(({method, path, handler}) => app[method](path, requestMiddleware, handler));
|
|
// Serve latus.
|
|
app.get('/latus.config.js', requestMiddleware, configMiddleware(latus));
|
|
app.use(express.static(join(process.cwd(), build)));
|
|
// eslint-disable-next-line no-eval
|
|
if ('production' !== eval('process.env.NODE_ENV')) {
|
|
const middlewares = Object.keys(await clientPlugins(latus))
|
|
.map((path) => Latus.runtimePath(path))
|
|
.filter((path) => !!Latus.runtimePath(`${path}/test`))
|
|
.map((path) => {
|
|
// eslint-disable-next-line no-eval
|
|
const staticPath = dirname(eval('require').resolve(path));
|
|
return express.static(staticPath);
|
|
});
|
|
for (let i = 0; i < middlewares.length; i++) {
|
|
app.use(middlewares[i]);
|
|
}
|
|
const proxy = httpProxy.createProxyServer({
|
|
secure: false,
|
|
target: `http://127.0.0.1:${devPort}`,
|
|
});
|
|
proxy.on('proxyRes', async (proxyRes, req, res) => {
|
|
if ('text/html; charset=UTF-8' === proxyRes.headers['content-type']) {
|
|
requestMiddleware(req, res, () => {
|
|
res.setHeader('Content-Type', proxyRes.headers['content-type']);
|
|
proxyRes.pipe(res);
|
|
});
|
|
}
|
|
else {
|
|
res.setHeader(
|
|
'Content-Type',
|
|
// ???
|
|
'/__webpack_hmr' === req.url ? 'text/event-stream' : proxyRes.headers['content-type'],
|
|
);
|
|
proxyRes.pipe(res);
|
|
}
|
|
});
|
|
proxy.on('error', (err, req, res) => {
|
|
if (res instanceof ServerResponse) {
|
|
res.status(502).end('Bad Gateway (WDS)');
|
|
}
|
|
});
|
|
app.all('*', (req, res) => proxy.web(req, res, {selfHandleResponse: true}));
|
|
httpServer.on('upgrade', (req, socket, head) => proxy.ws(req, socket, head));
|
|
httpServer.on('close', () => proxy.close());
|
|
}
|
|
else {
|
|
app.use(express.static(join(__dirname, 'client')));
|
|
app.get('*', async (req, res) => {
|
|
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
|
|
const stream = createReadStream(join(process.cwd(), build, 'index.html'));
|
|
stream.pipe(res);
|
|
});
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
const serverPort = HTTP_PORT || port;
|
|
const serverHost = HTTP_HOST || host;
|
|
const args = [serverPort];
|
|
if (serverHost) {
|
|
args.push(serverHost);
|
|
}
|
|
args.push(async (error) => {
|
|
if (error) {
|
|
return reject(error);
|
|
}
|
|
await Promise.all(latus.invokeFlat('@latus/http/server/up', httpServer));
|
|
process.stdout.write(`HTTP server up @ ${HTTP_HOST || host}:${HTTP_PORT || port}!\n`);
|
|
resolve();
|
|
return undefined;
|
|
});
|
|
httpServer.listen(...args);
|
|
});
|
|
};
|
|
|
|
export const destroyHttpServer = (httpServer) => {
|
|
if (!httpServer) {
|
|
return;
|
|
}
|
|
httpServer.close();
|
|
process.stdout.write('HTTP server down!\n');
|
|
};
|