Skip to content

Commit 4a70389

Browse files
Add --abs-proxy-base-path for when code-server is not at the root (#6958)
1 parent 39ce82a commit 4a70389

File tree

6 files changed

+43
-4
lines changed

6 files changed

+43
-4
lines changed

docs/guide.md

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
- [Proxying to a Vue app](#proxying-to-a-vue-app)
2121
- [Proxying to an Angular app](#proxying-to-an-angular-app)
2222
- [Proxying to a Svelte app](#proxying-to-a-svelte-app)
23+
- [Prefixing `/absproxy/<port>` with a path](#prefixing-absproxyport-with-a-path)
2324

2425
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
2526
<!-- prettier-ignore-end -->
@@ -432,3 +433,12 @@ const config = {
432433
3. Access app at `<code-server-root>/absproxy/5173/` e.g. `http://localhost:8080/absproxy/5173/
433434

434435
For additional context, see [this Github Issue](https://github.com/sveltejs/kit/issues/2958)
436+
437+
### Prefixing `/absproxy/<port>` with a path
438+
439+
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.
440+
441+
For example: `http://my-code-server.com/user/123/workspace/my-app`. To achieve this result:
442+
443+
1. Start code server with the switch `--abs-proxy-base-path=/user/123/workspace`
444+
2. Follow one of the instructions above for your framework.

src/node/cli.ts

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export interface UserProvidedCodeArgs {
5353
"disable-getting-started-override"?: boolean
5454
"disable-proxy"?: boolean
5555
"session-socket"?: string
56+
"abs-proxy-base-path"?: string
5657
}
5758

5859
/**
@@ -279,6 +280,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
279280
short: "w",
280281
description: "Text to show on login page",
281282
},
283+
"abs-proxy-base-path": {
284+
type: "string",
285+
description: "The base path to prefix to all absproxy requests",
286+
},
282287
}
283288

284289
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {

src/node/routes/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,13 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
121121
app.router.all("/absproxy/:port/:path(.*)?", async (req, res) => {
122122
await pathProxy.proxy(req, res, {
123123
passthroughPath: true,
124+
proxyBasePath: args["abs-proxy-base-path"],
124125
})
125126
})
126127
app.wsRouter.get("/absproxy/:port/:path(.*)?", async (req) => {
127128
await pathProxy.wsProxy(req as pluginapi.WebsocketRequest, {
128129
passthroughPath: true,
130+
proxyBasePath: args["abs-proxy-base-path"],
129131
})
130132
})
131133

src/node/routes/pathProxy.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,23 @@ import { HttpCode, HttpError } from "../../common/http"
55
import { ensureProxyEnabled, authenticated, ensureAuthenticated, ensureOrigin, redirect, self } from "../http"
66
import { proxy as _proxy } from "../proxy"
77

8-
const getProxyTarget = (req: Request): string => {
8+
const getProxyTarget = (
9+
req: Request,
10+
opts?: {
11+
proxyBasePath?: string
12+
},
13+
): string => {
914
// If there is a base path, strip it out.
1015
const base = (req as any).base || ""
11-
return `http://0.0.0.0:${req.params.port}/${req.originalUrl.slice(base.length)}`
16+
return `http://0.0.0.0:${req.params.port}${opts?.proxyBasePath || ""}/${req.originalUrl.slice(base.length)}`
1217
}
1318

1419
export async function proxy(
1520
req: Request,
1621
res: Response,
1722
opts?: {
1823
passthroughPath?: boolean
24+
proxyBasePath?: string
1925
},
2026
): Promise<void> {
2127
ensureProxyEnabled(req)
@@ -38,14 +44,15 @@ export async function proxy(
3844

3945
_proxy.web(req, res, {
4046
ignorePath: true,
41-
target: getProxyTarget(req),
47+
target: getProxyTarget(req, opts),
4248
})
4349
}
4450

4551
export async function wsProxy(
4652
req: pluginapi.WebsocketRequest,
4753
opts?: {
4854
passthroughPath?: boolean
55+
proxyBasePath?: string
4956
},
5057
): Promise<void> {
5158
ensureProxyEnabled(req)
@@ -59,6 +66,6 @@ export async function wsProxy(
5966

6067
_proxy.ws(req, req.ws, req.head, {
6168
ignorePath: true,
62-
target: getProxyTarget(req),
69+
target: getProxyTarget(req, opts),
6370
})
6471
}

test/unit/node/cli.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ describe("parser", () => {
106106

107107
"--disable-proxy",
108108

109+
["--abs-proxy-base-path", "/codeserver/app1"],
110+
109111
["--session-socket", "/tmp/override-code-server-ipc-socket"],
110112

111113
["--host", "0.0.0.0"],
@@ -143,6 +145,7 @@ describe("parser", () => {
143145
version: true,
144146
"bind-addr": "192.169.0.1:8080",
145147
"session-socket": "/tmp/override-code-server-ipc-socket",
148+
"abs-proxy-base-path": "/codeserver/app1",
146149
})
147150
})
148151

test/unit/node/proxy.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,18 @@ describe("proxy", () => {
256256
expect(spy).toHaveBeenCalledWith([test.expected, test.query])
257257
}
258258
})
259+
260+
it("should allow specifying an absproxy path", async () => {
261+
const prefixedPath = `/codeserver/app1${absProxyPath}`
262+
e.get(prefixedPath, (req, res) => {
263+
res.send("app being served behind a prefixed path")
264+
})
265+
codeServer = await integration.setup(["--auth=none", "--abs-proxy-base-path=/codeserver/app1"], "")
266+
const resp = await codeServer.fetch(absProxyPath)
267+
expect(resp.status).toBe(200)
268+
const text = await resp.text()
269+
expect(text).toBe("app being served behind a prefixed path")
270+
})
259271
})
260272

261273
// NOTE@jsjoeio

0 commit comments

Comments
 (0)