mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
Add support for extra proxies via external file
Allows defining custom reverse proxy routes via an `extra-proxies.js` file at the project root. The Gateway loads these configurations on startup. Additionally, the Nginx gateway manager no longer applies default prefix-stripping rewrites. Explicit `pathRewrite` rules are now required if prefix stripping is needed for any proxied service, including those defined externally.
This commit is contained in:
parent
80d84b3e17
commit
1b6d1c74a1
7
packages/server/extra-proxies.js
Normal file
7
packages/server/extra-proxies.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default {
|
||||||
|
"/spectrum/*": {
|
||||||
|
target: process.env.SPECTRUM_API ?? "https://live.ragestudio.net",
|
||||||
|
pathRewrite: { "^/spectrum/(.*)": "/$1", "^/spectrum": "/" },
|
||||||
|
websocket: true,
|
||||||
|
},
|
||||||
|
}
|
@ -165,6 +165,92 @@ export default class Gateway {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads and registers additional proxy routes from ../../extra-proxies.js
|
||||||
|
*/
|
||||||
|
async registerExtraProxies() {
|
||||||
|
try {
|
||||||
|
// Dynamic import is relative to the current file.
|
||||||
|
// extra-proxies.js can be CJS (module.exports = ...) or ESM (export default ...)
|
||||||
|
const extraProxiesModule = require(
|
||||||
|
path.resolve(process.cwd(), "extra-proxies.js"),
|
||||||
|
)
|
||||||
|
const extraProxies = extraProxiesModule.default // Node's CJS/ESM interop puts module.exports on .default
|
||||||
|
|
||||||
|
if (
|
||||||
|
!extraProxies ||
|
||||||
|
typeof extraProxies !== "object" ||
|
||||||
|
Object.keys(extraProxies).length === 0
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
"[Gateway] No extra proxies defined in `extra-proxies.js`, file is empty, or format is invalid. Skipping.",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[Gateway] Registering extra proxies from 'extra-proxies.js'...`,
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const proxyPathKey in extraProxies) {
|
||||||
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(
|
||||||
|
extraProxies,
|
||||||
|
proxyPathKey,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const config = extraProxies[proxyPathKey]
|
||||||
|
if (!config || typeof config.target !== "string") {
|
||||||
|
console.warn(
|
||||||
|
`[Gateway] Skipping invalid extra proxy config for path: '${proxyPathKey}' in 'extra-proxies.js'. Target is missing or not a string.`,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let registrationPath = proxyPathKey
|
||||||
|
|
||||||
|
// Normalize paths ending with /*
|
||||||
|
// e.g., "/spectrum/*" becomes "/spectrum"
|
||||||
|
// e.g., "/*" becomes "/"
|
||||||
|
if (registrationPath.endsWith("/*")) {
|
||||||
|
registrationPath = registrationPath.slice(0, -2)
|
||||||
|
if (registrationPath === "") {
|
||||||
|
registrationPath = "/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[Gateway] Registering extra proxy: '${proxyPathKey}' (as '${registrationPath}') -> ${config.target}`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await this.gateway.register({
|
||||||
|
serviceId: `extra-proxy:${registrationPath}`, // Unique ID for this proxy rule
|
||||||
|
path: registrationPath,
|
||||||
|
target: config.target,
|
||||||
|
pathRewrite: config.pathRewrite, // undefined if not present
|
||||||
|
websocket: !!config.websocket, // false if not present or falsy
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Handle cases where the extra-proxies.js file might not exist
|
||||||
|
if (
|
||||||
|
error.code === "ERR_MODULE_NOT_FOUND" ||
|
||||||
|
(error.message &&
|
||||||
|
error.message.toLowerCase().includes("cannot find module"))
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
"[Gateway] `extra-proxies.js` not found. Skipping extra proxy registration.",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
"[Gateway] Error loading or registering extra proxies from `extra-proxies.js`:",
|
||||||
|
error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle both router and websocket registration requests from services
|
* Handle both router and websocket registration requests from services
|
||||||
* @param {Service} service - Service registering a route or websocket
|
* @param {Service} service - Service registering a route or websocket
|
||||||
@ -304,6 +390,9 @@ export default class Gateway {
|
|||||||
await this.gateway.initialize()
|
await this.gateway.initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register any externally defined proxies before services start
|
||||||
|
await this.registerExtraProxies()
|
||||||
|
|
||||||
// Watch for service state changes
|
// Watch for service state changes
|
||||||
Observable.observe(this.serviceRegistry, (changes) => {
|
Observable.observe(this.serviceRegistry, (changes) => {
|
||||||
this.checkAllServicesReady()
|
this.checkAllServicesReady()
|
||||||
|
@ -371,19 +371,12 @@ http {
|
|||||||
|
|
||||||
if (route.pathRewrite && Object.keys(route.pathRewrite).length > 0) {
|
if (route.pathRewrite && Object.keys(route.pathRewrite).length > 0) {
|
||||||
rewriteConfig += "# Path rewrite rules\n"
|
rewriteConfig += "# Path rewrite rules\n"
|
||||||
|
|
||||||
for (const [pattern, replacement] of Object.entries(
|
for (const [pattern, replacement] of Object.entries(
|
||||||
route.pathRewrite,
|
route.pathRewrite,
|
||||||
)) {
|
)) {
|
||||||
// Improved rewrite pattern that preserves query parameters
|
// Improved rewrite pattern that preserves query parameters
|
||||||
rewriteConfig += `\trewrite ${pattern} ${replacement}$is_args$args break;`
|
rewriteConfig += `\nrewrite ${pattern} ${replacement} break;`
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If no explicit rewrite is defined, but we need to strip the path prefix,
|
|
||||||
// Generate a default rewrite that preserves the URL structure
|
|
||||||
if (path !== "/") {
|
|
||||||
rewriteConfig += "# Default path rewrite to strip prefix\n"
|
|
||||||
rewriteConfig += `\trewrite ^${path}(/.*)$ $1$is_args$args break;\n`
|
|
||||||
rewriteConfig += `\trewrite ^${path}$ / break;`
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,6 +416,8 @@ ${locationDirective} {
|
|||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
${rewriteConfig}
|
||||||
|
|
||||||
# Proxy pass to service
|
# Proxy pass to service
|
||||||
proxy_pass ${route.target};
|
proxy_pass ${route.target};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user