mirror of
https://github.com/coder/code-server.git
synced 2026-09-03 00:42:58 +02:00
Compare commits
7 Commits
2d5dbf0b77
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33546a6308 | ||
|
|
2b2f8b3d5c | ||
|
|
de89acbcdc | ||
|
|
e08e907889 | ||
|
|
92f44d9c7b | ||
|
|
88c2b7432e | ||
|
|
4cb856c475 |
@@ -1 +1 @@
|
||||
24.18.0
|
||||
24.18.1
|
||||
|
||||
31
CHANGELOG.md
31
CHANGELOG.md
@@ -22,6 +22,37 @@ Code v99.99.999
|
||||
|
||||
## Unreleased
|
||||
|
||||
## [4.135.0](https://github.com/coder/code-server/releases/tag/v4.135.0) - 2026-08-27
|
||||
|
||||
Code v1.135.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.135.0
|
||||
|
||||
## [4.134.0](https://github.com/coder/code-server/releases/tag/v4.134.0) - 2026-08-24
|
||||
|
||||
Code v1.134.0
|
||||
|
||||
### Added
|
||||
|
||||
- New `--socket-fd` flag that can be used to listen on a file descriptor. In
|
||||
particular, this allows using code-server with systemd's socket activation.
|
||||
- New `--vscode-option` repeatable flag that can be used to pass through options
|
||||
to VS Code. It requires `flag=value` or simply `flag` for booleans. For
|
||||
example: `--vscode-option enable-sandbox --vscode-option agents=true`. The
|
||||
`VSCODE_OPTIONS` environment variable may also be used. For example:
|
||||
`VSCODE_OPTIONS="enable-sandbox agents=true"`. Note that code-server simply
|
||||
splits this variable on spaces and is not aware of quoting.
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.134.0
|
||||
- Remove `--unsafe-perm` from installation scripts. This flag results in an
|
||||
error when used with npm since v12 and has been a no-op since v7. If you are
|
||||
installing with a version of npm older than v7 as root, installation may not
|
||||
work correctly.
|
||||
|
||||
## [4.133.0](https://github.com/coder/code-server/releases/tag/v4.133.0) - 2026-08-17
|
||||
|
||||
Code v1.133.0
|
||||
|
||||
@@ -15,9 +15,9 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 3.48.0
|
||||
version: 3.50.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
appVersion: 4.133.0
|
||||
appVersion: 4.135.0
|
||||
|
||||
@@ -6,7 +6,7 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: codercom/code-server
|
||||
tag: '4.133.0'
|
||||
tag: '4.135.0'
|
||||
pullPolicy: Always
|
||||
|
||||
# Specifies one or more secrets to be used when pulling images from a
|
||||
|
||||
39
docs/FAQ.md
39
docs/FAQ.md
@@ -41,6 +41,7 @@
|
||||
- [How do I disable the proxy?](#how-do-i-disable-the-proxy)
|
||||
- [How do I disable file download?](#how-do-i-disable-file-download)
|
||||
- [Why do web views not work?](#why-do-web-views-not-work)
|
||||
- [Can I run code-server with systemd socket activation?](#can-i-run-code-server-with-systemd-socket-activation)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -560,3 +561,41 @@ To fix this, you must either:
|
||||
create and trust a certificate manually).
|
||||
- Disable security if your browser allows it. For example, in Chromium see
|
||||
`chrome://flags/#unsafely-treat-insecure-origin-as-secure`
|
||||
|
||||
## Can I run code-server with systemd socket activation?
|
||||
|
||||
Yes. Pass the inherited socket to code-server with `--socket-fd`. systemd
|
||||
passes the first listening socket as file descriptor `3`.
|
||||
|
||||
Create a socket unit, `~/.config/systemd/user/code-server.socket`:
|
||||
|
||||
```ini
|
||||
[Socket]
|
||||
ListenStream=8080
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
```
|
||||
|
||||
And a matching service unit, `~/.config/systemd/user/code-server.service`:
|
||||
|
||||
```ini
|
||||
[Service]
|
||||
ExecStart=/usr/bin/code-server --socket-fd 3
|
||||
```
|
||||
|
||||
Then enable and start the socket:
|
||||
|
||||
```bash
|
||||
systemctl --user enable --now code-server.socket
|
||||
```
|
||||
|
||||
code-server will start on the first connection and listen on the socket
|
||||
systemd created. `--socket-fd` takes precedence over `--socket` and
|
||||
`--bind-addr`/`--port`/`--host`, and `--socket-mode` is ignored because
|
||||
systemd owns the socket's permissions.
|
||||
|
||||
Socket activation only changes how code-server binds; your usual
|
||||
authentication still applies (it keeps prompting for the configured password
|
||||
unless you set `--auth none`), so keep authentication enabled when exposing the
|
||||
server.
|
||||
|
||||
Submodule lib/vscode updated: a5b5009513...08d4889f9e
27
package-lock.json
generated
27
package-lock.json
generated
@@ -35,7 +35,7 @@
|
||||
"code-server": "out/node/entry.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.2.0",
|
||||
"@eslint/compat": "^2.1.0",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "^9.12.0",
|
||||
"@types/compression": "^1.7.3",
|
||||
@@ -170,19 +170,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/compat": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.4.1.tgz",
|
||||
"integrity": "sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.0.tgz",
|
||||
"integrity": "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@eslint/core": "^0.17.0"
|
||||
"@eslint/core": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.40 || 9"
|
||||
"eslint": "^8.40 || 9 || 10"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"eslint": {
|
||||
@@ -190,6 +190,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/compat/node_modules/@eslint/core": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz",
|
||||
"integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/config-array": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
},
|
||||
"main": "out/node/entry.js",
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.2.0",
|
||||
"@eslint/compat": "^2.1.0",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "^9.12.0",
|
||||
"@types/compression": "^1.7.3",
|
||||
|
||||
@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -366,8 +366,11 @@ export class WebClientServer {
|
||||
@@ -362,8 +362,11 @@ export class WebClientServer {
|
||||
linkProtectionTrustedDomains.push(...this._productService.linkProtectionTrustedDomains);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/network.ts
|
||||
@@ -245,7 +245,9 @@ class RemoteAuthoritiesImpl {
|
||||
@@ -251,7 +251,9 @@ class RemoteAuthoritiesImpl {
|
||||
return URI.from({
|
||||
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
|
||||
authority: `${host}:${port}`,
|
||||
@@ -111,7 +111,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -265,7 +265,9 @@ export class WebClientServer {
|
||||
@@ -263,7 +263,9 @@ export class WebClientServer {
|
||||
};
|
||||
|
||||
// Prefix routes with basePath for clients
|
||||
@@ -120,9 +120,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+ const vscodeBase = relativePath(getOriginalUrl(req))
|
||||
+ const basePath = vscodeBase || getFirstHeader('x-forwarded-prefix') || this._basePath;
|
||||
|
||||
const queryConnectionToken = parsedUrl.query[connectionTokenQueryName];
|
||||
if (typeof queryConnectionToken === 'string') {
|
||||
@@ -304,10 +306,14 @@ export class WebClientServer {
|
||||
const queryConnectionTokens = parsedUrl.searchParams.getAll(connectionTokenQueryName);
|
||||
if (queryConnectionTokens.length === 1) {
|
||||
@@ -300,10 +302,14 @@ export class WebClientServer {
|
||||
};
|
||||
|
||||
const useTestResolver = (!this._environmentService.isBuilt && this._environmentService.args['use-test-resolver']);
|
||||
@@ -138,7 +138,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
);
|
||||
if (!remoteAuthority) {
|
||||
return serveError(req, res, 400, `Bad request.`);
|
||||
@@ -354,6 +360,7 @@ export class WebClientServer {
|
||||
@@ -350,6 +356,7 @@ export class WebClientServer {
|
||||
|
||||
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
@@ -146,7 +146,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
embedderIdentifier: 'server-distro',
|
||||
voiceWsUrl: this._productService.voiceWsUrl,
|
||||
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? {
|
||||
@@ -403,7 +410,9 @@ export class WebClientServer {
|
||||
@@ -399,7 +406,9 @@ export class WebClientServer {
|
||||
WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '',
|
||||
WORKBENCH_WEB_BASE_URL: staticRoute,
|
||||
WORKBENCH_NLS_URL,
|
||||
@@ -157,7 +157,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
};
|
||||
|
||||
// DEV ---------------------------------------------------------------------------------------
|
||||
@@ -440,7 +449,7 @@ export class WebClientServer {
|
||||
@@ -436,7 +445,7 @@ export class WebClientServer {
|
||||
'default-src \'self\';',
|
||||
'img-src \'self\' https: data: blob:;',
|
||||
'media-src \'self\';',
|
||||
@@ -166,7 +166,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
'child-src \'self\';',
|
||||
`frame-src 'self' https://*.vscode-cdn.net data:;`,
|
||||
'worker-src \'self\' data: blob:;',
|
||||
@@ -513,3 +522,70 @@ export class WebClientServer {
|
||||
@@ -509,3 +518,70 @@ export class WebClientServer {
|
||||
return void res.end(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
@@ -146,6 +146,7 @@ export interface NativeParsedArgs {
|
||||
@@ -147,6 +147,7 @@ export interface NativeParsedArgs {
|
||||
'disable-chromium-sandbox'?: boolean;
|
||||
sandbox?: boolean;
|
||||
'enable-coi'?: boolean;
|
||||
@@ -102,7 +102,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.cli.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/server.cli.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/server.cli.ts
|
||||
@@ -77,6 +77,7 @@ const isSupportedForPipe = (optionId: ke
|
||||
@@ -78,6 +78,7 @@ const isSupportedForPipe = (optionId: ke
|
||||
case 'verbose':
|
||||
case 'remote':
|
||||
case 'locate-shell-integration-path':
|
||||
@@ -110,7 +110,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.cli.ts
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -300,6 +301,22 @@ export async function main(desc: Product
|
||||
@@ -307,6 +308,22 @@ export async function main(desc: Product
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -153,7 +153,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -25,6 +25,7 @@ import { URI } from '../../base/common/u
|
||||
@@ -24,6 +24,7 @@ import { URI } from '../../base/common/u
|
||||
import { streamToBuffer } from '../../base/common/buffer.js';
|
||||
import { IProductConfiguration } from '../../base/common/product.js';
|
||||
import { isString, Mutable } from '../../base/common/types.js';
|
||||
@@ -161,7 +161,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
import { CharCode } from '../../base/common/charCode.js';
|
||||
import { IExtensionManifest } from '../../platform/extensions/common/extensions.js';
|
||||
import { ICSSDevelopmentService } from '../../platform/cssDev/node/cssDevService.js';
|
||||
@@ -401,14 +402,22 @@ export class WebClientServer {
|
||||
@@ -397,14 +398,22 @@ export class WebClientServer {
|
||||
};
|
||||
|
||||
const cookies = cookie.parse(req.headers.cookie || '');
|
||||
|
||||
@@ -112,7 +112,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -384,6 +384,8 @@ export class WebClientServer {
|
||||
@@ -380,6 +380,8 @@ export class WebClientServer {
|
||||
serverBasePath: basePath,
|
||||
webviewEndpoint: staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
|
||||
userDataPath: this._environmentService.userDataPath,
|
||||
@@ -207,7 +207,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
@@ -40,6 +40,9 @@ export const EmbedderIdentifierContext =
|
||||
@@ -42,6 +42,9 @@ export const EmbedderIdentifierContext =
|
||||
|
||||
export const InAutomationContext = new RawContextKey<boolean>('inAutomation', false, localize('inAutomation', "Whether VS Code is running under automation/smoke test"));
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -388,6 +388,7 @@ export class WebClientServer {
|
||||
@@ -384,6 +384,7 @@ export class WebClientServer {
|
||||
userDataPath: this._environmentService.userDataPath,
|
||||
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
|
||||
isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'],
|
||||
@@ -234,7 +234,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
@@ -42,6 +42,7 @@ export const InAutomationContext = new R
|
||||
@@ -44,6 +44,7 @@ export const InAutomationContext = new R
|
||||
|
||||
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
|
||||
export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
|
||||
|
||||
@@ -251,7 +251,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -353,6 +353,7 @@ export class WebClientServer {
|
||||
@@ -349,6 +349,7 @@ export class WebClientServer {
|
||||
} : undefined;
|
||||
|
||||
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
|
||||
@@ -326,7 +326,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts
|
||||
@@ -47,8 +47,11 @@ export function createWorkbenchDialogOpt
|
||||
@@ -54,8 +54,11 @@ export function createWorkbenchDialogOpt
|
||||
|
||||
export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } {
|
||||
const detailString = (useAgo: boolean): string => {
|
||||
|
||||
@@ -18,7 +18,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -379,6 +379,7 @@ export class WebClientServer {
|
||||
@@ -375,6 +375,7 @@ export class WebClientServer {
|
||||
remoteAuthority,
|
||||
serverBasePath: basePath,
|
||||
webviewEndpoint: staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
|
||||
|
||||
@@ -40,7 +40,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -361,6 +361,7 @@ export class WebClientServer {
|
||||
@@ -357,6 +357,7 @@ export class WebClientServer {
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
rootEndpoint: rootBase,
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,
|
||||
|
||||
@@ -41,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -346,7 +346,6 @@ export class WebClientServer {
|
||||
@@ -342,7 +342,6 @@ export class WebClientServer {
|
||||
|
||||
const staticRoute = posix.join(basePath, this._productPath, STATIC_PATH);
|
||||
const callbackRoute = posix.join(basePath, this._productPath, CALLBACK_PATH);
|
||||
@@ -49,7 +49,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
|
||||
const resolveWorkspaceURI = (defaultLocation?: string) => defaultLocation && URI.file(resolve(defaultLocation)).with({ scheme: Schemas.vscodeRemote, authority: remoteAuthority });
|
||||
|
||||
@@ -363,14 +362,7 @@ export class WebClientServer {
|
||||
@@ -359,14 +358,7 @@ export class WebClientServer {
|
||||
rootEndpoint: rootBase,
|
||||
embedderIdentifier: 'server-distro',
|
||||
voiceWsUrl: this._productService.voiceWsUrl,
|
||||
|
||||
@@ -71,7 +71,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -362,6 +362,7 @@ export class WebClientServer {
|
||||
@@ -358,6 +358,7 @@ export class WebClientServer {
|
||||
rootEndpoint: rootBase,
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,
|
||||
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? rootBase + '/logout' : undefined,
|
||||
|
||||
@@ -54,7 +54,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -363,6 +363,10 @@ export class WebClientServer {
|
||||
@@ -359,6 +359,10 @@ export class WebClientServer {
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,
|
||||
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? rootBase + '/logout' : undefined,
|
||||
proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? rootBase + '/proxy/{{port}}/',
|
||||
|
||||
@@ -126,7 +126,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -367,6 +367,8 @@ export class WebClientServer {
|
||||
@@ -363,6 +363,8 @@ export class WebClientServer {
|
||||
scope: vscodeBase + '/',
|
||||
path: rootBase + '/_static/out/browser/serviceWorker.js',
|
||||
},
|
||||
@@ -151,7 +151,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
@@ -113,7 +113,8 @@ else {
|
||||
@@ -74,7 +74,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
|
||||
resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
|
||||
controlUrl: "",
|
||||
recommendationsUrl: "",
|
||||
|
||||
@@ -24,7 +24,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -358,6 +358,14 @@ export class WebClientServer {
|
||||
@@ -354,6 +354,14 @@ export class WebClientServer {
|
||||
scopes: [['user:email'], ['repo']]
|
||||
} : undefined;
|
||||
|
||||
@@ -39,7 +39,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
rootEndpoint: rootBase,
|
||||
@@ -373,6 +381,7 @@ export class WebClientServer {
|
||||
@@ -369,6 +377,7 @@ export class WebClientServer {
|
||||
embedderIdentifier: 'server-distro',
|
||||
voiceWsUrl: this._productService.voiceWsUrl,
|
||||
extensionsGallery: this._productService.extensionsGallery,
|
||||
|
||||
@@ -113,7 +113,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -360,6 +360,7 @@ export class WebClientServer {
|
||||
@@ -356,6 +356,7 @@ export class WebClientServer {
|
||||
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
rootEndpoint: rootBase,
|
||||
|
||||
@@ -41,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@@ -375,6 +375,7 @@ export class WebClientServer {
|
||||
@@ -371,6 +371,7 @@ export class WebClientServer {
|
||||
const workbenchWebConfiguration = {
|
||||
remoteAuthority,
|
||||
serverBasePath: basePath,
|
||||
|
||||
@@ -13,7 +13,8 @@ import { EditorSessionManager, makeEditorSessionManagerServer } from "./vscodeSo
|
||||
import { handleUpgrade } from "./wsRouter"
|
||||
|
||||
type SocketOptions = { socket: string; "socket-mode"?: string }
|
||||
type ListenOptions = DefaultedArgs | SocketOptions
|
||||
type FdOptions = { "socket-fd": number }
|
||||
type ListenOptions = DefaultedArgs | SocketOptions | FdOptions
|
||||
|
||||
export interface App extends Disposable {
|
||||
/** Handles regular HTTP requests. */
|
||||
@@ -30,8 +31,12 @@ const isSocketOpts = (opts: ListenOptions): opts is SocketOptions => {
|
||||
return !!(opts as SocketOptions).socket || !(opts as DefaultedArgs).host
|
||||
}
|
||||
|
||||
export const isFdOpts = (opts: ListenOptions): opts is FdOptions => {
|
||||
return typeof (opts as FdOptions)["socket-fd"] === "number"
|
||||
}
|
||||
|
||||
export const listen = async (server: http.Server, opts: ListenOptions) => {
|
||||
if (isSocketOpts(opts)) {
|
||||
if (!isFdOpts(opts) && isSocketOpts(opts)) {
|
||||
try {
|
||||
await fs.unlink(opts.socket)
|
||||
} catch (error: any) {
|
||||
@@ -46,7 +51,9 @@ export const listen = async (server: http.Server, opts: ListenOptions) => {
|
||||
server.on("error", (err) => util.logError(logger, "http server error", err))
|
||||
resolve()
|
||||
}
|
||||
if (isSocketOpts(opts)) {
|
||||
if (isFdOpts(opts)) {
|
||||
server.listen({ fd: opts["socket-fd"] }, onListen)
|
||||
} else if (isSocketOpts(opts)) {
|
||||
server.listen(opts.socket, onListen)
|
||||
} else {
|
||||
// [] is the correct format when using :: but Node errors with them.
|
||||
@@ -56,7 +63,7 @@ export const listen = async (server: http.Server, opts: ListenOptions) => {
|
||||
|
||||
// NOTE@jsjoeio: we need to chmod after the server is finished
|
||||
// listening. Otherwise, the socket may not have been created yet.
|
||||
if (isSocketOpts(opts)) {
|
||||
if (!isFdOpts(opts) && isSocketOpts(opts)) {
|
||||
if (opts["socket-mode"]) {
|
||||
await fs.chmod(opts.socket, opts["socket-mode"])
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
|
||||
open?: boolean
|
||||
"bind-addr"?: string
|
||||
socket?: string
|
||||
"socket-fd"?: number
|
||||
"socket-mode"?: string
|
||||
"trusted-origins"?: string[]
|
||||
version?: boolean
|
||||
@@ -236,6 +237,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
|
||||
port: { type: "number", description: "" },
|
||||
|
||||
socket: { type: "string", path: true, description: "Path to a socket (bind-addr will be ignored)." },
|
||||
"socket-fd": {
|
||||
type: "number",
|
||||
description: "File descriptor of a pre-bound, listening socket to use (for systemd socket activation).",
|
||||
},
|
||||
"socket-mode": { type: "string", description: "File mode of the socket." },
|
||||
"trusted-origins": {
|
||||
type: "string[]",
|
||||
|
||||
@@ -3,7 +3,7 @@ import { promises } from "fs"
|
||||
import * as http from "http"
|
||||
import * as https from "https"
|
||||
import * as path from "path"
|
||||
import { createApp, ensureAddress, handleArgsSocketCatchError, listen } from "../../../src/node/app"
|
||||
import { createApp, ensureAddress, handleArgsSocketCatchError, isFdOpts, listen } from "../../../src/node/app"
|
||||
import { OptionalString, setDefaults } from "../../../src/node/cli"
|
||||
import { generateCertificate } from "../../../src/node/util"
|
||||
import { clean, mockLogger, getAvailablePort, tmpdir } from "../../utils/helpers"
|
||||
@@ -261,3 +261,47 @@ describe("listen", () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("listen (socket-fd)", () => {
|
||||
// Wrap a bound-but-not-yet-listening TCP socket so we get a real file
|
||||
// descriptor that listen({ fd }) can adopt, mirroring the systemd socket
|
||||
// activation case where the process inherits an fd and calls listen(2) on it.
|
||||
// Using a live net.Server's fd instead fails with EEXIST because the socket
|
||||
// is already listening in-process.
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { TCP, constants: TCPConstants } = (process as any).binding("tcp_wrap")
|
||||
|
||||
let inherited: any
|
||||
let httpServer: http.Server
|
||||
let unlinkSpy: jest.SpyInstance
|
||||
|
||||
beforeEach(async () => {
|
||||
mockLogger()
|
||||
unlinkSpy = jest.spyOn(promises, "unlink")
|
||||
inherited = new TCP(TCPConstants.SERVER)
|
||||
inherited.bind("127.0.0.1", 0)
|
||||
httpServer = http.createServer()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
httpServer.close()
|
||||
try {
|
||||
inherited.close()
|
||||
} catch {
|
||||
// The fd is adopted by httpServer.close() above; ignore double-close.
|
||||
}
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("isFdOpts detects a numeric socket-fd", () => {
|
||||
expect(isFdOpts({ "socket-fd": 3 })).toBe(true)
|
||||
expect(isFdOpts({ socket: "/tmp/x.sock" } as any)).toBe(false)
|
||||
})
|
||||
|
||||
it("listens on an inherited fd without unlinking", async () => {
|
||||
const fd = inherited.fd as number
|
||||
await listen(httpServer, { "socket-fd": fd })
|
||||
expect(httpServer.address()).not.toBeNull()
|
||||
expect(unlinkSpy).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user