Skip to content

Commit 8e4f3d8

Browse files
committed
Add /absproxy to remove --proxy-path-passthrough
See coder#2222 (comment) Makes way more sense.
1 parent 4bace1a commit 8e4f3d8

File tree

4 files changed

+56
-32
lines changed

4 files changed

+56
-32
lines changed

src/node/cli.ts

-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ export interface Args extends VsArgs {
5050
"show-versions"?: boolean
5151
"uninstall-extension"?: string[]
5252
"proxy-domain"?: string[]
53-
"proxy-path-passthrough"?: boolean
5453
locale?: string
5554
_: string[]
5655
"reuse-window"?: boolean
@@ -173,10 +172,6 @@ const options: Options<Required<Args>> = {
173172
"uninstall-extension": { type: "string[]", description: "Uninstall a VS Code extension by id." },
174173
"show-versions": { type: "boolean", description: "Show VS Code extension versions." },
175174
"proxy-domain": { type: "string[]", description: "Domain used for proxying ports." },
176-
"proxy-path-passthrough": {
177-
type: "boolean",
178-
description: "Whether the path proxy should leave the /proxy/<port> in the request path when proxying.",
179-
},
180175
"ignore-last-opened": {
181176
type: "boolean",
182177
short: "e",

src/node/routes/index.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,25 @@ export const register = async (
103103
app.use("/", domainProxy.router)
104104
wsApp.use("/", domainProxy.wsRouter.router)
105105

106-
app.use("/proxy", proxy.router)
107-
wsApp.use("/proxy", proxy.wsRouter.router)
106+
app.all("/proxy/(:port)(/*)?", (req, res) => {
107+
proxy.proxy(req, res)
108+
})
109+
wsApp.get("/proxy/(:port)(/*)?", (req, res) => {
110+
proxy.wsProxy(req as WebsocketRequest)
111+
})
112+
// These two routes pass through the path directly.
113+
// So the proxied app must be aware it is running
114+
// under /absproxy/<someport>/
115+
app.all("/absproxy/(:port)(/*)?", (req, res) => {
116+
proxy.proxy(req, res, {
117+
passthroughPath: true,
118+
})
119+
})
120+
wsApp.get("/absproxy/(:port)(/*)?", (req, res) => {
121+
proxy.wsProxy(req as WebsocketRequest, {
122+
passthroughPath: true,
123+
})
124+
})
108125

109126
app.use(bodyParser.json())
110127
app.use(bodyParser.urlencoded({ extended: true }))

src/node/routes/pathProxy.ts

+28-18
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1-
import { Request, Router } from "express"
1+
import { Request, Response } from "express"
22
import qs from "qs"
33
import { HttpCode, HttpError } from "../../common/http"
44
import { normalize } from "../../common/util"
55
import { authenticated, ensureAuthenticated, redirect } from "../http"
6-
import { proxy } from "../proxy"
7-
import { Router as WsRouter } from "../wsRouter"
6+
import { proxy as _proxy } from "../proxy"
7+
import { WebsocketRequest } from "../wsRouter"
8+
import * as path from "path"
89

9-
export const router = Router()
10-
11-
const getProxyTarget = (req: Request, passthroughPath: boolean): string => {
10+
const getProxyTarget = (req: Request, passthroughPath?: boolean): string => {
1211
if (passthroughPath) {
1312
return `http://0.0.0.0:${req.params.port}/${req.originalUrl}`
1413
}
1514
const query = qs.stringify(req.query)
1615
return `http://0.0.0.0:${req.params.port}/${req.params[0] || ""}${query ? `?${query}` : ""}`
1716
}
1817

19-
router.all("/(:port)(/*)?", (req, res) => {
18+
export function proxy(
19+
req: Request,
20+
res: Response,
21+
opts?: {
22+
passthroughPath?: boolean
23+
},
24+
): void {
2025
if (!authenticated(req)) {
2126
// If visiting the root (/:port only) redirect to the login page.
2227
if (!req.params[0] || req.params[0] === "/") {
@@ -28,22 +33,27 @@ router.all("/(:port)(/*)?", (req, res) => {
2833
throw new HttpError("Unauthorized", HttpCode.Unauthorized)
2934
}
3035

31-
if (!req.args["proxy-path-passthrough"]) {
36+
if (!opts?.passthroughPath) {
3237
// Absolute redirects need to be based on the subpath when rewriting.
33-
;(req as any).base = `${req.baseUrl}/${req.params.port}`
38+
// See proxy.ts.
39+
;(req as any).base = req.path.split(path.sep).slice(0, 3).join(path.sep)
3440
}
3541

36-
proxy.web(req, res, {
42+
_proxy.web(req, res, {
3743
ignorePath: true,
38-
target: getProxyTarget(req, req.args["proxy-path-passthrough"] || false),
44+
target: getProxyTarget(req, opts?.passthroughPath),
3945
})
40-
})
41-
42-
export const wsRouter = WsRouter()
46+
}
4347

44-
wsRouter.ws("/(:port)(/*)?", ensureAuthenticated, (req) => {
45-
proxy.ws(req, req.ws, req.head, {
48+
export function wsProxy(
49+
req: WebsocketRequest,
50+
opts?: {
51+
passthroughPath?: boolean
52+
},
53+
): void {
54+
ensureAuthenticated(req)
55+
_proxy.ws(req, req.ws, req.head, {
4656
ignorePath: true,
47-
target: getProxyTarget(req, req.args["proxy-path-passthrough"] || false),
57+
target: getProxyTarget(req, opts?.passthroughPath),
4858
})
49-
})
59+
}

test/proxy.test.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ describe("proxy", () => {
77
const nhooyrDevServer = new httpserver.HttpServer()
88
let codeServer: httpserver.HttpServer | undefined
99
let proxyPath: string
10+
let absProxyPath: string
1011
let e: express.Express
1112

1213
beforeAll(async () => {
1314
await nhooyrDevServer.listen((req, res) => {
1415
e(req, res)
1516
})
1617
proxyPath = `/proxy/${nhooyrDevServer.port()}/wsup`
18+
absProxyPath = proxyPath.replace("/proxy/", "/absproxy/")
1719
})
1820

1921
afterAll(async () => {
@@ -43,11 +45,11 @@ describe("proxy", () => {
4345
})
4446

4547
it("should not rewrite the base path", async () => {
46-
e.get(proxyPath, (req, res) => {
48+
e.get(absProxyPath, (req, res) => {
4749
res.json("joe is the best")
4850
})
49-
;[, , codeServer] = await integration.setup(["--auth=none", "--proxy-path-passthrough=true"], "")
50-
const resp = await codeServer.fetch(proxyPath)
51+
;[, , codeServer] = await integration.setup(["--auth=none"], "")
52+
const resp = await codeServer.fetch(absProxyPath)
5153
expect(resp.status).toBe(200)
5254
const json = await resp.json()
5355
expect(json).toBe("joe is the best")
@@ -69,15 +71,15 @@ describe("proxy", () => {
6971
})
7072

7173
it("should not rewrite redirects", async () => {
72-
const finalePath = proxyPath.replace("/wsup", "/finale")
73-
e.post(proxyPath, (req, res) => {
74+
const finalePath = absProxyPath.replace("/wsup", "/finale")
75+
e.post(absProxyPath, (req, res) => {
7476
res.redirect(307, finalePath)
7577
})
7678
e.post(finalePath, (req, res) => {
7779
res.json("redirect success")
7880
})
79-
;[, , codeServer] = await integration.setup(["--auth=none", "--proxy-path-passthrough=true"], "")
80-
const resp = await codeServer.fetch(proxyPath, {
81+
;[, , codeServer] = await integration.setup(["--auth=none"], "")
82+
const resp = await codeServer.fetch(absProxyPath, {
8183
method: "POST",
8284
})
8385
expect(resp.status).toBe(200)

0 commit comments

Comments
 (0)