1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Fully move last of LensProxy to injectables

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-03-21 16:06:40 -04:00
parent 6be63df9e6
commit 455b7ed744
6 changed files with 105 additions and 94 deletions

View File

@ -1,23 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { LensProxy } from "./lens-proxy";
import loggerInjectable from "../../common/logger.injectable";
import lensProxyHttpsServerInjectable from "./https-proxy/server.injectable";
import proxyRetryInjectable from "./proxy/retry.injectable";
import attemptToListenInjectable from "./attempt-to-listen.injectable";
const lensProxyInjectable = getInjectable({
id: "lens-proxy",
instantiate: (di) => new LensProxy({
proxyServer: di.inject(lensProxyHttpsServerInjectable),
logger: di.inject(loggerInjectable),
proxyRetry: di.inject(proxyRetryInjectable),
attemptToListen: di.inject(attemptToListenInjectable),
}),
});
export default lensProxyInjectable;

View File

@ -1,68 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type https from "https";
import type http from "http";
import type { Cluster } from "../../common/cluster/cluster";
import type { ProxyApiRequestArgs } from "./proxy-functions";
import type { SetRequired } from "type-fest";
import type { Logger } from "../../common/logger";
import { disallowedPorts } from "./disallowed-ports";
import type { ProxyRetry } from "./proxy/retry.injectable";
import type { AttemptToListen } from "./attempt-to-listen.injectable";
export type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | undefined;
export type ServerIncomingMessage = SetRequired<http.IncomingMessage, "url" | "method">;
export type LensProxyApiRequest = (args: ProxyApiRequestArgs) => void | Promise<void>;
interface Dependencies {
attemptToListen: AttemptToListen;
readonly logger: Logger;
readonly proxyServer: https.Server;
readonly proxyRetry: ProxyRetry;
}
export class LensProxy {
constructor(private readonly dependencies: Dependencies) {}
/**
* Starts the lens proxy.
* @resolves After the server is listening on a good port
* @rejects if there is an error before that happens
*/
async listen(): Promise<void> {
const seenPorts = new Set<number>();
while(true) {
this.dependencies.proxyServer?.close();
const port = await this.dependencies.attemptToListen();
if (!disallowedPorts.has(port)) {
// We didn't get a port that would result in an ERR_UNSAFE_PORT error, use it
return;
}
this.dependencies.logger.warn(`[LENS-PROXY]: Proxy server has with port known to be considered unsafe to connect to by chrome, restarting...`);
if (seenPorts.has(port)) {
/**
* Assume that if we have seen the port before, then the OS has looped
* through all the ports possible and we will not be able to get a safe
* port.
*/
throw new Error("Failed to start LensProxy due to seeing too many unsafe ports. Please restart Lens.");
} else {
seenPorts.add(port);
}
}
}
close() {
this.dependencies.logger.info("[LENS-PROXY]: Closing server");
this.dependencies.proxyServer.close();
this.dependencies.proxyRetry.close();
}
}

View File

@ -0,0 +1,54 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import loggerInjectable from "../../common/logger.injectable";
import attemptToListenInjectable from "./attempt-to-listen.injectable";
import { disallowedPorts } from "./disallowed-ports";
import lensProxyHttpsServerInjectable from "./https-proxy/server.injectable";
/**
* Starts the lens proxy.
* @resolves After the server is listening on a good port
* @rejects if there is an error before that happens
*/
export type StartLensProxyListening = () => Promise<void>;
const startLensProxyListeningInjectable = getInjectable({
id: "start-lens-proxy-listening",
instantiate: (di): StartLensProxyListening => {
const attemptToListen = di.inject(attemptToListenInjectable);
const logger = di.inject(loggerInjectable);
const proxyServer = di.inject(lensProxyHttpsServerInjectable);
return async () => {
const seenPorts = new Set<number>();
while(true) {
proxyServer.close();
const port = await attemptToListen();
if (!disallowedPorts.has(port)) {
// We didn't get a port that would result in an ERR_UNSAFE_PORT error, use it
return;
}
logger.warn(`[LENS-PROXY]: Proxy server has with port known to be considered unsafe to connect to by chrome, restarting...`);
if (seenPorts.has(port)) {
/**
* Assume that if we have seen the port before, then the OS has looped
* through all the ports possible and we will not be able to get a safe
* port.
*/
throw new Error("Failed to start LensProxy due to seeing too many unsafe ports. Please restart Lens.");
} else {
seenPorts.add(port);
}
}
};
},
});
export default startLensProxyListeningInjectable;

View File

@ -0,0 +1,25 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import loggerInjectable from "../../common/logger.injectable";
import lensProxyHttpsServerInjectable from "./https-proxy/server.injectable";
import proxyRetryInjectable from "./proxy/retry.injectable";
const stopLensProxyListeningInjectable = getInjectable({
id: "stop-lens-proxy-listening",
instantiate: (di) => {
const logger = di.inject(loggerInjectable);
const proxyServer = di.inject(lensProxyHttpsServerInjectable);
const proxyRetry = di.inject(proxyRetryInjectable);
return () => {
logger.info("[LENS-PROXY]: Closing server");
proxyServer.close();
proxyRetry.close();
};
},
});
export default stopLensProxyListeningInjectable;

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { beforeQuitOfBackEndInjectionToken } from "../start-main-application/runnable-tokens/phases";
import stopLensProxyListeningInjectable from "./stop-listening.injectable";
const stopLensProxyOnQuitInjectable = getInjectable({
id: "stop-lens-proxy-on-quit",
instantiate: (di) => ({
run: () => {
const stopLensProxyListening = di.inject(stopLensProxyListeningInjectable);
stopLensProxyListening();
return undefined;
},
}),
injectionToken: beforeQuitOfBackEndInjectionToken,
});
export default stopLensProxyOnQuitInjectable;

View File

@ -4,7 +4,6 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import exitAppInjectable from "../../electron-app/features/exit-app.injectable"; import exitAppInjectable from "../../electron-app/features/exit-app.injectable";
import lensProxyInjectable from "../../lens-proxy/lens-proxy.injectable";
import loggerInjectable from "../../../common/logger.injectable"; import loggerInjectable from "../../../common/logger.injectable";
import lensProxyPortInjectable from "../../lens-proxy/lens-proxy-port.injectable"; import lensProxyPortInjectable from "../../lens-proxy/lens-proxy-port.injectable";
import isWindowsInjectable from "../../../common/vars/is-windows.injectable"; import isWindowsInjectable from "../../../common/vars/is-windows.injectable";
@ -15,13 +14,14 @@ import initializeBuildVersionInjectable from "../../vars/build-version/init.inje
import lensProxyCertificateInjectable from "../../../common/certificate/lens-proxy-certificate.injectable"; import lensProxyCertificateInjectable from "../../../common/certificate/lens-proxy-certificate.injectable";
import fetchInjectable from "../../../common/fetch/fetch.injectable"; import fetchInjectable from "../../../common/fetch/fetch.injectable";
import { Agent } from "https"; import { Agent } from "https";
import startLensProxyListeningInjectable from "../../lens-proxy/start-listening.injectable";
const setupLensProxyInjectable = getInjectable({ const setupLensProxyInjectable = getInjectable({
id: "setup-lens-proxy", id: "setup-lens-proxy",
instantiate: (di) => ({ instantiate: (di) => ({
run: async () => { run: async () => {
const lensProxy = di.inject(lensProxyInjectable); const startLensProxyListening = di.inject(startLensProxyListeningInjectable);
const exitApp = di.inject(exitAppInjectable); const exitApp = di.inject(exitAppInjectable);
const logger = di.inject(loggerInjectable); const logger = di.inject(loggerInjectable);
const lensProxyPort = di.inject(lensProxyPortInjectable); const lensProxyPort = di.inject(lensProxyPortInjectable);
@ -33,7 +33,7 @@ const setupLensProxyInjectable = getInjectable({
try { try {
logger.info("🔌 Starting LensProxy"); logger.info("🔌 Starting LensProxy");
await lensProxy.listen(); // lensProxy.port available await startLensProxyListening();
} catch (error: any) { } catch (error: any) {
showErrorPopup("Lens Error", `Could not start proxy: ${error?.message || "unknown error"}`); showErrorPopup("Lens Error", `Could not start proxy: ${error?.message || "unknown error"}`);