mirror of https://github.com/coder/code-server.git
Combine main and webview servers
This commit is contained in:
parent
fd55139c82
commit
329acbb251
|
@ -57,6 +57,5 @@ VOLUME [ "/home/coder/project" ]
|
||||||
|
|
||||||
COPY --from=0 /src/build/code-server /usr/local/bin/code-server
|
COPY --from=0 /src/build/code-server /usr/local/bin/code-server
|
||||||
EXPOSE 8443
|
EXPOSE 8443
|
||||||
EXPOSE 8444
|
|
||||||
|
|
||||||
ENTRYPOINT ["dumb-init", "code-server", "--host", "0.0.0.0"]
|
ENTRYPOINT ["dumb-init", "code-server", "--host", "0.0.0.0"]
|
||||||
|
|
|
@ -5,7 +5,7 @@ remote server, accessible through the browser.
|
||||||
|
|
||||||
Try it out:
|
Try it out:
|
||||||
```bash
|
```bash
|
||||||
docker run -it -p 127.0.0.1:8443:8443 -p 127.0.0.1:8444:8444 -v "$PWD:/home/coder/project" codercom/code-server
|
docker run -it -p 127.0.0.1:8443:8443 -v "$PWD:/home/coder/project" codercom/code-server
|
||||||
```
|
```
|
||||||
|
|
||||||
- Code on your Chromebook, tablet, and laptop with a consistent dev environment.
|
- Code on your Chromebook, tablet, and laptop with a consistent dev environment.
|
||||||
|
|
|
@ -1247,6 +1247,19 @@ index 4d8a5d6907..b464d5276f 100644
|
||||||
template.decorationIcon.title = resource.decorations.tooltip || '';
|
template.decorationIcon.title = resource.decorations.tooltip || '';
|
||||||
} else {
|
} else {
|
||||||
template.decorationIcon.style.display = 'none';
|
template.decorationIcon.style.display = 'none';
|
||||||
|
diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||||
|
index a6be033e07..a4dcb7357a 100644
|
||||||
|
--- a/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||||
|
+++ b/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||||
|
@@ -355,7 +355,7 @@
|
||||||
|
// seeing the service worker applying properly.
|
||||||
|
// Fake load an empty on the correct origin and then write real html
|
||||||
|
// into it to get around this.
|
||||||
|
- newFrame.src = `/fake.html?id=${ID}`;
|
||||||
|
+ newFrame.src = `fake.html?id=${ID}`;
|
||||||
|
}
|
||||||
|
newFrame.style.cssText = 'display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden';
|
||||||
|
document.body.appendChild(newFrame);
|
||||||
diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts
|
diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts
|
||||||
index 6d4d096a9c..bbb7930e7a 100644
|
index 6d4d096a9c..bbb7930e7a 100644
|
||||||
--- a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts
|
--- a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts
|
||||||
|
|
23
src/cli.ts
23
src/cli.ts
|
@ -7,7 +7,7 @@ import { buildHelpMessage, buildVersionMessage, options } from "vs/platform/envi
|
||||||
import pkg from "vs/platform/product/node/package";
|
import pkg from "vs/platform/product/node/package";
|
||||||
import product from "vs/platform/product/node/product";
|
import product from "vs/platform/product/node/product";
|
||||||
|
|
||||||
import { AuthType, MainServer, WebviewServer } from "vs/server/src/server";
|
import { AuthType, MainServer } from "vs/server/src/server";
|
||||||
import "vs/server/src/tar";
|
import "vs/server/src/tar";
|
||||||
import { buildAllowedMessage, generateCertificate, generatePassword, open, unpackExecutables } from "vs/server/src/util";
|
import { buildAllowedMessage, generateCertificate, generatePassword, open, unpackExecutables } from "vs/server/src/util";
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ interface Args extends ParsedArgs {
|
||||||
open?: string;
|
open?: string;
|
||||||
port?: string;
|
port?: string;
|
||||||
socket?: string;
|
socket?: string;
|
||||||
"webview-port"?: string;
|
|
||||||
"webview-socket"?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The last item is _ which is like -- so our options need to come before it.
|
// The last item is _ which is like -- so our options need to come before it.
|
||||||
|
@ -57,13 +55,11 @@ options.push({ id: "cert", type: "string", cat: "o", description: "Path to certi
|
||||||
options.push({ id: "cert-key", type: "string", cat: "o", description: "Path to the certificate's key if one was provided." });
|
options.push({ id: "cert-key", type: "string", cat: "o", description: "Path to the certificate's key if one was provided." });
|
||||||
options.push({ id: "extra-builtin-extensions-dir", type: "string", cat: "o", description: "Path to an extra builtin extension directory." });
|
options.push({ id: "extra-builtin-extensions-dir", type: "string", cat: "o", description: "Path to an extra builtin extension directory." });
|
||||||
options.push({ id: "extra-extensions-dir", type: "string", cat: "o", description: "Path to an extra user extension directory." });
|
options.push({ id: "extra-extensions-dir", type: "string", cat: "o", description: "Path to an extra user extension directory." });
|
||||||
options.push({ id: "host", type: "string", cat: "o", description: "Host for the main and webview servers." });
|
options.push({ id: "host", type: "string", cat: "o", description: "Host for the server." });
|
||||||
options.push({ id: "auth", type: "string", cat: "o", description: `The type of authentication to use. ${buildAllowedMessage(AuthType)}.` });
|
options.push({ id: "auth", type: "string", cat: "o", description: `The type of authentication to use. ${buildAllowedMessage(AuthType)}.` });
|
||||||
options.push({ id: "open", type: "boolean", cat: "o", description: "Open in the browser on startup." });
|
options.push({ id: "open", type: "boolean", cat: "o", description: "Open in the browser on startup." });
|
||||||
options.push({ id: "port", type: "string", cat: "o", description: "Port for the main server." });
|
options.push({ id: "port", type: "string", cat: "o", description: "Port for the main server." });
|
||||||
options.push({ id: "socket", type: "string", cat: "o", description: "Listen on a socket instead of host:port." });
|
options.push({ id: "socket", type: "string", cat: "o", description: "Listen on a socket instead of host:port." });
|
||||||
options.push({ id: "webview-port", type: "string", cat: "o", description: "Port for the webview server." });
|
|
||||||
options.push({ id: "webview-socket", type: "string", cat: "o", description: "Listen on a socket instead of host:port." });
|
|
||||||
|
|
||||||
options.push(last);
|
options.push(last);
|
||||||
|
|
||||||
|
@ -140,26 +136,17 @@ const main = async (): Promise<void> => {
|
||||||
options.certKey = certKey;
|
options.certKey = certKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
const webviewPort = args["webview-port"];
|
|
||||||
const webviewServer = new WebviewServer({
|
|
||||||
...options,
|
|
||||||
port: typeof webviewPort !== "undefined" && parseInt(webviewPort, 10) || 8444,
|
|
||||||
socket: args["webview-socket"],
|
|
||||||
});
|
|
||||||
|
|
||||||
const server = new MainServer({
|
const server = new MainServer({
|
||||||
...options,
|
...options,
|
||||||
port: typeof args.port !== "undefined" && parseInt(args.port, 10) || 8443,
|
port: typeof args.port !== "undefined" && parseInt(args.port, 10) || 8443,
|
||||||
socket: args.socket,
|
socket: args.socket,
|
||||||
}, webviewServer, args);
|
}, args);
|
||||||
|
|
||||||
const [webviewAddress, serverAddress, /* ignore */] = await Promise.all([
|
const [serverAddress, /* ignore */] = await Promise.all([
|
||||||
webviewServer.listen(),
|
|
||||||
server.listen(),
|
server.listen(),
|
||||||
unpackExecutables(),
|
unpackExecutables(),
|
||||||
]);
|
]);
|
||||||
console.log(`Main server listening on ${serverAddress}`);
|
console.log(`Server listening on ${serverAddress}`);
|
||||||
console.log(`Webview server listening on ${webviewAddress}`);
|
|
||||||
|
|
||||||
if (options.auth && !process.env.PASSWORD) {
|
if (options.auth && !process.env.PASSWORD) {
|
||||||
console.log(" - Password is", options.password);
|
console.log(" - Password is", options.password);
|
||||||
|
|
|
@ -121,8 +121,8 @@ export abstract class Server {
|
||||||
public constructor(options: ServerOptions) {
|
public constructor(options: ServerOptions) {
|
||||||
this.options = {
|
this.options = {
|
||||||
host: options.auth && options.cert ? "0.0.0.0" : "localhost",
|
host: options.auth && options.cert ? "0.0.0.0" : "localhost",
|
||||||
basePath: options.basePath ? options.basePath.replace(/\/+$/, "") : "",
|
|
||||||
...options,
|
...options,
|
||||||
|
basePath: options.basePath ? options.basePath.replace(/\/+$/, "") : "",
|
||||||
};
|
};
|
||||||
this.protocol = this.options.cert ? "https" : "http";
|
this.protocol = this.options.cert ? "https" : "http";
|
||||||
if (this.protocol === "https") {
|
if (this.protocol === "https") {
|
||||||
|
@ -154,7 +154,7 @@ export abstract class Server {
|
||||||
/**
|
/**
|
||||||
* The local address of the server. If you pass in a request, it will use the
|
* The local address of the server. If you pass in a request, it will use the
|
||||||
* request's host if listening on a port (rather than a socket). This enables
|
* request's host if listening on a port (rather than a socket). This enables
|
||||||
* accessing the webview server from the same host as the main server.
|
* setting the webview endpoint to the same host the browser is using.
|
||||||
*/
|
*/
|
||||||
public address(request?: http.IncomingMessage): string {
|
public address(request?: http.IncomingMessage): string {
|
||||||
const address = this.server.address();
|
const address = this.server.address();
|
||||||
|
@ -357,11 +357,7 @@ export class MainServer extends Server {
|
||||||
private readonly services = new ServiceCollection();
|
private readonly services = new ServiceCollection();
|
||||||
private readonly servicesPromise: Promise<void>;
|
private readonly servicesPromise: Promise<void>;
|
||||||
|
|
||||||
public constructor(
|
public constructor(options: ServerOptions, args: ParsedArgs) {
|
||||||
options: ServerOptions,
|
|
||||||
private readonly webviewServer: WebviewServer,
|
|
||||||
args: ParsedArgs,
|
|
||||||
) {
|
|
||||||
super(options);
|
super(options);
|
||||||
this.server.on("upgrade", async (request, socket) => {
|
this.server.on("upgrade", async (request, socket) => {
|
||||||
const protocol = this.createProtocol(request, socket);
|
const protocol = this.createProtocol(request, socket);
|
||||||
|
@ -398,6 +394,9 @@ export class MainServer extends Server {
|
||||||
case "/out":
|
case "/out":
|
||||||
return this.getResource(path.join(this.rootPath, base, requestPath));
|
return this.getResource(path.join(this.rootPath, base, requestPath));
|
||||||
case "/resources": return this.getResource(requestPath);
|
case "/resources": return this.getResource(requestPath);
|
||||||
|
case "/webview":
|
||||||
|
const webviewPath = path.join(this.rootPath, "out/vs/workbench/contrib/webview/browser/pre");
|
||||||
|
return this.getResource(path.join(webviewPath, requestPath || "/index.html"));
|
||||||
default: throw new HttpError("Not found", HttpCode.NotFound);
|
default: throw new HttpError("Not found", HttpCode.NotFound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,11 +405,10 @@ export class MainServer extends Server {
|
||||||
const filePath = path.join(this.rootPath, "out/vs/code/browser/workbench/workbench.html");
|
const filePath = path.join(this.rootPath, "out/vs/code/browser/workbench/workbench.html");
|
||||||
let [content] = await Promise.all([
|
let [content] = await Promise.all([
|
||||||
util.promisify(fs.readFile)(filePath, "utf8"),
|
util.promisify(fs.readFile)(filePath, "utf8"),
|
||||||
this.webviewServer.listen(),
|
|
||||||
this.servicesPromise,
|
this.servicesPromise,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const webviewEndpoint = this.webviewServer.address(request);
|
const webviewEndpoint = this.address(request) + "/webview/";
|
||||||
const cwd = process.env.VSCODE_CWD || process.cwd();
|
const cwd = process.env.VSCODE_CWD || process.cwd();
|
||||||
const workspacePath = parsedUrl.query.workspace as string | undefined;
|
const workspacePath = parsedUrl.query.workspace as string | undefined;
|
||||||
const folderPath = !workspacePath ? parsedUrl.query.folder as string | undefined || this.options.folderUri || cwd: undefined;
|
const folderPath = !workspacePath ? parsedUrl.query.folder as string | undefined || this.options.folderUri || cwd: undefined;
|
||||||
|
@ -567,13 +565,3 @@ export class MainServer extends Server {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebviewServer extends Server {
|
|
||||||
protected async handleRequest(
|
|
||||||
base: string,
|
|
||||||
requestPath: string,
|
|
||||||
): Promise<Response> {
|
|
||||||
const webviewPath = path.join(this.rootPath, "out/vs/workbench/contrib/webview/browser/pre");
|
|
||||||
return this.getResource(path.join(webviewPath, base, requestPath || "/index.html"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue