Skip to content

Commit 8c7a3f2

Browse files
authored
Set remote authority on frontend (#25)
Trying to determine the remote authority on the backend is brittle because it does not work behind reverse proxies unless they send the right headers containing information about the proxied source. We could require users add the relevant configuration or provide the remote authority via a flag but neither are user-friendly options. We can make it work out of the box by changing the frontend to make requests to its current address (which is what we try to set the remote authority to anyway). This actually already happens for the most part except in some UI and logs although recent issues suggest there might be other problems which should be entirely resolved by setting this on the frontend. In other words, the remote authority we set on the backend should never be used so we set it to something invalid to ensure we notice (the alternative is to rip it out but that is probably a bigger patch thus generating more conflicts). One scenario where we might want to set the remote authority from the backend is if the frontend is served from a different location than the backend but that is not supported behavior at the moment. Even if we did support this we still cannot determine the authority from the backend (even for non-proxy scenarios in this case) and would need to add a flag for it so this change would still be necessary. coder/code-server#4604 coder/code-server#4607 coder/code-server#4608
1 parent 478224a commit 8c7a3f2

File tree

4 files changed

+16
-36
lines changed

4 files changed

+16
-36
lines changed

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
"@vscode/vscode-languagedetection": "1.0.21",
6666
"applicationinsights": "1.0.8",
6767
"cookie": "^0.4.1",
68-
"forwarded-parse": "^2.1.2",
6968
"graceful-fs": "4.2.8",
7069
"http-proxy-agent": "^2.1.0",
7170
"https-proxy-agent": "^2.2.3",

src/vs/code/browser/workbench/workbench.ts

+6
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,12 @@ class WindowIndicator implements IWindowIndicator {
559559
// Finally create workbench
560560
create(document.body, {
561561
...config,
562+
/**
563+
* Ensure the remote authority points to the current address since we cannot
564+
* determine this reliably on the backend.
565+
* @author coder
566+
*/
567+
remoteAuthority: location.host,
562568
/**
563569
* Override relative URLs in the product configuration against the window
564570
* location as necessary. Only paths that must be absolute need to be

src/vs/server/webClientServer.ts

+10-30
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import * as url from 'url';
99
import * as util from 'util';
1010
import * as cookie from 'cookie';
1111
import * as crypto from 'crypto';
12-
import parseForwardHeader = require('forwarded-parse');
1312
import { isEqualOrParent, sanitizeFilePath } from 'vs/base/common/extpath';
1413
import { getMediaMime } from 'vs/base/common/mime';
1514
import { isLinux } from 'vs/base/common/platform';
@@ -27,7 +26,6 @@ import type { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.a
2726
import { editorBackground, editorForeground } from 'vs/platform/theme/common/colorRegistry';
2827
import { ClientTheme, getOriginalUrl, HTTPNotFoundError, relativePath, relativeRoot, WebManifest } from 'vs/server/common/net';
2928
import { IServerThemeService } from 'vs/server/serverThemeService';
30-
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
3129

3230
const textMimeType = {
3331
'.html': 'text/html',
@@ -167,29 +165,6 @@ export class WebClientServer {
167165

168166
private _iconSizes = [192, 512];
169167

170-
private getRemoteAuthority(req: http.IncomingMessage): URL {
171-
if (req.headers.forwarded) {
172-
const [parsedHeader] = parseForwardHeader(req.headers.forwarded);
173-
return new URL(`${parsedHeader.proto}://${parsedHeader.host}`);
174-
}
175-
176-
/* Return first non-empty header. */
177-
const parseHeaders = (headerNames: string[]): string | undefined => {
178-
for (const headerName of headerNames) {
179-
const header = req.headers[headerName]?.toString();
180-
if (!isFalsyOrWhitespace(header)) {
181-
return header;
182-
}
183-
}
184-
return undefined;
185-
};
186-
187-
const proto = parseHeaders(['X-Forwarded-Proto']) || 'http';
188-
const host = parseHeaders(['X-Forwarded-Host', 'host']) || 'localhost';
189-
190-
return new URL(`${proto}://${host}`);
191-
}
192-
193168
/**
194169
* PWA manifest file. This informs the browser that the app may be installed.
195170
*/
@@ -292,9 +267,15 @@ export class WebClientServer {
292267
// return this.serveError(req, res, 403, `Forbidden.`, parsedUrl);
293268
// }
294269

295-
const remoteAuthority = this.getRemoteAuthority(req);
296-
297-
const transformer = createRemoteURITransformer(remoteAuthority.host);
270+
/**
271+
* It is not possible to reliably detect the remote authority on the server
272+
* in all cases. Set this to something invalid to make sure we catch code
273+
* that is using this when it should not.
274+
*
275+
* @author coder
276+
*/
277+
const remoteAuthority = 'remote';
278+
const transformer = createRemoteURITransformer(remoteAuthority);
298279
const { workspacePath, isFolder } = await this._getWorkspaceFromCLI();
299280

300281
function escapeAttribute(value: string): string {
@@ -343,8 +324,7 @@ export class WebClientServer {
343324
},
344325
folderUri: (workspacePath && isFolder) ? transformer.transformOutgoing(URI.file(workspacePath)) : undefined,
345326
workspaceUri: (workspacePath && !isFolder) ? transformer.transformOutgoing(URI.file(workspacePath)) : undefined,
346-
// Add port to prevent client-side mismatch for reverse proxies.
347-
remoteAuthority: `${remoteAuthority.hostname}:${remoteAuthority.port || (remoteAuthority.protocol === 'https:' ? '443' : '80')}`,
327+
remoteAuthority,
348328
_wrapWebWorkerExtHostInIframe,
349329
developmentOptions: {
350330
enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined,

yarn.lock

-5
Original file line numberDiff line numberDiff line change
@@ -4348,11 +4348,6 @@ form-data@~2.3.2:
43484348
combined-stream "^1.0.6"
43494349
mime-types "^2.1.12"
43504350

4351-
forwarded-parse@^2.1.2:
4352-
version "2.1.2"
4353-
resolved "https://registry.yarnpkg.com/forwarded-parse/-/forwarded-parse-2.1.2.tgz#08511eddaaa2ddfd56ba11138eee7df117a09325"
4354-
integrity sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==
4355-
43564351
fragment-cache@^0.2.1:
43574352
version "0.2.1"
43584353
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"

0 commit comments

Comments
 (0)