mirror of
https://github.com/coder/code-server.git
synced 2026-09-09 19:30:33 +02:00
Default the session socket to a named pipe on windows (#7985)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { field, Level, logger } from "@coder/logger"
|
import { field, Level, logger } from "@coder/logger"
|
||||||
|
import * as crypto from "crypto"
|
||||||
import { promises as fs } from "fs"
|
import { promises as fs } from "fs"
|
||||||
import { load } from "js-yaml"
|
import { load } from "js-yaml"
|
||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
@@ -561,7 +562,7 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!args["session-socket"]) {
|
if (!args["session-socket"]) {
|
||||||
args["session-socket"] = path.join(args["user-data-dir"], "code-server-ipc.sock")
|
args["session-socket"] = defaultSessionSocket(args["user-data-dir"])
|
||||||
}
|
}
|
||||||
process.env.CODE_SERVER_SESSION_SOCKET = args["session-socket"]
|
process.env.CODE_SERVER_SESSION_SOCKET = args["session-socket"]
|
||||||
|
|
||||||
@@ -710,6 +711,25 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
|
|||||||
} as DefaultedArgs // TODO: Technically no guarantee this is fulfilled.
|
} as DefaultedArgs // TODO: Technically no guarantee this is fulfilled.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The session socket to use when one was not given.
|
||||||
|
*
|
||||||
|
* Windows has no Unix sockets, so there it is a named pipe, which lives in its
|
||||||
|
* own namespace rather than on disk and so cannot be placed inside the user
|
||||||
|
* data directory. The name is derived from that directory anyway, so that two
|
||||||
|
* instances with separate data directories do not collide and a later
|
||||||
|
* invocation with the same one finds the first. Windows paths are compared
|
||||||
|
* without regard to case, so the name is folded before it is hashed; otherwise
|
||||||
|
* the same directory typed two ways would produce two pipes.
|
||||||
|
*/
|
||||||
|
export function defaultSessionSocket(userDataDir: string, platform: NodeJS.Platform = process.platform): string {
|
||||||
|
if (platform !== "win32") {
|
||||||
|
return path.join(userDataDir, "code-server-ipc.sock")
|
||||||
|
}
|
||||||
|
const name = crypto.createHash("sha256").update(path.resolve(userDataDir).toLowerCase()).digest("hex").slice(0, 16)
|
||||||
|
return String.raw`\\.\pipe\code-server-ipc-${name}`
|
||||||
|
}
|
||||||
|
|
||||||
export function getResolvedPathsFromArgs(args: UserProvidedArgs): string[] {
|
export function getResolvedPathsFromArgs(args: UserProvidedArgs): string[] {
|
||||||
return (args._ ?? []).map((p) => path.resolve(p))
|
return (args._ ?? []).map((p) => path.resolve(p))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
UserProvidedArgs,
|
UserProvidedArgs,
|
||||||
bindAddrFromArgs,
|
bindAddrFromArgs,
|
||||||
defaultConfigFile,
|
defaultConfigFile,
|
||||||
|
defaultSessionSocket,
|
||||||
parse,
|
parse,
|
||||||
parseConfigFile,
|
parseConfigFile,
|
||||||
setDefaults,
|
setDefaults,
|
||||||
@@ -37,7 +38,7 @@ const defaults = {
|
|||||||
usingEnvHashedPassword: false,
|
usingEnvHashedPassword: false,
|
||||||
"extensions-dir": path.join(paths.data, "extensions"),
|
"extensions-dir": path.join(paths.data, "extensions"),
|
||||||
"user-data-dir": paths.data,
|
"user-data-dir": paths.data,
|
||||||
"session-socket": path.join(paths.data, "code-server-ipc.sock"),
|
"session-socket": defaultSessionSocket(paths.data),
|
||||||
"app-name": "code-server",
|
"app-name": "code-server",
|
||||||
_: [],
|
_: [],
|
||||||
}
|
}
|
||||||
@@ -977,6 +978,26 @@ describe("bindAddrFromArgs", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("defaultSessionSocket", () => {
|
||||||
|
const dataDir = path.join("/home/coder/.local/share", "code-server")
|
||||||
|
|
||||||
|
it("should put the socket in the user data directory", () => {
|
||||||
|
expect(defaultSessionSocket(dataDir, "linux")).toBe(path.join(dataDir, "code-server-ipc.sock"))
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should use a named pipe on windows", () => {
|
||||||
|
expect(defaultSessionSocket(dataDir, "win32")).toMatch(/^\\\\\.\\pipe\\code-server-ipc-[0-9a-f]{16}$/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should give separate data directories separate pipes", () => {
|
||||||
|
expect(defaultSessionSocket(dataDir, "win32")).not.toBe(defaultSessionSocket(dataDir + "-other", "win32"))
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should give one data directory one pipe however it is spelled", () => {
|
||||||
|
expect(defaultSessionSocket(dataDir.toUpperCase(), "win32")).toBe(defaultSessionSocket(dataDir, "win32"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("defaultConfigFile", () => {
|
describe("defaultConfigFile", () => {
|
||||||
it("should return the default config file as a string", async () => {
|
it("should return the default config file as a string", async () => {
|
||||||
const password = await generatePassword()
|
const password = await generatePassword()
|
||||||
|
|||||||
Reference in New Issue
Block a user