feat: introduce --abs-proxy-base-path that allows app proxying while code-server is not server at the root.

This commit is contained in:
rafael_ferreira 2024-08-25 12:01:06 +01:00
parent 39ce82a44d
commit f8a4da7667
6 changed files with 54 additions and 16 deletions

View File

@ -432,3 +432,12 @@ const config = {
3. Access app at `<code-server-root>/absproxy/5173/` e.g. `http://localhost:8080/absproxy/5173/
For additional context, see [this Github Issue](https://github.com/sveltejs/kit/issues/2958)
### Prefixing `/absproxy/<port>` with a path
This is a case where you need to serve an application via `absproxy` as explained above while serving `codeserver` itself from a path other than the root in your domain.
For example: `http://my-code-server.com/user/123/workspace/my-app`. To achieve this result:
1. start code server with the switch `--abs-proxy-base-path=/user/123/workspace`
2. Follow one of the instructions above for your framework.

View File

@ -53,6 +53,7 @@ export interface UserProvidedCodeArgs {
"disable-getting-started-override"?: boolean
"disable-proxy"?: boolean
"session-socket"?: string
"abs-proxy-base-path"?: string
}
/**
@ -279,6 +280,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
short: "w",
description: "Text to show on login page",
},
"abs-proxy-base-path": {
type: "string",
description: "The base path to prefix all absproxy requests",
},
}
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {

View File

@ -121,11 +121,13 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
app.router.all("/absproxy/:port/:path(.*)?", async (req, res) => {
await pathProxy.proxy(req, res, {
passthroughPath: true,
proxyBasePath: args["abs-proxy-base-path"],
})
})
app.wsRouter.get("/absproxy/:port/:path(.*)?", async (req) => {
await pathProxy.wsProxy(req as pluginapi.WebsocketRequest, {
passthroughPath: true,
proxyBasePath: args["abs-proxy-base-path"],
})
})

View File

@ -5,10 +5,15 @@ import { HttpCode, HttpError } from "../../common/http"
import { ensureProxyEnabled, authenticated, ensureAuthenticated, ensureOrigin, redirect, self } from "../http"
import { proxy as _proxy } from "../proxy"
const getProxyTarget = (req: Request): string => {
const getProxyTarget = (
req: Request,
opts?: {
proxyBasePath?: string
},
): string => {
// If there is a base path, strip it out.
const base = (req as any).base || ""
return `http://0.0.0.0:${req.params.port}/${req.originalUrl.slice(base.length)}`
return `http://0.0.0.0:${req.params.port}${opts?.proxyBasePath || ""}/${req.originalUrl.slice(base.length)}`
}
export async function proxy(
@ -16,6 +21,7 @@ export async function proxy(
res: Response,
opts?: {
passthroughPath?: boolean
proxyBasePath?: string
},
): Promise<void> {
ensureProxyEnabled(req)
@ -38,7 +44,7 @@ export async function proxy(
_proxy.web(req, res, {
ignorePath: true,
target: getProxyTarget(req),
target: getProxyTarget(req, opts),
})
}
@ -46,6 +52,7 @@ export async function wsProxy(
req: pluginapi.WebsocketRequest,
opts?: {
passthroughPath?: boolean
proxyBasePath?: string
},
): Promise<void> {
ensureProxyEnabled(req)
@ -59,6 +66,6 @@ export async function wsProxy(
_proxy.ws(req, req.ws, req.head, {
ignorePath: true,
target: getProxyTarget(req),
target: getProxyTarget(req, opts),
})
}

View File

@ -106,6 +106,8 @@ describe("parser", () => {
"--disable-proxy",
["--abs-proxy-base-path", "/codeserver/app1"],
["--session-socket", "/tmp/override-code-server-ipc-socket"],
["--host", "0.0.0.0"],
@ -143,6 +145,7 @@ describe("parser", () => {
version: true,
"bind-addr": "192.169.0.1:8080",
"session-socket": "/tmp/override-code-server-ipc-socket",
"abs-proxy-base-path": "/codeserver/app1",
})
})

View File

@ -256,6 +256,18 @@ describe("proxy", () => {
expect(spy).toHaveBeenCalledWith([test.expected, test.query])
}
})
it("should allow specifying an absproxy path", async () => {
const prefixedPath = `/codeserver/app1${absProxyPath}`
e.get(prefixedPath, (req, res) => {
res.send("app being served behind a prefixed path")
})
codeServer = await integration.setup(["--auth=none", "--abs-proxy-base-path=/codeserver/app1"], "")
const resp = await codeServer.fetch(absProxyPath)
expect(resp.status).toBe(200)
const text = await resp.text()
expect(text).toBe("app being served behind a prefixed path")
})
})
// NOTE@jsjoeio