Target a recent commit for VS Code
This is so we can try out the web worker extension host.
This commit is contained in:
parent
624a4c08b9
commit
b901043bfc
12 changed files with 443 additions and 580 deletions
|
@ -8,14 +8,14 @@ matrix:
|
|||
- os: linux
|
||||
dist: trusty
|
||||
env:
|
||||
- VSCODE_VERSION="1.37.0" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="linux"
|
||||
- VSCODE_VERSION="20dd80d91a76cbe80fb1d1979c3a9f02d94ba161" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="linux"
|
||||
- os: linux
|
||||
dist: trusty
|
||||
env:
|
||||
- VSCODE_VERSION="1.37.0" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="alpine"
|
||||
- VSCODE_VERSION="20dd80d91a76cbe80fb1d1979c3a9f02d94ba161" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="alpine"
|
||||
- os: osx
|
||||
env:
|
||||
- VSCODE_VERSION="1.37.0" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER"
|
||||
- VSCODE_VERSION="20dd80d91a76cbe80fb1d1979c3a9f02d94ba161" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER"
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_BRANCH" == "master" ]]; then export MINIFY="true"; fi
|
||||
- if [[ "$TRAVIS_BRANCH" == "master" ]]; then export PACKAGE="true"; fi
|
||||
|
|
26
README.md
26
README.md
|
@ -81,7 +81,7 @@ data collected to improve code-server.
|
|||
```shell
|
||||
git clone https://github.com/microsoft/vscode
|
||||
cd vscode
|
||||
git checkout 1.37.0
|
||||
git checkout <see travis.yml for the VS Code version to use here>
|
||||
git clone https://github.com/cdr/code-server src/vs/server
|
||||
cd src/vs/server
|
||||
yarn patch:apply
|
||||
|
@ -98,30 +98,28 @@ If you run into issues about a different version of Node being used, try running
|
|||
`vscode-ripgrep`.
|
||||
|
||||
### Upgrading VS Code
|
||||
We have to patch VS Code to provide and fix some functionality. As the web
|
||||
portion of VS Code matures, we'll be able to shrink and maybe even entirely
|
||||
eliminate our patch. In the meantime, however, upgrading the VS Code version
|
||||
requires ensuring that the patch still applies and has the intended effects.
|
||||
We patch VS Code to provide and fix some functionality. As the web portion of VS
|
||||
Code matures, we'll be able to shrink and maybe even entirely eliminate our
|
||||
patch. In the meantime, however, upgrading the VS Code version requires ensuring
|
||||
that the patch still applies and has the intended effects.
|
||||
|
||||
To generate a new patch, **stage all the changes** you want to be included in
|
||||
the patch in the VS Code source, then run `yarn patch:generate` in this
|
||||
directory.
|
||||
|
||||
Our changes include:
|
||||
- Add a `code-server` schema.
|
||||
- Change the remote schema to `code-server`.
|
||||
- Allow multiple extension directories (both user and built-in).
|
||||
- Modify the loader, websocket, webview, service worker, and asset requests to
|
||||
use the URL of the page as a base (and TLS if necessary for the websocket).
|
||||
- Send client-side telemetry through the server.
|
||||
- Add a file prefix to ignore for temporary files created during upload.
|
||||
- Insert our upload service for use in editor windows and explorer.
|
||||
- Modify the log level to get its initial setting from the server.
|
||||
- Change a regular expression used for mnemonics so it works on Firefox.
|
||||
- Send client-side telemetry through the server and get the initial log level
|
||||
from the server.
|
||||
- Add an upload service for use in editor windows and the explorer along with a
|
||||
file prefix to ignore for temporary files created during upload.
|
||||
- Make changing the display language work.
|
||||
- Make hiding or toggling the menu bar possible.
|
||||
- Make it possible for us to load code on the client.
|
||||
- Modify the build process to include our code.
|
||||
- Fix a CSP issue within webviews.
|
||||
- Fix an issue displaying extension contributions.
|
||||
- Make changing the display language work.
|
||||
|
||||
## License
|
||||
[MIT](LICENSE)
|
||||
|
|
|
@ -133,7 +133,7 @@ function build-task() {
|
|||
mkdir -p "${stagingPath}"
|
||||
if [[ ! -d "${sourcePath}" ]] ; then
|
||||
if ! download-pre-built "vscode-${vscodeVersion}.tar.gz" ; then
|
||||
git clone https://github.com/microsoft/vscode --quiet \
|
||||
git clone https://github.com/microsoft/vscode --quiet \
|
||||
--branch "${vscodeVersion}" --single-branch --depth=1 \
|
||||
"${sourcePath}"
|
||||
fi
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,7 @@ import { OS } from "vs/base/common/platform";
|
|||
import { URI, UriComponents } from "vs/base/common/uri";
|
||||
import { transformOutgoingURIs } from "vs/base/common/uriIpc";
|
||||
import { IServerChannel } from "vs/base/parts/ipc/common/ipc";
|
||||
import { IDiagnosticInfo } from "vs/platform/diagnostics/common/diagnosticsService";
|
||||
import { IDiagnosticInfo } from "vs/platform/diagnostics/common/diagnostics";
|
||||
import { IEnvironmentService } from "vs/platform/environment/common/environment";
|
||||
import { ExtensionIdentifier, IExtensionDescription } from "vs/platform/extensions/common/extensions";
|
||||
import { FileDeleteOptions, FileOpenOptions, FileOverwriteOptions, FileType, IStat, IWatchOptions } from "vs/platform/files/common/files";
|
||||
|
@ -163,11 +163,10 @@ export class FileProviderChannel implements IServerChannel, IDisposable {
|
|||
}
|
||||
|
||||
private transform(resource: UriComponents): URI {
|
||||
// HACK: for now assume /out is relative to the build (used for the
|
||||
// walkthrough content).
|
||||
if (resource.path.indexOf("/out") === 0) {
|
||||
return URI.file(this.environmentService.appRoot + resource.path);
|
||||
// This is used by the webview service worker to load resources.
|
||||
// Used for walkthrough content.
|
||||
if (resource.path.indexOf("/static") === 0) {
|
||||
return URI.file(this.environmentService.appRoot + resource.path.replace(/^\/static/, ""));
|
||||
// Used by the webview service worker to load resources.
|
||||
} else if (resource.path === "/vscode-resource" && resource.query) {
|
||||
try {
|
||||
const query = JSON.parse(resource.query);
|
||||
|
@ -185,6 +184,7 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
|
|||
private readonly environment: IEnvironmentService,
|
||||
private readonly log: ILogService,
|
||||
private readonly telemetry: ITelemetryService,
|
||||
private readonly connectionToken: string,
|
||||
) {}
|
||||
|
||||
public listen(_: unknown, event: string): Event<any> {
|
||||
|
@ -207,6 +207,7 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
|
|||
private async getEnvironmentData(locale: string): Promise<IRemoteAgentEnvironment> {
|
||||
return {
|
||||
pid: process.pid,
|
||||
connectionToken: this.connectionToken,
|
||||
appRoot: URI.file(this.environment.appRoot),
|
||||
appSettingsHome: this.environment.appSettingsHome,
|
||||
settingsPath: this.environment.machineSettingsHome,
|
||||
|
|
|
@ -7,6 +7,7 @@ import { LocalizationsService } from "vs/platform/localizations/electron-browser
|
|||
import { IUpdateService } from "vs/platform/update/common/update";
|
||||
import { UpdateService } from "vs/platform/update/electron-browser/updateService";
|
||||
import { TelemetryChannelClient } from "vs/server/src/telemetry";
|
||||
import { IUploadService, UploadService } from 'vs/server/src/upload';
|
||||
import { IRemoteAgentService } from "vs/workbench/services/remote/common/remoteAgentService";
|
||||
|
||||
class TelemetryService extends TelemetryChannelClient {
|
||||
|
@ -18,12 +19,13 @@ class TelemetryService extends TelemetryChannelClient {
|
|||
}
|
||||
|
||||
registerSingleton(ILocalizationsService, LocalizationsService);
|
||||
registerSingleton(IUpdateService, UpdateService);
|
||||
registerSingleton(ITelemetryService, TelemetryService);
|
||||
registerSingleton(IUpdateService, UpdateService);
|
||||
registerSingleton(IUploadService, UploadService, true);
|
||||
|
||||
import "vs/workbench/contrib/update/electron-browser/update.contribution";
|
||||
import 'vs/workbench/contrib/localizations/browser/localizations.contribution';
|
||||
|
||||
import "vs/css!./media/firefox";
|
||||
import { coderApi, vscodeApi } from "vs/server/src/api";
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,104 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'unsafe-inline'; manifest-src 'self'; img-src 'self';">
|
||||
<title>Authenticate: code-server</title>
|
||||
<style>
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
html, body {
|
||||
background-color: #FFFFFF;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-family: "monospace";
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 18px 80px 10px rgba(69, 65, 78, 0.08);
|
||||
color: #575962;
|
||||
margin-top: -10%;
|
||||
max-width: 328px;
|
||||
padding: 40px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form > .title {
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1.5px;
|
||||
line-height: 15px;
|
||||
margin-bottom: 0px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.login-form > .subtitle {
|
||||
font-size: 19px;
|
||||
font-weight: bold;
|
||||
line-height: 25px;
|
||||
margin-bottom: 45px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-form > .field {
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
color: #797E84;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.login-form > .field > .input {
|
||||
background: none !important;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 2px;
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form > .button {
|
||||
border: none;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 12px 17px 2px rgba(171,173,163,0.14), 0 5px 22px 4px rgba(171,173,163,0.12), 0 7px 8px -4px rgba(171,173,163,0.2);
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: 15px 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form > .button:hover {
|
||||
background-color: rgb(0, 122, 204);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.error-display {
|
||||
box-sizing: border-box;
|
||||
color: #bb2d0f;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 12px;
|
||||
padding: 20px 8px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
|
||||
<link rel="manifest" href="./manifest.json">
|
||||
<link href="./static/out/vs/server/src/media/login.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<form class="login-form" method="post">
|
||||
|
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
|
@ -1,14 +0,0 @@
|
|||
@supports (-moz-appearance:none) {
|
||||
/* Firefox doesn't support -webkit-margin-{before/after} so use margin. */
|
||||
/* These are the collapsible section headings in a sidebar panel. */
|
||||
.monaco-panel-view .panel > .panel-header h3.title {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Firefox doesn't seem to support fit-content. */
|
||||
/* These are the file tabs. */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit {
|
||||
min-width: -moz-fit-content;
|
||||
}
|
||||
}
|
94
src/media/login.css
Normal file
94
src/media/login.css
Normal file
|
@ -0,0 +1,94 @@
|
|||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
html, body {
|
||||
background-color: #FFFFFF;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-family: "monospace";
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 18px 80px 10px rgba(69, 65, 78, 0.08);
|
||||
color: #575962;
|
||||
margin-top: -10%;
|
||||
max-width: 328px;
|
||||
padding: 40px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form > .title {
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1.5px;
|
||||
line-height: 15px;
|
||||
margin-bottom: 0px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.login-form > .subtitle {
|
||||
font-size: 19px;
|
||||
font-weight: bold;
|
||||
line-height: 25px;
|
||||
margin-bottom: 45px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-form > .field {
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
color: #797E84;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.login-form > .field > .input {
|
||||
background: none !important;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 2px;
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form > .button {
|
||||
border: none;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 12px 17px 2px rgba(171,173,163,0.14), 0 5px 22px 4px rgba(171,173,163,0.12), 0 7px 8px -4px rgba(171,173,163,0.2);
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: 15px 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form > .button:hover {
|
||||
background-color: rgb(0, 122, 204);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.error-display {
|
||||
box-sizing: border-box;
|
||||
color: #bb2d0f;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 12px;
|
||||
padding: 20px 8px 0;
|
||||
text-align: center;
|
||||
}
|
13
src/media/manifest.json
Normal file
13
src/media/manifest.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "code-server",
|
||||
"short_name": "code-server",
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"background-color": "#fff",
|
||||
"description": "Run VS Code on a remote server.",
|
||||
"icons": [{
|
||||
"src": "static/code-server.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
}]
|
||||
}
|
104
src/server.ts
104
src/server.ts
|
@ -41,10 +41,9 @@ import { LocalizationsChannel } from "vs/platform/localizations/node/localizatio
|
|||
import { getLogLevel, ILogService } from "vs/platform/log/common/log";
|
||||
import { LogLevelSetterChannel } from "vs/platform/log/common/logIpc";
|
||||
import { SpdLogService } from "vs/platform/log/node/spdlogService";
|
||||
import { IProductConfiguration, IProductService } from "vs/platform/product/common/product";
|
||||
import { IProductService } from "vs/platform/product/common/product";
|
||||
import pkg from "vs/platform/product/node/package";
|
||||
import product from "vs/platform/product/node/product";
|
||||
import { ProductService } from "vs/platform/product/node/productService";
|
||||
import { ConnectionType, ConnectionTypeRequest } from "vs/platform/remote/common/remoteAgentConnection";
|
||||
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from "vs/platform/remote/common/remoteAgentFileSystemChannel";
|
||||
import { IRequestService } from "vs/platform/request/common/request";
|
||||
|
@ -81,8 +80,6 @@ export enum HttpCode {
|
|||
export interface Options {
|
||||
WORKBENCH_WEB_CONGIGURATION: IWorkbenchConstructionOptions;
|
||||
REMOTE_USER_DATA_URI: UriComponents | URI;
|
||||
PRODUCT_CONFIGURATION: IProductConfiguration | null;
|
||||
CONNECTION_AUTH_TOKEN: string;
|
||||
NLS_CONFIGURATION: NLSConfiguration;
|
||||
}
|
||||
|
||||
|
@ -110,6 +107,7 @@ export class HttpError extends Error {
|
|||
export interface ServerOptions {
|
||||
readonly auth?: AuthType;
|
||||
readonly basePath?: string;
|
||||
readonly connectionToken?: string;
|
||||
readonly cert?: string;
|
||||
readonly certKey?: string;
|
||||
readonly folderUri?: string;
|
||||
|
@ -122,6 +120,8 @@ export interface ServerOptions {
|
|||
export abstract class Server {
|
||||
protected readonly server: http.Server | https.Server;
|
||||
protected rootPath = path.resolve(__dirname, "../../../..");
|
||||
protected serverRoot = path.join(this.rootPath, "/out/vs/server/src");
|
||||
protected readonly allowedRequestPaths: string[] = [this.rootPath];
|
||||
private listenPromise: Promise<string> | undefined;
|
||||
public readonly protocol: "http" | "https";
|
||||
public readonly options: ServerOptions;
|
||||
|
@ -185,6 +185,9 @@ export abstract class Server {
|
|||
|
||||
protected async getResource(...parts: string[]): Promise<Response> {
|
||||
const filePath = path.join(...parts);
|
||||
if (!this.isAllowedRequestPath(filePath)) {
|
||||
throw new HttpError("Unauthorized", HttpCode.Unauthorized);
|
||||
}
|
||||
return { content: await util.promisify(fs.readFile)(filePath), filePath };
|
||||
}
|
||||
|
||||
|
@ -193,10 +196,20 @@ export abstract class Server {
|
|||
return `${this.protocol}://${request.headers.host}${this.options.basePath}${path}${split.length === 2 ? `?${split[1]}` : ""}`;
|
||||
}
|
||||
|
||||
private isAllowedRequestPath(path: string): boolean {
|
||||
for (let i = 0; i < this.allowedRequestPaths.length; ++i) {
|
||||
if (path.indexOf(this.allowedRequestPaths[i]) === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private onRequest = async (request: http.IncomingMessage, response: http.ServerResponse): Promise<void> => {
|
||||
try {
|
||||
const payload = await this.preHandleRequest(request);
|
||||
response.writeHead(payload.redirect ? HttpCode.Redirect : payload.code || HttpCode.Ok, {
|
||||
// "Cache-Control": "public, max-age=31536000",
|
||||
"Content-Type": getMediaMime(payload.filePath),
|
||||
...(payload.redirect ? { Location: this.withBase(request, payload.redirect) } : {}),
|
||||
...(request.headers["service-worker"] ? { "Service-Worker-Allowed": this.options.basePath || "/" } : {}),
|
||||
|
@ -233,25 +246,29 @@ export abstract class Server {
|
|||
base = path.normalize(base);
|
||||
requestPath = path.normalize(requestPath || "/index.html");
|
||||
|
||||
if (base !== "/login" || !this.options.auth || requestPath !== "/index.html") {
|
||||
this.ensureGet(request);
|
||||
}
|
||||
|
||||
switch (base) {
|
||||
case "/":
|
||||
this.ensureGet(request);
|
||||
if (requestPath === "/favicon.ico") {
|
||||
return this.getResource(this.rootPath, "/out/vs/server/src/favicon", requestPath);
|
||||
} else if (!this.authenticate(request)) {
|
||||
switch (requestPath) {
|
||||
case "/favicon.ico":
|
||||
case "/manifest.json":
|
||||
return this.getResource(this.serverRoot, "media", requestPath);
|
||||
}
|
||||
if (!this.authenticate(request)) {
|
||||
return { redirect: "/login" };
|
||||
}
|
||||
break;
|
||||
case "/static":
|
||||
return this.getResource(this.rootPath, requestPath);
|
||||
case "/login":
|
||||
if (!this.options.auth) {
|
||||
if (!this.options.auth || requestPath !== "/index.html") {
|
||||
throw new HttpError("Not found", HttpCode.NotFound);
|
||||
} else if (requestPath === "/index.html") {
|
||||
return this.tryLogin(request);
|
||||
}
|
||||
this.ensureGet(request);
|
||||
return this.getResource(this.rootPath, "/out/vs/server/src/login", requestPath);
|
||||
return this.tryLogin(request);
|
||||
default:
|
||||
this.ensureGet(request);
|
||||
if (!this.authenticate(request)) {
|
||||
throw new HttpError("Unauthorized", HttpCode.Unauthorized);
|
||||
}
|
||||
|
@ -274,6 +291,7 @@ export abstract class Server {
|
|||
socket.on("error", () => socket.destroy());
|
||||
socket.on("end", () => socket.destroy());
|
||||
|
||||
this.ensureGet(request);
|
||||
if (!this.authenticate(request)) {
|
||||
throw new HttpError("Unauthorized", HttpCode.Unauthorized);
|
||||
} else if (request.headers.upgrade !== "websocket") {
|
||||
|
@ -297,8 +315,7 @@ export abstract class Server {
|
|||
}
|
||||
|
||||
private async tryLogin(request: http.IncomingMessage): Promise<Response> {
|
||||
if (this.authenticate(request)) {
|
||||
this.ensureGet(request);
|
||||
if (this.authenticate(request) && (request.method === "GET" || request.method === "POST")) {
|
||||
return { redirect: "/" };
|
||||
}
|
||||
if (request.method === "POST") {
|
||||
|
@ -322,7 +339,7 @@ export abstract class Server {
|
|||
}
|
||||
|
||||
private async getLogin(error: string = "", payload?: LoginPayload): Promise<Response> {
|
||||
const filePath = path.join(this.rootPath, "out/vs/server/src/login/index.html");
|
||||
const filePath = path.join(this.serverRoot, "login/index.html");
|
||||
const content = (await util.promisify(fs.readFile)(filePath, "utf8"))
|
||||
.replace("{{ERROR}}", error)
|
||||
.replace("display:none", error ? "display:block" : "display:none")
|
||||
|
@ -446,24 +463,12 @@ export class MainServer extends Server {
|
|||
): Promise<Response> {
|
||||
switch (base) {
|
||||
case "/": return this.getRoot(request, parsedUrl);
|
||||
case "/resources":
|
||||
case "/vscode-resources":
|
||||
if (requestPath === "/fetch") {
|
||||
if (typeof parsedUrl.query.u === "string") {
|
||||
return this.getResource(JSON.parse(parsedUrl.query.u).path);
|
||||
}
|
||||
// For some reason VS Code encodes the = so the query doesn't parse
|
||||
// correctly. We'll look through what's available and try to find it.
|
||||
for (let value in parsedUrl.query) {
|
||||
if (value && typeof value === "string") {
|
||||
const query = querystring.parse(value);
|
||||
if (typeof query.u === "string") {
|
||||
return this.getResource(JSON.parse(query.u).path);
|
||||
}
|
||||
}
|
||||
}
|
||||
case "/resource":
|
||||
case "/vscode-remote-resource":
|
||||
if (typeof parsedUrl.query.path === "string") {
|
||||
return this.getResource(parsedUrl.query.path);
|
||||
}
|
||||
throw new HttpError("Not found", HttpCode.NotFound);
|
||||
break;
|
||||
case "/webview":
|
||||
if (requestPath.indexOf("/vscode-resource") === 0) {
|
||||
return this.getResource(requestPath.replace(/^\/vscode-resource/, ""));
|
||||
|
@ -473,9 +478,8 @@ export class MainServer extends Server {
|
|||
"out/vs/workbench/contrib/webview/browser/pre",
|
||||
requestPath
|
||||
);
|
||||
default:
|
||||
return this.getResource(this.rootPath, base, requestPath);
|
||||
}
|
||||
throw new HttpError("Not found", HttpCode.NotFound);
|
||||
}
|
||||
|
||||
private async getRoot(request: http.IncomingMessage, parsedUrl: url.UrlWithParsedQuery): Promise<Response> {
|
||||
|
@ -502,16 +506,11 @@ export class MainServer extends Server {
|
|||
? transformer.transformOutgoing(URI.file(sanitizeFilePath(folderPath, cwd)))
|
||||
: undefined,
|
||||
remoteAuthority,
|
||||
productConfiguration: product,
|
||||
},
|
||||
REMOTE_USER_DATA_URI: transformer.transformOutgoing(
|
||||
(this.services.get(IEnvironmentService) as EnvironmentService).webUserDataHome,
|
||||
),
|
||||
PRODUCT_CONFIGURATION: {
|
||||
...product,
|
||||
// @ts-ignore workaround for getting the VS Code version to the browser.
|
||||
version: pkg.version,
|
||||
},
|
||||
CONNECTION_AUTH_TOKEN: "",
|
||||
NLS_CONFIGURATION: await getNlsConfiguration(locale, environment.userDataPath),
|
||||
};
|
||||
|
||||
|
@ -586,6 +585,14 @@ export class MainServer extends Server {
|
|||
const fileService = new FileService(logService);
|
||||
fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(logService));
|
||||
|
||||
this.allowedRequestPaths.push(
|
||||
path.join(environmentService.userDataPath, "clp"), // Language packs.
|
||||
environmentService.extensionsPath,
|
||||
environmentService.builtinExtensionsPath,
|
||||
...environmentService.extraExtensionPaths,
|
||||
...environmentService.extraBuiltinExtensionPaths,
|
||||
);
|
||||
|
||||
this.ipc.registerChannel("loglevel", new LogLevelSetterChannel(logService));
|
||||
this.ipc.registerChannel(ExtensionHostDebugBroadcastChannel.ChannelName, new ExtensionHostDebugBroadcastChannel());
|
||||
|
||||
|
@ -595,7 +602,7 @@ export class MainServer extends Server {
|
|||
this.services.set(IConfigurationService, new SyncDescriptor(ConfigurationService, [environmentService.machineSettingsResource]));
|
||||
this.services.set(IRequestService, new SyncDescriptor(RequestService));
|
||||
this.services.set(IFileService, fileService);
|
||||
this.services.set(IProductService, new SyncDescriptor(ProductService));
|
||||
this.services.set(IProductService, { _serviceBrand: undefined, ...product });
|
||||
this.services.set(IDialogService, new DialogChannelClient(this.ipc.getChannel("dialog", router)));
|
||||
this.services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));
|
||||
this.services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
|
||||
|
@ -608,14 +615,9 @@ export class MainServer extends Server {
|
|||
),
|
||||
commonProperties: resolveCommonProperties(
|
||||
product.commit, pkg.codeServerVersion, await getMachineId(),
|
||||
environmentService.installSourcePath, "code-server",
|
||||
[], environmentService.installSourcePath, "code-server",
|
||||
),
|
||||
piiPaths: [
|
||||
environmentService.appRoot,
|
||||
environmentService.extensionsPath,
|
||||
...environmentService.extraExtensionPaths,
|
||||
...environmentService.extraBuiltinExtensionPaths,
|
||||
],
|
||||
piiPaths: this.allowedRequestPaths,
|
||||
} as ITelemetryServiceConfig]));
|
||||
} else {
|
||||
this.services.set(ITelemetryService, NullTelemetryService);
|
||||
|
@ -633,7 +635,7 @@ export class MainServer extends Server {
|
|||
const telemetryService = this.services.get(ITelemetryService) as ITelemetryService;
|
||||
|
||||
const extensionsChannel = new ExtensionManagementChannel(extensionsService, (context) => getUriTransformer(context.remoteAuthority));
|
||||
const extensionsEnvironmentChannel = new ExtensionEnvironmentChannel(environmentService, logService, telemetryService);
|
||||
const extensionsEnvironmentChannel = new ExtensionEnvironmentChannel(environmentService, logService, telemetryService, this.options.connectionToken || "");
|
||||
const fileChannel = new FileProviderChannel(environmentService, logService);
|
||||
const requestChannel = new RequestChannel(this.services.get(IRequestService) as IRequestService);
|
||||
const telemetryChannel = new TelemetryChannel(telemetryService);
|
||||
|
|
Loading…
Reference in a new issue