add https support

This commit is contained in:
lincomatic
2026-03-20 09:21:02 -07:00
parent 2f07ae2e5c
commit 209e17fcd4
3 changed files with 43 additions and 5 deletions
+5
View File
@@ -148,6 +148,10 @@ Edit `config.json`:
```json
{
"port": 3000,
"https": {
"cert": "/path/to/cert.pem",
"key": "/path/to/key.pem"
},
"mqtt": {
"broker": "mqtt://localhost:1883",
"topic": "meshcore/+/+/packets"
@@ -178,6 +182,7 @@ Edit `config.json`:
| Field | Description |
|-------|-------------|
| `port` | HTTP server port (default: 3000) |
| `https.cert` / `https.key` | Optional PEM cert/key paths to enable native HTTPS (falls back to HTTP if omitted or unreadable) |
| `mqtt.broker` | Local MQTT broker URL. Set to `""` to disable |
| `mqtt.topic` | MQTT topic pattern for packet ingestion |
| `mqttSources` | Array of external MQTT broker connections (optional) |
+4
View File
@@ -1,5 +1,9 @@
{
"port": 3000,
"https": {
"cert": "/path/to/cert.pem",
"key": "/path/to/key.pem"
},
"mqtt": {
"broker": "mqtt://localhost:1883",
"topic": "meshcore/+/+/packets"
+34 -5
View File
@@ -2,9 +2,11 @@
const express = require('express');
const http = require('http');
const https = require('https');
const { WebSocketServer } = require('ws');
const mqtt = require('mqtt');
const path = require('path');
const fs = require('fs');
const config = require('./config.json');
const decoder = require('./decoder');
const crypto = require('crypto');
@@ -137,7 +139,29 @@ const cache = new TTLCache();
db.seed();
const app = express();
const server = http.createServer(app);
function createServer(app, cfg) {
const tls = cfg.https || {};
if (!tls.cert || !tls.key) {
return { server: http.createServer(app), isHttps: false };
}
try {
const certPath = path.resolve(tls.cert);
const keyPath = path.resolve(tls.key);
const options = {
cert: fs.readFileSync(certPath),
key: fs.readFileSync(keyPath),
};
console.log(`[https] enabled (cert: ${certPath}, key: ${keyPath})`);
return { server: https.createServer(options, app), isHttps: true };
} catch (e) {
console.error(`[https] failed to load TLS cert/key, falling back to HTTP: ${e.message}`);
return { server: http.createServer(app), isHttps: false };
}
}
const { server, isHttps } = createServer(app, config);
// --- Performance Instrumentation ---
const perfStats = {
@@ -2142,8 +2166,10 @@ app.get('/{*splat}', (req, res) => {
});
// --- Start ---
server.listen(process.env.PORT || config.port, () => {
console.log(`MeshCore Analyzer running on http://localhost:${config.port}`);
const listenPort = process.env.PORT || config.port;
server.listen(listenPort, () => {
const protocol = isHttps ? 'https' : 'http';
console.log(`MeshCore Analyzer running on ${protocol}://localhost:${listenPort}`);
// Pre-warm expensive caches on startup
setTimeout(() => {
const t0 = Date.now();
@@ -2179,7 +2205,8 @@ server.listen(process.env.PORT || config.port, () => {
console.log(`[pre-warm] subpaths: ${Date.now() - t0}ms`);
// Pre-warm other heavy analytics endpoints via self-request
const port = process.env.PORT || config.port;
const port = listenPort;
const warmClient = isHttps ? https : http;
const warmEndpoints = [
'/api/analytics/rf',
'/api/analytics/topology',
@@ -2195,7 +2222,9 @@ server.listen(process.env.PORT || config.port, () => {
return;
}
const ep = warmEndpoints[warmed++];
http.get(`http://127.0.0.1:${port}${ep}`, (res) => {
const requestOptions = { hostname: '127.0.0.1', port, path: ep };
if (isHttps) requestOptions.rejectUnauthorized = false;
warmClient.get(requestOptions, (res) => {
res.resume();
res.on('end', warmNext);
}).on('error', warmNext);