Skip to content

Commit 448ada0

Browse files
committed
Fixes microsoft#144513: Allow cross origin requests for vscode resources from the web worker extension host origin
1 parent 177fb07 commit 448ada0

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

src/vs/server/node/remoteExtensionHostAgentServer.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { connectionTokenQueryName, FileAccess, Schemas } from 'vs/base/common/ne
1818
import { dirname, join } from 'vs/base/common/path';
1919
import * as perf from 'vs/base/common/performance';
2020
import * as platform from 'vs/base/common/platform';
21+
import { createRegExp, escapeRegExpCharacters } from 'vs/base/common/strings';
2122
import { URI } from 'vs/base/common/uri';
2223
import { generateUuid } from 'vs/base/common/uuid';
2324
import { findFreePort } from 'vs/base/node/ports';
@@ -58,6 +59,7 @@ export class RemoteExtensionHostAgentServer extends Disposable implements IServe
5859
private readonly _managementConnections: { [reconnectionToken: string]: ManagementConnection };
5960
private readonly _allReconnectionTokens: Set<string>;
6061
private readonly _webClientServer: WebClientServer | null;
62+
private readonly _webEndpointOriginChecker = WebEndpointOriginChecker.create(this._productService);
6163

6264
private shutdownTimer: NodeJS.Timer | undefined;
6365

@@ -142,6 +144,14 @@ export class RemoteExtensionHostAgentServer extends Disposable implements IServe
142144
responseHeaders['Cache-Control'] = 'public, max-age=31536000';
143145
}
144146
}
147+
148+
// Allow cross origin requests from the web worker extension host
149+
responseHeaders['Vary'] = 'Origin';
150+
const requestOrigin = req.headers['origin'];
151+
if (requestOrigin && this._webEndpointOriginChecker.matches(requestOrigin)) {
152+
responseHeaders['Access-Control-Allow-Origin'] = requestOrigin;
153+
}
154+
145155
return serveFile(this._logService, req, res, filePath, responseHeaders);
146156
}
147157

@@ -767,3 +777,45 @@ export async function createServer(address: string | net.AddressInfo | null, arg
767777
}
768778
return remoteExtensionHostAgentServer;
769779
}
780+
781+
class WebEndpointOriginChecker {
782+
783+
public static create(productService: IProductService): WebEndpointOriginChecker {
784+
const webEndpointUrlTemplate = productService.webEndpointUrlTemplate;
785+
const commit = productService.commit;
786+
const quality = productService.quality;
787+
if (!webEndpointUrlTemplate || !commit || !quality) {
788+
return new WebEndpointOriginChecker(null);
789+
}
790+
791+
const uuid = generateUuid();
792+
const exampleUrl = new URL(
793+
webEndpointUrlTemplate
794+
.replace('{{uuid}}', uuid)
795+
.replace('{{commit}}', commit)
796+
.replace('{{quality}}', quality)
797+
);
798+
const exampleOrigin = exampleUrl.origin;
799+
const originRegExpSource = (
800+
escapeRegExpCharacters(exampleOrigin)
801+
.replace(uuid, '[a-zA-Z0-9\-]+')
802+
);
803+
try {
804+
const originRegExp = createRegExp(`^${originRegExpSource}$`, true, { matchCase: false });
805+
return new WebEndpointOriginChecker(originRegExp);
806+
} catch (err) {
807+
return new WebEndpointOriginChecker(null);
808+
}
809+
}
810+
811+
constructor(
812+
private readonly _originRegExp: RegExp | null
813+
) { }
814+
815+
public matches(origin: string): boolean {
816+
if (!this._originRegExp) {
817+
return false;
818+
}
819+
return this._originRegExp.test(origin);
820+
}
821+
}

0 commit comments

Comments
 (0)