fix: improve proxy URI handling (#810)

This commit is contained in:
Whitewater 2024-10-08 17:55:05 -08:00 committed by GitHub
parent 6490dc54ef
commit e7e930d177
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 118 additions and 9 deletions

View File

@ -18,6 +18,7 @@
"main": "./src/index.ts",
"scripts": {
"build": "tsup",
"test": "vitest",
"typecheck": "tsup && tsc --noEmit"
},
"dependencies": {

View File

@ -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>",
})
})
})
})

View File

@ -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,
})
}

View File

@ -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"],
}),
],
})

View File

@ -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"