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

View File

@ -1,13 +1,26 @@
import { field, logger } from "@coder/logger"
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"
/**
* Static file HTTP provider. Static requests do not require authentication and
* they only allow access to resources within the application.
* Static file HTTP provider. Regular static requests (the path is the request
* 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 {
public async handleRequest(route: Route, request: http.IncomingMessage): Promise<HttpResponse> {
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)
if (!this.isDev) {
response.cache = true
@ -30,4 +43,23 @@ export class StaticHttpProvider extends HttpProvider {
}
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)
}
break
case "/tar":
if (typeof route.query.path === "string") {
return this.getTarredResource(request, route.query.path)
}
break
case "/webview":
if (/^\/vscode-resource/.test(route.requestPath)) {
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 safeCompare from "safe-compare"
import { Readable } from "stream"
import * as tarFs from "tar-fs"
import * as tls from "tls"
import * as url from "url"
import * as zlib from "zlib"
import { HttpCode, HttpError } from "../common/http"
import { normalize, Options, plural, split } from "../common/util"
import { SocketProxyProvider } from "./socket"
@ -233,25 +231,6 @@ export abstract class HttpProvider {
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).
*/