@samitouri / QOSami-HFS / commits / 4b8a7f42

fix: (regression 0.52.6) reverse-proxy with prefix was not working without roots

Massimo Melina committed May 12, 2024 at 17:04 UTC 4b8a7f4266f687d6e9bce2a662f96d99cd64de7d
1 file changed +18 -15
src/roots.ts
+18 -15
@@ -1,5 +1,5 @@
1 import { defineConfig } from './config'
2 -import { ADMIN_URI, API_URI, CFG, isLocalHost, makeMatcher, removeStarting, SPECIAL_URI } from './misc'
2 +import { ADMIN_URI, API_URI, Callback, CFG, isLocalHost, makeMatcher, removeStarting, SPECIAL_URI } from './misc'
3 import Koa from 'koa'
4 import { disconnect } from './connections'
5 import _ from 'lodash'
@@ -21,10 +21,11 @@ export const rootsMiddleware: Koa.Middleware = (ctx, next) =>
21 let params: undefined | typeof ctx.state.params | typeof ctx.query // undefined if we are not going to work on api parameters
22 if (ctx.path.startsWith(SPECIAL_URI)) { // special uris should be excluded...
23 if (!ctx.path.startsWith(API_URI)) return // ...unless it's an api
24 + params = ctx.state.params || ctx.query // for api we'll translate params
25 + changeUriParams(v => removeStarting(ctx.state.revProxyPath, v)) // removal must be done before adding the root
26 let { referer } = ctx.headers
27 referer &&= new URL(referer).pathname
28 if (referer?.startsWith(ctx.state.revProxyPath + ADMIN_URI)) return // exclude apis for admin-panel
27 - params = ctx.state.params || ctx.query // for api we'll translate params
29 }
30 if (_.isEmpty(roots.get())) return
31 const host2root = roots.compiled()
@@ -36,20 +37,22 @@ export const rootsMiddleware: Koa.Middleware = (ctx, next) =>
37 disconnect(ctx, 'bad-domain')
38 return true // true will avoid calling next
39 }
39 - if (!params) {
40 - ctx.path = join(root, ctx.path, '')
41 - return
42 - }
43 - for (const [k,v] of Object.entries(params))
44 - if (k.startsWith('uri'))
45 - params[k] = Array.isArray(v) ? v.map(x => join(root, x)) : join(root, v)
40 + changeUriParams(v => join(root, v))
41 + if (!params)
42 + ctx.path = join(root, ctx.path)
43
47 - function join(a: string, b: any, removePrefix=ctx.state.revProxyPath) {
48 - return a + (b && b[0] !== '/' ? '/' : '')
49 - + removeStarting(removePrefix, b) // removal must be done before adding the root
44 + function changeUriParams(cb: Callback<string, string>) {
45 + if (!params) return
46 + for (const [k, v] of Object.entries(params))
47 + if (k.startsWith('uri'))
48 + params[k] = Array.isArray(v) ? v.map(cb) : cb(v)
49 }
50 })() || next()
51
53 -function join(a: string, b: any) {
54 - return a + (b && b[0] !== '/' ? '/' : '') + b
55 -}
\ No newline at end of file
52 +function join(a: string, b: string, joiner='/') { // similar to path.join but OS independent
53 + if (!b) return a
54 + if (!a) return b
55 + const ends = a.at(-1) === joiner
56 + const starts = b[0] === joiner
57 + return a + (!ends && !starts ? joiner + b : ends && starts ? b.slice(1) : b)
58 +}