fix: improve proxy URI handling (#810)
This commit is contained in:
parent
6490dc54ef
commit
e7e930d177
|
|
@ -18,6 +18,7 @@
|
|||
"main": "./src/index.ts",
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"test": "vitest",
|
||||
"typecheck": "tsup && tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
import { session } from "electron"
|
||||
import type { Mock } from "vitest"
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||
|
||||
import { logger } from "../logger"
|
||||
import { getProxyConfig, setProxyConfig, updateProxy } from "./proxy"
|
||||
import { store } from "./store"
|
||||
|
||||
vi.mock("electron", () => ({
|
||||
session: {
|
||||
defaultSession: {
|
||||
setProxy: vi.fn(),
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock("./store", () => ({
|
||||
store: {
|
||||
set: vi.fn(),
|
||||
get: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock("../logger", () => ({
|
||||
logger: {
|
||||
log: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
describe("proxy", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe("setProxyConfig", () => {
|
||||
it("should set proxy config and return true for valid proxy", () => {
|
||||
const proxy = "http://localhost:8080"
|
||||
const result = setProxyConfig(proxy)
|
||||
expect(store.set).toHaveBeenCalledWith("proxy", "http://localhost:8080")
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
it("should return false for invalid proxy", () => {
|
||||
const proxy = "invalid-proxy"
|
||||
const result = setProxyConfig(proxy)
|
||||
expect(store.set).toHaveBeenCalledWith("proxy", undefined)
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("getProxyConfig", () => {
|
||||
it("should return normalized proxy config if set", () => {
|
||||
;(store.get as Mock).mockReturnValue("http://localhost:8080")
|
||||
const result = getProxyConfig()
|
||||
expect(result).toBe("http://localhost:8080")
|
||||
})
|
||||
|
||||
it("should compatible dirty data", () => {
|
||||
;(store.get as Mock).mockReturnValue("http://localhost:8080,direct://")
|
||||
const result = getProxyConfig()
|
||||
expect(result).toBe("http://localhost:8080")
|
||||
})
|
||||
})
|
||||
|
||||
describe("updateProxy", () => {
|
||||
it("should set system proxy mode if no proxy config is set", () => {
|
||||
;(store.get as Mock).mockReturnValue("")
|
||||
updateProxy()
|
||||
expect(session.defaultSession.setProxy).toHaveBeenCalledWith({ mode: "system" })
|
||||
})
|
||||
|
||||
it("should set proxy rules if proxy config is set", () => {
|
||||
;(store.get as Mock).mockReturnValue("http://localhost:8080")
|
||||
updateProxy()
|
||||
expect(logger.log).toHaveBeenCalledWith("Loading proxy: http://localhost:8080,direct://")
|
||||
expect(session.defaultSession.setProxy).toHaveBeenCalledWith({
|
||||
proxyRules: "http://localhost:8080,direct://",
|
||||
proxyBypassRules: "<local>",
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -38,18 +38,17 @@ const normalizeProxyUri = (userProxy: string) => {
|
|||
if (!userProxy) {
|
||||
return
|
||||
}
|
||||
// Only use the first proxy if there are multiple urls
|
||||
const firstInput = userProxy.split(",")[0]
|
||||
|
||||
try {
|
||||
const proxyUrl = new URL(userProxy)
|
||||
const proxyUrl = new URL(firstInput)
|
||||
if (!URL_SCHEME.has(proxyUrl.protocol) || !proxyUrl.hostname || !proxyUrl.port) {
|
||||
return
|
||||
}
|
||||
// There are multiple ways to specify a proxy in Electron,
|
||||
// but for security reasons, we only support simple proxy URLs for now.
|
||||
return [
|
||||
`${proxyUrl.protocol}//${proxyUrl.hostname}:${proxyUrl.port}`,
|
||||
// Failing over to using no proxy if the proxy is unavailable
|
||||
"direct://",
|
||||
].join(",")
|
||||
return `${proxyUrl.protocol}//${proxyUrl.hostname}:${proxyUrl.port}`
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
@ -67,10 +66,15 @@ export const updateProxy = () => {
|
|||
})
|
||||
return
|
||||
}
|
||||
const proxyRules = [
|
||||
proxyUri,
|
||||
// Failing over to using no proxy if the proxy is unavailable
|
||||
"direct://",
|
||||
].join(",")
|
||||
|
||||
logger.log(`Loading proxy: ${proxyUri}`)
|
||||
logger.log(`Loading proxy: ${proxyRules}`)
|
||||
session.defaultSession.setProxy({
|
||||
proxyRules: proxyUri,
|
||||
proxyRules,
|
||||
proxyBypassRules: BYPASS_RULES,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
import { resolve } from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
|
||||
import tsconfigPath from "vite-tsconfig-paths"
|
||||
import { defineProject } from "vitest/config"
|
||||
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url))
|
||||
|
||||
export default defineProject({
|
||||
root: "./",
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "node",
|
||||
includeSource: [resolve(__dirname, ".")],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
tsconfigPath({
|
||||
projects: ["./tsconfig.json"],
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
"publish": "electron-vite build && electron-forge publish",
|
||||
"start": "electron-vite preview",
|
||||
"sync:ab": "tsx scripts/pull-ab-flags.ts",
|
||||
"test": "pnpm -F web run test",
|
||||
"test": "pnpm --recursive run test",
|
||||
"typecheck": "npm run typecheck:node && npm run typecheck:web",
|
||||
"typecheck:node": "pnpm -F electron-main run typecheck",
|
||||
"typecheck:web": "pnpm -F web run typecheck"
|
||||
|
|
|
|||
Loading…
Reference in New Issue