Make client-side extensions work at any base

This commit is contained in:
Asher 2020-03-16 12:04:09 -05:00
parent 88f4b986c5
commit d832f61d5b
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
4 changed files with 37 additions and 31 deletions

View File

@ -819,7 +819,7 @@ index 0000000000..0d2e93edae
+} +}
diff --git a/src/vs/server/browser/worker.ts b/src/vs/server/browser/worker.ts diff --git a/src/vs/server/browser/worker.ts b/src/vs/server/browser/worker.ts
new file mode 100644 new file mode 100644
index 0000000000..0ba93cc070 index 0000000000..a93381631a
--- /dev/null --- /dev/null
+++ b/src/vs/server/browser/worker.ts +++ b/src/vs/server/browser/worker.ts
@@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
@ -841,8 +841,8 @@ index 0000000000..0ba93cc070
+ const fetchUri = URI.from({ + const fetchUri = URI.from({
+ scheme: self.location.protocol.replace(':', ''), + scheme: self.location.protocol.replace(':', ''),
+ authority: self.location.host, + authority: self.location.host,
+ path: `${self.location.pathname.replace(/\/static.*\/out\/vs\/workbench\/services\/extensions\/worker\/extensionHostWorkerMain.js$/, '')}/tar`, + path: self.location.pathname.replace(/\/static\/([^\/]+)\/.*$/, '/static/$1\/'),
+ query: `path=${encodeURIComponent(module.extensionLocation.path)}`, + query: `tar=${encodeURIComponent(module.extensionLocation.path)}`,
+ }); + });
+ const response = await fetch(fetchUri.toString(true)); + const response = await fetch(fetchUri.toString(true));
+ if (response.status !== 200) { + if (response.status !== 200) {

View File

@ -1,13 +1,26 @@
import { field, logger } from "@coder/logger"
import * as http from "http" import * as http from "http"
import * as path from "path"
import { Readable } from "stream"
import * as tarFs from "tar-fs"
import * as zlib from "zlib"
import { HttpProvider, HttpResponse, Route } from "../http" import { HttpProvider, HttpResponse, Route } from "../http"
/** /**
* Static file HTTP provider. Static requests do not require authentication and * Static file HTTP provider. Regular static requests (the path is the request
* they only allow access to resources within the application. * itself) do not require authentication and they only allow access to resources
* within the application. Requests for tars (the path is in a query parameter)
* do require permissions and can access any directory.
*/ */
export class StaticHttpProvider extends HttpProvider { export class StaticHttpProvider extends HttpProvider {
public async handleRequest(route: Route, request: http.IncomingMessage): Promise<HttpResponse> { public async handleRequest(route: Route, request: http.IncomingMessage): Promise<HttpResponse> {
this.ensureMethod(request) this.ensureMethod(request)
if (typeof route.query.tar === "string") {
this.ensureAuthenticated(request)
return this.getTarredResource(request, route.query.tar)
}
const response = await this.getReplacedResource(route) const response = await this.getReplacedResource(route)
if (!this.isDev) { if (!this.isDev) {
response.cache = true response.cache = true
@ -30,4 +43,23 @@ export class StaticHttpProvider extends HttpProvider {
} }
return this.getResource(this.rootPath, ...split) return this.getResource(this.rootPath, ...split)
} }
/**
* Tar up and stream a directory.
*/
private async getTarredResource(request: http.IncomingMessage, ...parts: string[]): Promise<HttpResponse> {
const filePath = path.join(...parts)
let stream: Readable = tarFs.pack(filePath)
const headers: http.OutgoingHttpHeaders = {}
if (request.headers["accept-encoding"] && request.headers["accept-encoding"].includes("gzip")) {
logger.debug("gzipping tar", field("filePath", filePath))
const compress = zlib.createGzip()
stream.pipe(compress)
stream.on("error", (error) => compress.destroy(error))
stream.on("close", () => compress.end())
stream = compress
headers["content-encoding"] = "gzip"
}
return { stream, filePath, mime: "application/x-tar", cache: true, headers }
}
} }

View File

@ -155,11 +155,6 @@ export class VscodeHttpProvider extends HttpProvider {
return this.getResource(route.query.path) return this.getResource(route.query.path)
} }
break break
case "/tar":
if (typeof route.query.path === "string") {
return this.getTarredResource(request, route.query.path)
}
break
case "/webview": case "/webview":
if (/^\/vscode-resource/.test(route.requestPath)) { if (/^\/vscode-resource/.test(route.requestPath)) {
return this.getResource(route.requestPath.replace(/^\/vscode-resource(\/file)?/, "")) return this.getResource(route.requestPath.replace(/^\/vscode-resource(\/file)?/, ""))

View File

@ -8,10 +8,8 @@ import * as path from "path"
import * as querystring from "querystring" import * as querystring from "querystring"
import safeCompare from "safe-compare" import safeCompare from "safe-compare"
import { Readable } from "stream" import { Readable } from "stream"
import * as tarFs from "tar-fs"
import * as tls from "tls" import * as tls from "tls"
import * as url from "url" import * as url from "url"
import * as zlib from "zlib"
import { HttpCode, HttpError } from "../common/http" import { HttpCode, HttpError } from "../common/http"
import { normalize, Options, plural, split } from "../common/util" import { normalize, Options, plural, split } from "../common/util"
import { SocketProxyProvider } from "./socket" import { SocketProxyProvider } from "./socket"
@ -233,25 +231,6 @@ export abstract class HttpProvider {
return { content: await fs.readFile(filePath, "utf8"), filePath } return { content: await fs.readFile(filePath, "utf8"), filePath }
} }
/**
* Tar up and stream a directory.
*/
protected async getTarredResource(request: http.IncomingMessage, ...parts: string[]): Promise<HttpResponse> {
const filePath = path.join(...parts)
let stream: Readable = tarFs.pack(filePath)
const headers: http.OutgoingHttpHeaders = {}
if (request.headers["accept-encoding"] && request.headers["accept-encoding"].includes("gzip")) {
logger.debug("gzipping tar", field("filePath", filePath))
const compress = zlib.createGzip()
stream.pipe(compress)
stream.on("error", (error) => compress.destroy(error))
stream.on("close", () => compress.end())
stream = compress
headers["content-encoding"] = "gzip"
}
return { stream, filePath, mime: "application/x-tar", cache: true, headers }
}
/** /**
* Helper to error on invalid methods (default GET). * Helper to error on invalid methods (default GET).
*/ */