Skip to content

Commit

Permalink
Add --abs-proxy-base-path for when code-server is not at the root (#6958
Browse files Browse the repository at this point in the history
)
  • Loading branch information
rafaelnferreira committed Aug 26, 2024
1 parent 39ce82a commit 4a70389
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 4 deletions.
10 changes: 10 additions & 0 deletions docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [Proxying to a Vue app](#proxying-to-a-vue-app)
- [Proxying to an Angular app](#proxying-to-an-angular-app)
- [Proxying to a Svelte app](#proxying-to-a-svelte-app)
- [Prefixing `/absproxy/<port>` with a path](#prefixing-absproxyport-with-a-path)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
Expand Down Expand Up @@ -432,3 +433,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.
5 changes: 5 additions & 0 deletions src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface UserProvidedCodeArgs {
"disable-getting-started-override"?: boolean
"disable-proxy"?: boolean
"session-socket"?: string
"abs-proxy-base-path"?: string
}

/**
Expand Down Expand Up @@ -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 to all absproxy requests",
},
}

export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {
Expand Down
2 changes: 2 additions & 0 deletions src/node/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
})
})

Expand Down
15 changes: 11 additions & 4 deletions src/node/routes/pathProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ 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(
req: Request,
res: Response,
opts?: {
passthroughPath?: boolean
proxyBasePath?: string
},
): Promise<void> {
ensureProxyEnabled(req)
Expand All @@ -38,14 +44,15 @@ export async function proxy(

_proxy.web(req, res, {
ignorePath: true,
target: getProxyTarget(req),
target: getProxyTarget(req, opts),
})
}

export async function wsProxy(
req: pluginapi.WebsocketRequest,
opts?: {
passthroughPath?: boolean
proxyBasePath?: string
},
): Promise<void> {
ensureProxyEnabled(req)
Expand All @@ -59,6 +66,6 @@ export async function wsProxy(

_proxy.ws(req, req.ws, req.head, {
ignorePath: true,
target: getProxyTarget(req),
target: getProxyTarget(req, opts),
})
}
3 changes: 3 additions & 0 deletions test/unit/node/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down Expand Up @@ -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",
})
})

Expand Down
12 changes: 12 additions & 0 deletions test/unit/node/proxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 4a70389

Please sign in to comment.