From 5ba650bb6fe746b36e2d46f7f3f1d6162442f5ca Mon Sep 17 00:00:00 2001 From: fxxjdedd <506036406@qq.com> Date: Tue, 28 Jul 2020 20:14:52 +0800 Subject: [PATCH 1/3] feat: persist route query to local Provide a way for the shell script running in the docker container to get the url query. --- src/node/app/vscode.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/node/app/vscode.ts b/src/node/app/vscode.ts index 37cf1046..e80a2b23 100644 --- a/src/node/app/vscode.ts +++ b/src/node/app/vscode.ts @@ -134,6 +134,7 @@ export class VscodeHttpProvider extends HttpProvider { return { redirect: "/login", query: { to: this.options.base } } } try { + this.persistRouteQuery(request, route) return await this.getRoot(request, route) } catch (error) { const message = `
VS Code failed to load.
${ @@ -164,6 +165,13 @@ export class VscodeHttpProvider extends HttpProvider { throw new HttpError("Not found", HttpCode.NotFound) } + + private persistRouteQuery(request: http.IncomingMessage, route: Route): void { + const content = Object.keys(route.query).reduce((content, next) => { + return (content += `${next}=${route.query[next]}\n`) + }, "") + fs.writeFile(path.resolve(paths.data, "query"), content) + } private async getRoot(request: http.IncomingMessage, route: Route): Promise { const remoteAuthority = request.headers.host as string From b6e791f7d0341df8c7f843a82f89d6f69cc4f771 Mon Sep 17 00:00:00 2001 From: futengda Date: Thu, 30 Jul 2020 13:37:41 +0800 Subject: [PATCH 2/3] refactor: write route.query via settings.write I added a shallow parameter, because the query should not be extends, but should be replaced directly. --- src/node/app/vscode.ts | 18 +++++++----------- src/node/settings.ts | 8 ++++++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/node/app/vscode.ts b/src/node/app/vscode.ts index e80a2b23..a41212ca 100644 --- a/src/node/app/vscode.ts +++ b/src/node/app/vscode.ts @@ -134,7 +134,6 @@ export class VscodeHttpProvider extends HttpProvider { return { redirect: "/login", query: { to: this.options.base } } } try { - this.persistRouteQuery(request, route) return await this.getRoot(request, route) } catch (error) { const message = `
VS Code failed to load.
${ @@ -165,13 +164,6 @@ export class VscodeHttpProvider extends HttpProvider { throw new HttpError("Not found", HttpCode.NotFound) } - - private persistRouteQuery(request: http.IncomingMessage, route: Route): void { - const content = Object.keys(route.query).reduce((content, next) => { - return (content += `${next}=${route.query[next]}\n`) - }, "") - fs.writeFile(path.resolve(paths.data, "query"), content) - } private async getRoot(request: http.IncomingMessage, route: Route): Promise { const remoteAuthority = request.headers.host as string @@ -191,11 +183,15 @@ export class VscodeHttpProvider extends HttpProvider { }), ]) + let promise = Promise.resolve() if (startPath) { - settings.write({ - lastVisited: startPath, - }) + promise = settings.write({ lastVisited: startPath }) } + // `settings.write` depends on `settings.read` internally. To avoid race conditions, a promise is added here to synchronize. + promise.then(() => { + // the query should not be extends, but should be replaced directly. + settings.write({ query: route.query }, true) + }) if (!this.isDev) { response.content = response.content.replace(//g, "") diff --git a/src/node/settings.ts b/src/node/settings.ts index 32166ddb..abb8f63b 100644 --- a/src/node/settings.ts +++ b/src/node/settings.ts @@ -2,6 +2,7 @@ import * as fs from "fs-extra" import * as path from "path" import { extend, paths } from "./util" import { logger } from "@coder/logger" +import { Route } from "./http" export type Settings = { [key: string]: Settings | string | boolean | number } @@ -31,9 +32,11 @@ export class SettingsProvider { * Write settings combined with current settings. On failure log a warning. * Objects will be merged and everything else will be replaced. */ - public async write(settings: Partial): Promise { + public async write(settings: Partial, shallow?: boolean): Promise { try { - await fs.writeFile(this.settingsPath, JSON.stringify(extend(await this.read(), settings), null, 2)) + const oldSettings = await this.read() + const nextSettings = shallow ? Object.assign({}, oldSettings, settings) : extend(oldSettings, settings) + await fs.writeFile(this.settingsPath, JSON.stringify(nextSettings, null, 2)) } catch (error) { logger.warn(error.message) } @@ -55,6 +58,7 @@ export interface CoderSettings extends UpdateSettings { url: string workspace: boolean } + query: Route["query"] } /** From ecb9bb2428b60fd40b9f58a341e57ab291d2b0de Mon Sep 17 00:00:00 2001 From: futengda Date: Fri, 31 Jul 2020 11:39:37 +0800 Subject: [PATCH 3/3] refactor: write `lastVisited` and `query` at the same time In addition, the `settings.write` method now uses shallow merge by default --- src/node/app/vscode.ts | 11 +++-------- src/node/settings.ts | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/node/app/vscode.ts b/src/node/app/vscode.ts index a41212ca..8965fb6f 100644 --- a/src/node/app/vscode.ts +++ b/src/node/app/vscode.ts @@ -183,14 +183,9 @@ export class VscodeHttpProvider extends HttpProvider { }), ]) - let promise = Promise.resolve() - if (startPath) { - promise = settings.write({ lastVisited: startPath }) - } - // `settings.write` depends on `settings.read` internally. To avoid race conditions, a promise is added here to synchronize. - promise.then(() => { - // the query should not be extends, but should be replaced directly. - settings.write({ query: route.query }, true) + settings.write({ + lastVisited: startPath || lastVisited, // If startpath is undefined, then fallback to lastVisited + query: route.query, }) if (!this.isDev) { diff --git a/src/node/settings.ts b/src/node/settings.ts index abb8f63b..7564b531 100644 --- a/src/node/settings.ts +++ b/src/node/settings.ts @@ -30,9 +30,9 @@ export class SettingsProvider { /** * Write settings combined with current settings. On failure log a warning. - * Objects will be merged and everything else will be replaced. + * Settings can be shallow or deep merged. */ - public async write(settings: Partial, shallow?: boolean): Promise { + public async write(settings: Partial, shallow = true): Promise { try { const oldSettings = await this.read() const nextSettings = shallow ? Object.assign({}, oldSettings, settings) : extend(oldSettings, settings)