From f7f11ad6c275ae2b8287ca68274b2591e069f9ef Mon Sep 17 00:00:00 2001 From: Asher Date: Mon, 18 May 2020 12:57:50 -0500 Subject: [PATCH] Fix paths from Windows client to non-Windows server Fixes #1659 Fixes #1642 --- ci/dev/vscode.patch | 12 +++++------ src/node/app/static.ts | 3 ++- src/node/app/vscode.ts | 3 ++- src/node/util.ts | 48 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/ci/dev/vscode.patch b/ci/dev/vscode.patch index 9aa241fc..b339f852 100644 --- a/ci/dev/vscode.patch +++ b/ci/dev/vscode.patch @@ -248,19 +248,17 @@ index 1e16cde724..0000000000 -target "12.4.0" -runtime "node" diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts -index e4546b2cf6..9df12239fb 100644 +index e4546b2cf6..ad2c544e89 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts -@@ -94,16 +94,18 @@ class RemoteAuthoritiesImpl { +@@ -94,16 +94,17 @@ class RemoteAuthoritiesImpl { if (host && host.indexOf(':') !== -1) { host = `[${host}]`; } - const port = this._ports[authority]; + // const port = this._ports[authority]; const connectionToken = this._connectionTokens[authority]; -- let query = `path=${encodeURIComponent(uri.path)}`; -+ // NOTE@coder: Use fsPath for Windows support. -+ let query = `path=${encodeURIComponent(uri.fsPath)}`; + let query = `path=${encodeURIComponent(uri.path)}`; if (typeof connectionToken === 'string') { query += `&tkn=${encodeURIComponent(connectionToken)}`; } @@ -1067,7 +1065,7 @@ index 0000000000..0d2e93edae +} diff --git a/src/vs/server/browser/worker.ts b/src/vs/server/browser/worker.ts new file mode 100644 -index 0000000000..8db1e17c38 +index 0000000000..a93381631a --- /dev/null +++ b/src/vs/server/browser/worker.ts @@ -0,0 +1,57 @@ @@ -1090,7 +1088,7 @@ index 0000000000..8db1e17c38 + scheme: self.location.protocol.replace(':', ''), + authority: self.location.host, + path: self.location.pathname.replace(/\/static\/([^\/]+)\/.*$/, '/static/$1\/'), -+ query: `tar=${encodeURIComponent(module.extensionLocation.fsPath)}`, ++ query: `tar=${encodeURIComponent(module.extensionLocation.path)}`, + }); + const response = await fetch(fetchUri.toString(true)); + if (response.status !== 200) { diff --git a/src/node/app/static.ts b/src/node/app/static.ts index 676a99a8..f84d2075 100644 --- a/src/node/app/static.ts +++ b/src/node/app/static.ts @@ -5,6 +5,7 @@ import { Readable } from "stream" import * as tarFs from "tar-fs" import * as zlib from "zlib" import { HttpProvider, HttpResponse, Route } from "../http" +import { pathToFsPath } from "../util" /** * Static file HTTP provider. Regular static requests (the path is the request @@ -18,7 +19,7 @@ export class StaticHttpProvider extends HttpProvider { if (typeof route.query.tar === "string") { this.ensureAuthenticated(request) - return this.getTarredResource(request, route.query.tar) + return this.getTarredResource(request, pathToFsPath(route.query.tar)) } const response = await this.getReplacedResource(route) diff --git a/src/node/app/vscode.ts b/src/node/app/vscode.ts index 6dafe6f6..37cf1046 100644 --- a/src/node/app/vscode.ts +++ b/src/node/app/vscode.ts @@ -18,6 +18,7 @@ import { generateUuid } from "../../common/util" import { Args } from "../cli" import { HttpProvider, HttpProviderOptions, HttpResponse, Route } from "../http" import { settings } from "../settings" +import { pathToFsPath } from "../util" export class VscodeHttpProvider extends HttpProvider { private readonly serverRootPath: string @@ -151,7 +152,7 @@ export class VscodeHttpProvider extends HttpProvider { case "/resource": case "/vscode-remote-resource": if (typeof route.query.path === "string") { - return this.getResource(route.query.path) + return this.getResource(pathToFsPath(route.query.path)) } break case "/webview": diff --git a/src/node/util.ts b/src/node/util.ts index ffe9fcac..a6f8f9b5 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -217,3 +217,51 @@ export function extend(...args: any[]): any { } return c } + +/** + * Taken from vs/base/common/charCode.ts. Copied for now instead of importing so + * we don't have to set up a `vs` alias to be able to import with types (since + * the alternative is to directly import from `out`). + */ +const enum CharCode { + Slash = 47, + A = 65, + Z = 90, + a = 97, + z = 122, + Colon = 58, +} + +/** + * Compute `fsPath` for the given uri. + * Taken from vs/base/common/uri.ts. It's not imported to avoid also importing + * everything that file imports. + */ +export function pathToFsPath(path: string, keepDriveLetterCasing = false): string { + const isWindows = process.platform === "win32" + const uri = { authority: undefined, path, scheme: "file" } + let value: string + if (uri.authority && uri.path.length > 1 && uri.scheme === "file") { + // unc path: file://shares/c$/far/boo + value = `//${uri.authority}${uri.path}` + } else if ( + uri.path.charCodeAt(0) === CharCode.Slash && + ((uri.path.charCodeAt(1) >= CharCode.A && uri.path.charCodeAt(1) <= CharCode.Z) || + (uri.path.charCodeAt(1) >= CharCode.a && uri.path.charCodeAt(1) <= CharCode.z)) && + uri.path.charCodeAt(2) === CharCode.Colon + ) { + if (!keepDriveLetterCasing) { + // windows drive letter: file:///c:/far/boo + value = uri.path[1].toLowerCase() + uri.path.substr(2) + } else { + value = uri.path.substr(1) + } + } else { + // other path + value = uri.path + } + if (isWindows) { + value = value.replace(/\//g, "\\") + } + return value +}