Skip to content

Commit d574012

Browse files
committed
Fix duplicate files opening with folder parameter
When using a query parameter without a scheme, the scheme defaults to `file`. This results in the files in the explorer being technically different from the file picker files because they are file:// instead of vscode-remote://, causing the same file to open twice and causing numerous issues. Normally the file explorer wouldn't even load at all in this case but we provide a file service for file:// URLs as a failsafe for certain files that wouldn't load correctly in the past. These files load fine now using the vscode-remote scheme, so I'm also removing that service. Related: #1351. Fixes #1294.
1 parent 250a542 commit d574012

File tree

2 files changed

+59
-20
lines changed

2 files changed

+59
-20
lines changed

scripts/vscode.patch

+41-9
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,46 @@ index 2c64061da7..c0ef8faedd 100644
7676
} catch (err) {
7777
// Do nothing. If we can't read the file we have no
7878
// language pack config.
79+
diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts
80+
index a599f5a7eb..ec7ccd43f8 100644
81+
--- a/src/vs/code/browser/workbench/workbench.ts
82+
+++ b/src/vs/code/browser/workbench/workbench.ts
83+
@@ -298,35 +298,6 @@ class WorkspaceProvider implements IWorkspaceProvider {
84+
let workspace: IWorkspace;
85+
let payload = Object.create(null);
86+
87+
- const query = new URL(document.location.href).searchParams;
88+
- query.forEach((value, key) => {
89+
- switch (key) {
90+
-
91+
- // Folder
92+
- case WorkspaceProvider.QUERY_PARAM_FOLDER:
93+
- workspace = { folderUri: URI.parse(value) };
94+
- foundWorkspace = true;
95+
- break;
96+
-
97+
- // Workspace
98+
- case WorkspaceProvider.QUERY_PARAM_WORKSPACE:
99+
- workspace = { workspaceUri: URI.parse(value) };
100+
- foundWorkspace = true;
101+
- break;
102+
-
103+
- // Empty
104+
- case WorkspaceProvider.QUERY_PARAM_EMPTY_WINDOW:
105+
- workspace = undefined;
106+
- foundWorkspace = true;
107+
- break;
108+
-
109+
- // Payload
110+
- case WorkspaceProvider.QUERY_PARAM_PAYLOAD:
111+
- payload = JSON.parse(value);
112+
- break;
113+
- }
114+
- });
115+
-
116+
// If no workspace is provided through the URL, check for config attribute from server
117+
if (!foundWorkspace) {
118+
if (config.folderUri) {
79119
diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts
80120
index abd1e33b18..bf75952ce1 100644
81121
--- a/src/vs/platform/environment/common/environment.ts
@@ -680,7 +720,7 @@ index 4781f22676..25143a97c0 100644
680720
throw new Error(`Cannot load module '${request}'`);
681721
}
682722
diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts
683-
index 94e7052574..4219adda2c 100644
723+
index 94e7052574..7e5563b417 100644
684724
--- a/src/vs/workbench/browser/web.main.ts
685725
+++ b/src/vs/workbench/browser/web.main.ts
686726
@@ -49,6 +49,7 @@ import { IndexedDBLogProvider } from 'vs/workbench/services/log/browser/indexedD
@@ -699,14 +739,6 @@ index 94e7052574..4219adda2c 100644
699739
}
700740

701741
private registerListeners(workbench: Workbench, storageService: BrowserStorageService): void {
702-
@@ -245,6 +247,7 @@ class BrowserMain extends Disposable {
703-
// Remote file system
704-
const remoteFileSystemProvider = this._register(new RemoteFileSystemProvider(remoteAgentService));
705-
fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider);
706-
+ fileService.registerProvider(Schemas.file, remoteFileSystemProvider);
707-
708-
if (!this.configuration.userDataProvider) {
709-
const remoteUserDataUri = this.getRemoteUserDataUri();
710742
diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts
711743
index c509716fc4..e416413084 100644
712744
--- a/src/vs/workbench/common/resources.ts

src/node/server.ts

+18-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import * as tls from "tls";
1010
import * as url from "url";
1111
import * as util from "util";
1212
import { Emitter } from "vs/base/common/event";
13-
import { sanitizeFilePath } from "vs/base/common/extpath";
1413
import { Schemas } from "vs/base/common/network";
1514
import { URI, UriComponents } from "vs/base/common/uri";
1615
import { generateUuid } from "vs/base/common/uuid";
@@ -574,6 +573,7 @@ export class MainServer extends Server {
574573
}
575574

576575
private async getRoot(request: http.IncomingMessage, parsedUrl: url.UrlWithParsedQuery): Promise<Response> {
576+
const remoteAuthority = request.headers.host as string;
577577
const filePath = path.join(this.serverRoot, "browser/workbench.html");
578578
let [content, startPath] = await Promise.all([
579579
util.promisify(fs.readFile)(filePath, "utf8"),
@@ -582,14 +582,14 @@ export class MainServer extends Server {
582582
{ path: parsedUrl.query.folder, workspace: false },
583583
(await this.readSettings()).lastVisited,
584584
{ path: this.options.openUri }
585-
]),
585+
], remoteAuthority),
586586
this.servicesPromise,
587587
]);
588588

589589
if (startPath) {
590590
this.writeSettings({
591591
lastVisited: {
592-
path: startPath.uri.fsPath,
592+
path: startPath.uri,
593593
workspace: startPath.workspace
594594
},
595595
});
@@ -598,14 +598,13 @@ export class MainServer extends Server {
598598
const logger = this.services.get(ILogService) as ILogService;
599599
logger.info("request.url", `"${request.url}"`);
600600

601-
const remoteAuthority = request.headers.host as string;
602601
const transformer = getUriTransformer(remoteAuthority);
603602

604603
const environment = this.services.get(IEnvironmentService) as IEnvironmentService;
605604
const options: Options = {
606605
WORKBENCH_WEB_CONFIGURATION: {
607-
workspaceUri: startPath && startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined,
608-
folderUri: startPath && !startPath.workspace ? transformer.transformOutgoing(startPath.uri) : undefined,
606+
workspaceUri: startPath && startPath.workspace ? URI.parse(startPath.uri) : undefined,
607+
folderUri: startPath && !startPath.workspace ? URI.parse(startPath.uri) : undefined,
609608
remoteAuthority,
610609
logLevel: getLogLevel(environment),
611610
},
@@ -631,21 +630,29 @@ export class MainServer extends Server {
631630
* workspace or a directory are acceptable. Otherwise it must be a file if a
632631
* workspace or a directory otherwise.
633632
*/
634-
private async getFirstValidPath(startPaths: Array<StartPath | undefined>): Promise<{ uri: URI, workspace?: boolean} | undefined> {
633+
private async getFirstValidPath(startPaths: Array<StartPath | undefined>, remoteAuthority: string): Promise<{ uri: string, workspace?: boolean} | undefined> {
635634
const logger = this.services.get(ILogService) as ILogService;
636-
const cwd = process.env.VSCODE_CWD || process.cwd();
637635
for (let i = 0; i < startPaths.length; ++i) {
638636
const startPath = startPaths[i];
639637
if (!startPath) {
640638
continue;
641639
}
642640
const paths = typeof startPath.path === "string" ? [startPath.path] : (startPath.path || []);
643641
for (let j = 0; j < paths.length; ++j) {
644-
const uri = URI.file(sanitizeFilePath(paths[j], cwd));
642+
const uri = url.parse(paths[j]);
645643
try {
646-
const stat = await util.promisify(fs.stat)(uri.fsPath);
644+
if (!uri.pathname) {
645+
throw new Error(`${paths[j]} is not valid`);
646+
}
647+
const stat = await util.promisify(fs.stat)(uri.pathname);
647648
if (typeof startPath.workspace === "undefined" || startPath.workspace !== stat.isDirectory()) {
648-
return { uri, workspace: !stat.isDirectory() };
649+
return { uri: url.format({
650+
protocol: uri.protocol || "vscode-remote",
651+
hostname: remoteAuthority.split(":")[0],
652+
port: remoteAuthority.split(":")[1],
653+
pathname: uri.pathname,
654+
slashes: true,
655+
}), workspace: !stat.isDirectory() };
649656
}
650657
} catch (error) {
651658
logger.warn(error.message);

0 commit comments

Comments
 (0)