From 4f690ae0a75b1f7715a098065994101bda7e26c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Thu, 23 Jan 2025 16:58:33 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=85=8D=E7=BD=AE=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BB=A3=E7=A0=81=E9=87=8D=E6=9E=84=EF=BC=8C=E5=87=8F?= =?UTF-8?q?=E5=B0=91=E9=87=8D=E5=A4=8D=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/config.js | 138 +++-------------- packages/core/src/config/index.js | 139 +----------------- .../core/src/config/local-config-loader.js | 138 +++++++++++++++++ .../shell/scripts/set-system-proxy/index.js | 3 +- packages/core/src/utils/util.logger.js | 2 + packages/mitmproxy/src/json.js | 14 +- .../src/lib/proxy/compatible/compatible.js | 15 +- 7 files changed, 183 insertions(+), 266 deletions(-) create mode 100644 packages/core/src/config/local-config-loader.js diff --git a/packages/core/src/config.js b/packages/core/src/config.js index 729f18477c..7f1035a3e0 100644 --- a/packages/core/src/config.js +++ b/packages/core/src/config.js @@ -1,5 +1,4 @@ const fs = require('node:fs') -const path = require('node:path') const jsonApi = require('@docmirror/mitmproxy/src/json') const lodash = require('lodash') const request = require('request') @@ -7,6 +6,7 @@ const defConfig = require('./config/index.js') const mergeApi = require('./merge.js') const Shell = require('./shell') const log = require('./utils/util.log') +const configLoader = require('./config/local-config-loader') let configTarget = lodash.cloneDeep(defConfig) @@ -14,34 +14,6 @@ function get () { return configTarget } -const getDefaultConfigBasePath = function () { - return get().server.setting.userBasePath -} - -function _getRemoteSavePath (suffix = '') { - const dir = getDefaultConfigBasePath() - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir) - } - return path.join(dir, `/remote_config${suffix}.json5`) -} - -function _getConfigPath () { - const dir = getDefaultConfigBasePath() - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir) - return path.join(dir, '/config.json') - } else { - // 兼容1.7.3及以下版本的配置文件处理逻辑 - const newFilePath = path.join(dir, '/config.json') - const oldFilePath = path.join(dir, '/config.json5') - if (!fs.existsSync(newFilePath) && fs.existsSync(oldFilePath)) { - return oldFilePath // 如果新文件不存在,且旧文件存在,则返回旧文件路径 - } - return newFilePath - } -} - let timer const configApi = { async startAutoDownloadRemoteConfig () { @@ -68,13 +40,10 @@ const configApi = { } const remoteConfig = get().app.remoteConfig - await configApi.doDownloadCommonRemoteConfig(remoteConfig.url) - await configApi.doDownloadCommonRemoteConfig(remoteConfig.personalUrl, '_personal') + await configApi.doDownloadRemoteConfig(remoteConfig.url) + await configApi.doDownloadRemoteConfig(remoteConfig.personalUrl, '_personal') }, - doDownloadCommonRemoteConfig (remoteConfigUrl, suffix = '') { - if (get().app.remoteConfig.enabled !== true) { - return - } + doDownloadRemoteConfig (remoteConfigUrl, suffix = '') { if (!remoteConfigUrl) { // 删除保存的远程配置文件 configApi.deleteRemoteConfigFile(suffix) @@ -116,7 +85,7 @@ const configApi = { } if (remoteConfig != null) { - const remoteSavePath = _getRemoteSavePath(suffix) + const remoteSavePath = configLoader.getRemoteConfigPath(suffix) fs.writeFileSync(remoteSavePath, body) log.info('保存远程配置文件成功:', remoteSavePath) } else { @@ -139,35 +108,15 @@ const configApi = { }) }, deleteRemoteConfigFile (suffix = '') { - const remoteSavePath = _getRemoteSavePath(suffix) + const remoteSavePath = configLoader.getRemoteConfigPath(suffix) if (fs.existsSync(remoteSavePath)) { fs.unlinkSync(remoteSavePath) log.info('删除远程配置文件成功:', remoteSavePath) } }, - readRemoteConfig (suffix = '') { - try { - return jsonApi.parse(configApi.readRemoteConfigStr(suffix)) - } catch (e) { - log.error(`读取远程配置失败,suffix: ${suffix}`, e) - return {} - } - }, readRemoteConfigStr (suffix = '') { - if (get().app.remoteConfig.enabled !== true) { - if (suffix === '_personal') { - if (!get().app.remoteConfig.personalUrl) { - return '{}' - } - } else if (suffix === '') { - if (!get().app.remoteConfig.url) { - return '{}' - } - } - return '{}' - } try { - const path = _getRemoteSavePath(suffix) + const path = configLoader.getRemoteConfigPath(suffix) if (fs.existsSync(path)) { const file = fs.readFileSync(path) log.info('读取远程配置文件内容成功:', path) @@ -187,21 +136,23 @@ const configApi = { */ save (newConfig) { // 对比默认config的异同 - let defConfig = configApi.getDefault() + const defConfig = configApi.cloneDefault() // 如果开启了远程配置,则读取远程配置,合并到默认配置中 if (get().app.remoteConfig.enabled === true) { if (get().app.remoteConfig.url) { - defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig()) + mergeApi.doMerge(defConfig, configLoader.getRemoteConfig()) } if (get().app.remoteConfig.personalUrl) { - defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig('_personal')) + mergeApi.doMerge(defConfig, configLoader.getRemoteConfig('_personal')) } } - // 计算新配置与默认配置(启用远程配置时,含远程配置)的差异,并保存到 config.json 中 + // 计算新配置与默认配置(启用远程配置时,含远程配置)的差异 const diffConfig = mergeApi.doDiff(defConfig, newConfig) - const configPath = _getConfigPath() + + // 将差异作为用户配置保存到 config.json 中 + const configPath = configLoader.getUserConfigPath() fs.writeFileSync(configPath, jsonApi.stringify(diffConfig)) log.info('保存 config.json 自定义配置文件成功:', configPath) @@ -219,25 +170,8 @@ const configApi = { * 读取 config.json 后,合并配置 */ reload () { - const configPath = _getConfigPath() - let userConfig - if (!fs.existsSync(configPath)) { - userConfig = {} - log.info('config.json 文件不存在:', configPath) - } else { - const file = fs.readFileSync(configPath) - log.info('读取 config.json 成功:', configPath) - const fileStr = file.toString() - try { - userConfig = jsonApi.parse(fileStr) - } catch (e) { - log.error(`config.json 文件内容格式不正确,文件路径:${configPath},文件内容: ${fileStr}, error:`, e) - userConfig = {} - } - } - - const config = configApi.set(userConfig) - return config || {} + const userConfig = configLoader.getUserConfig() + return configApi.set(userConfig) || {} }, update (partConfig) { const newConfig = lodash.merge(configApi.get(), partConfig) @@ -252,41 +186,11 @@ const configApi = { return configApi.load(newConfig) }, load (newConfig) { - // 以用户配置作为基准配置,是为了保证用户配置的顺序在前 - const merged = newConfig != null ? lodash.cloneDeep(newConfig) : {} - - if (get().app.remoteConfig.enabled === true) { - let personalRemoteConfig = null - let shareRemoteConfig = null - - if (get().app.remoteConfig.personalUrl) { - personalRemoteConfig = configApi.readRemoteConfig('_personal') - mergeApi.doMerge(merged, personalRemoteConfig) // 先合并一次个人远程配置,使配置顺序在前 - } - if (get().app.remoteConfig.url) { - shareRemoteConfig = configApi.readRemoteConfig() - mergeApi.doMerge(merged, shareRemoteConfig) // 先合并一次共享远程配置,使配置顺序在前 - } - mergeApi.doMerge(merged, defConfig) // 合并默认配置,顺序排在最后 - if (get().app.remoteConfig.url) { - mergeApi.doMerge(merged, shareRemoteConfig) // 再合并一次共享远程配置,使配置生效 - } - if (get().app.remoteConfig.personalUrl) { - mergeApi.doMerge(merged, personalRemoteConfig) // 再合并一次个人远程配置,使配置生效 - } - } else { - mergeApi.doMerge(merged, defConfig) // 合并默认配置 - } - if (newConfig != null) { - mergeApi.doMerge(merged, newConfig) // 再合并一次用户配置,使用户配置重新生效 - } - mergeApi.deleteNullItems(merged) // 删除为null及[delete]的项 - configTarget = merged - log.info('加载及合并远程配置完成') - - return configTarget + const config = configLoader.getConfigFromFiles(newConfig, defConfig) + configTarget = config + return config }, - getDefault () { + cloneDefault () { return lodash.cloneDeep(defConfig) }, addDefault (key, defValue) { @@ -294,7 +198,7 @@ const configApi = { }, // 移除用户配置,用于恢复出厂设置功能 async removeUserConfig () { - const configPath = _getConfigPath() + const configPath = configLoader.getUserConfigPath() if (fs.existsSync(configPath)) { // 读取 config.json 文件内容 const fileOriginalStr = fs.readFileSync(configPath).toString() diff --git a/packages/core/src/config/index.js b/packages/core/src/config/index.js index 19cb72f939..968d5a50ab 100644 --- a/packages/core/src/config/index.js +++ b/packages/core/src/config/index.js @@ -1,20 +1,12 @@ -const fs = require('node:fs') const path = require('node:path') -const lodash = require('lodash') -const jsonApi = require('@docmirror/mitmproxy/src/json') -const mergeApi = require('../merge') - -function getUserBasePath () { - const userHome = process.env.USERPROFILE || process.env.HOME || '/' - return path.resolve(userHome, './.dev-sidecar') -} +const configLoader = require('./local-config-loader') function getRootCaCertPath () { - return path.join(getUserBasePath(), '/dev-sidecar.ca.crt') + return path.join(configLoader.getUserBasePath(), '/dev-sidecar.ca.crt') } function getRootCaKeyPath () { - return path.join(getUserBasePath(), '/dev-sidecar.ca.key.pem') + return path.join(configLoader.getUserBasePath(), '/dev-sidecar.ca.key.pem') } const defaultConfig = { @@ -43,7 +35,7 @@ const defaultConfig = { showShutdownTip: true, // 日志相关配置 - logFileSavePath: path.join(getUserBasePath(), '/logs'), // 日志文件保存路径 + logFileSavePath: path.join(configLoader.getUserBasePath(), '/logs'), // 日志文件保存路径 keepLogFileCount: 15, // 保留日志文件数 }, server: { @@ -57,7 +49,7 @@ const defaultConfig = { enabled: true, defaultDir: './extra/scripts/', }, - userBasePath: getUserBasePath(), + userBasePath: configLoader.getUserBasePath(), rootCaFile: { certPath: getRootCaCertPath(), keyPath: getRootCaKeyPath(), @@ -447,126 +439,7 @@ const defaultConfig = { }, } -// region 加载本地配置文件所需的方法 - -function _getConfigPath () { - const dir = defaultConfig.server.setting.userBasePath - if (!fs.existsSync(dir)) { - return null - } - - // 兼容1.7.3及以下版本的配置文件处理逻辑 - const newFilePath = path.join(dir, '/config.json') - const oldFilePath = path.join(dir, '/config.json5') - if (!fs.existsSync(newFilePath)) { - if (fs.existsSync(oldFilePath)) { - return oldFilePath // 如果新文件不存在,且旧文件存在,则返回旧文件路径 - } else { - return null // 两个文件都不存在 - } - } - - return newFilePath -} - -function _getConfig () { - const configFilePath = _getConfigPath() - if (configFilePath == null) { - return {} - } - - if (!fs.existsSync(configFilePath)) { - return {} - } - - try { - return jsonApi.parse(fs.readFileSync(configFilePath)) - } catch (e) { - console.error('读取配置文件失败:', configFilePath, e) - return {} - } -} - -function _getRemoteSavePath (suffix = '') { - const dir = defaultConfig.server.setting.userBasePath - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir) - } - return path.join(dir, `/remote_config${suffix}.json5`) -} - -function _readRemoteConfigStr (suffix = '') { - if (defaultConfig.app.remoteConfig.enabled !== true) { - if (suffix === '_personal') { - if (!defaultConfig.app.remoteConfig.personalUrl) { - return '{}' - } - } else if (suffix === '') { - if (!defaultConfig.app.remoteConfig.url) { - return '{}' - } - } - return '{}' - } - try { - const path = _getRemoteSavePath(suffix) - if (fs.existsSync(path)) { - const file = fs.readFileSync(path) - return file.toString() - } - } catch { - } - - return '{}' -} - -function _readRemoteConfig (suffix = '') { - try { - return jsonApi.parse(_readRemoteConfigStr(suffix)) - } catch (e) { - console.error(`读取远程配置失败,suffix: ${suffix}`, e) - return {} - } -} - -function _getConfigFromFiles () { - const newConfig = _getConfig() - - const merged = newConfig != null ? lodash.cloneDeep(newConfig) : {} - - if (defaultConfig.app.remoteConfig.enabled === true) { - let personalRemoteConfig = null - let shareRemoteConfig = null - - if (defaultConfig.app.remoteConfig.personalUrl) { - personalRemoteConfig = _readRemoteConfig('_personal') - mergeApi.doMerge(merged, personalRemoteConfig) // 先合并一次个人远程配置,使配置顺序在前 - } - if (defaultConfig.app.remoteConfig.url) { - shareRemoteConfig = _readRemoteConfig() - mergeApi.doMerge(merged, shareRemoteConfig) // 先合并一次共享远程配置,使配置顺序在前 - } - mergeApi.doMerge(merged, defaultConfig) // 合并默认配置,顺序排在最后 - if (defaultConfig.app.remoteConfig.url) { - mergeApi.doMerge(merged, shareRemoteConfig) // 再合并一次共享远程配置,使配置生效 - } - if (defaultConfig.app.remoteConfig.personalUrl) { - mergeApi.doMerge(merged, personalRemoteConfig) // 再合并一次个人远程配置,使配置生效 - } - } else { - mergeApi.doMerge(merged, defaultConfig) // 合并默认配置 - } - if (newConfig != null) { - mergeApi.doMerge(merged, newConfig) // 再合并一次用户配置,使用户配置重新生效 - } - mergeApi.deleteNullItems(merged) // 删除为null及[delete]的项 - - return merged -} - -// endregion - // 从本地文件中加载配置 -defaultConfig.configFromFiles = _getConfigFromFiles() +defaultConfig.configFromFiles = configLoader.getConfigFromFiles(configLoader.getUserConfig(), defaultConfig) module.exports = defaultConfig diff --git a/packages/core/src/config/local-config-loader.js b/packages/core/src/config/local-config-loader.js new file mode 100644 index 0000000000..994ad09f9d --- /dev/null +++ b/packages/core/src/config/local-config-loader.js @@ -0,0 +1,138 @@ +const fs = require('node:fs') +const path = require('node:path') +const lodash = require('lodash') +const jsonApi = require('@docmirror/mitmproxy/src/json') +const mergeApi = require('../merge') + +let log = console // 默认使用console,日志系统初始化完成后,设置为 logger +function setLogger (logger) { + log = logger + jsonApi.setLogger(logger) +} + +function getUserBasePath (autoCreate = true) { + const userHome = process.env.USERPROFILE || process.env.HOME || '/' + const dir = path.resolve(userHome, './.dev-sidecar') + + // 自动创建目录 + if (autoCreate && !fs.existsSync(dir)) { + fs.mkdirSync(dir) + } + + return dir +} + +function loadConfigFromFile (configFilePath) { + if (configFilePath == null) { + log.warn('配置文件地址为空') + return {} + } + + if (!fs.existsSync(configFilePath)) { + log.info('配置文件不存在:', configFilePath) + return {} // 文件不存在,返回空配置 + } + + // 读取配置文件 + let configStr + try { + configStr = fs.readFileSync(configFilePath) + } catch (e) { + log.error('读取配置文件失败:', configFilePath, ', error:', e) + return {} + } + + // 解析配置文件 + try { + const config = jsonApi.parse(configStr) + log.info('读取配置文件成功:', configFilePath) + return config + } catch (e) { + log.error(`解析配置文件失败,文件内容格式不正确,文件路径: ${configFilePath},文件内容:${configStr},error:`, e) + return {} + } +} + +function getUserConfigPath () { + const dir = getUserBasePath() + + // 兼容1.7.3及以下版本的配置文件处理逻辑 + const newFilePath = path.join(dir, '/config.json') + const oldFilePath = path.join(dir, '/config.json5') + if (!fs.existsSync(newFilePath)) { + if (fs.existsSync(oldFilePath)) { + return oldFilePath // 如果新文件不存在,但旧文件存在,则返回旧文件路径 + } else { + return null // 两个文件都不存在 + } + } + + return newFilePath +} + +function getUserConfig () { + const configFilePath = getUserConfigPath() + return loadConfigFromFile(configFilePath) +} + +function getRemoteConfigPath (suffix = '') { + const dir = getUserBasePath() + return path.join(dir, `/remote_config${suffix}.json5`) +} + +function getRemoteConfig (suffix = '') { + const remoteConfigFilePath = getRemoteConfigPath(suffix) + return loadConfigFromFile(remoteConfigFilePath) +} + +function getAutomaticCompatibleConfigPath () { + const dir = getUserBasePath() + return path.join(dir, '/automaticCompatibleConfig.json') +} + +/** + * 从文件读取配置 + * + * @param userConfig 用户配置 + * @param defaultConfig 默认配置 + */ +function getConfigFromFiles (userConfig, defaultConfig) { + const merged = userConfig != null ? lodash.cloneDeep(userConfig) : {} + + const personalRemoteConfig = getRemoteConfig('_personal') + const shareRemoteConfig = getRemoteConfig() + + mergeApi.doMerge(merged, personalRemoteConfig) // 先合并一次个人远程配置,使配置顺序在前 + mergeApi.doMerge(merged, shareRemoteConfig) // 先合并一次共享远程配置,使配置顺序在前 + mergeApi.doMerge(merged, defaultConfig) // 合并默认配置,顺序排在最后 + mergeApi.doMerge(merged, shareRemoteConfig) // 再合并一次共享远程配置,使配置生效 + mergeApi.doMerge(merged, personalRemoteConfig) // 再合并一次个人远程配置,使配置生效 + + if (userConfig != null) { + mergeApi.doMerge(merged, userConfig) // 再合并一次用户配置,使用户配置重新生效 + } + + // 删除为null及[delete]的项 + mergeApi.deleteNullItems(merged) + + log.info('加载及合并远程配置完成') + return merged +} + +module.exports = { + setLogger, + + getUserBasePath, + + loadConfigFromFile, + + getUserConfigPath, + getUserConfig, + + getRemoteConfigPath, + getRemoteConfig, + + getAutomaticCompatibleConfigPath, + + getConfigFromFiles, +} diff --git a/packages/core/src/shell/scripts/set-system-proxy/index.js b/packages/core/src/shell/scripts/set-system-proxy/index.js index 6002d4fc06..3dccea691c 100644 --- a/packages/core/src/shell/scripts/set-system-proxy/index.js +++ b/packages/core/src/shell/scripts/set-system-proxy/index.js @@ -160,6 +160,7 @@ function getProxyExcludeIpStr (split) { } // 排除国内域名 + // log.debug('系统代理排除域名(excludeIpStr):', excludeIpStr) if (config.get().proxy.excludeDomesticDomainAllowList) { try { let domesticDomainAllowList = getDomesticDomainAllowList() @@ -177,8 +178,6 @@ function getProxyExcludeIpStr (split) { } } - log.debug('系统代理排除域名(excludeIpStr):', excludeIpStr) - return excludeIpStr } diff --git a/packages/core/src/utils/util.logger.js b/packages/core/src/utils/util.logger.js index 60697aa969..c4de3ba29f 100644 --- a/packages/core/src/utils/util.logger.js +++ b/packages/core/src/utils/util.logger.js @@ -1,5 +1,6 @@ const path = require('node:path') const log4js = require('log4js') +const configLoader = require('../config/local-config-loader') const configFromFiles = require('../config/index').configFromFiles // 日志级别 @@ -52,6 +53,7 @@ function log4jsConfigure (categories) { // 拿第一个日志类型来logger并设置到log变量中 log = log4js.getLogger(categories[0]) + configLoader.setLogger(log) log.info('设置日志配置完成:', config) } diff --git a/packages/mitmproxy/src/json.js b/packages/mitmproxy/src/json.js index d8dfa9d403..6ba5a785d7 100644 --- a/packages/mitmproxy/src/json.js +++ b/packages/mitmproxy/src/json.js @@ -1,18 +1,26 @@ let JSON5 = require('json5') - if (JSON5.default) { JSON5 = JSON5.default } +let log = console // 默认使用console,日志系统初始化完成后,设置为 logger +function setLogger (logger) { + log = logger +} + module.exports = { parse (str, defaultValue) { if (str == null || str.length < 2) { return defaultValue || {} } + + str = str.toString() + if (defaultValue != null) { try { return JSON5.parse(str) - } catch { + } catch (e) { + log.error(`JSON5解析失败: ${e.message},JSON内容:\r\n`, str) return defaultValue } } else { @@ -35,4 +43,6 @@ module.exports = { } } }, + + setLogger, } diff --git a/packages/mitmproxy/src/lib/proxy/compatible/compatible.js b/packages/mitmproxy/src/lib/proxy/compatible/compatible.js index 04bc3feec2..803c73012f 100644 --- a/packages/mitmproxy/src/lib/proxy/compatible/compatible.js +++ b/packages/mitmproxy/src/lib/proxy/compatible/compatible.js @@ -6,10 +6,10 @@ * @author WangLiang */ const fs = require('node:fs') -const path = require('node:path') const jsonApi = require('../../../json') const log = require('../../../utils/util.log') const matchUtil = require('../../../utils/util.match') +const configLoader = require('@docmirror/dev-sidecar/src/config/local-config-loader') const defaultConfig = { // connect阶段所需的兼容性配置 @@ -43,17 +43,8 @@ function _getRequestConfig (hostname, port) { // region 本地配置文件所需函数 -function _getConfigPath () { - const userHome = process.env.USERPROFILE || process.env.HOME || '/' - const dir = path.resolve(userHome, './.dev-sidecar') - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir) - } - return path.join(dir, '/automaticCompatibleConfig.json') -} - function _loadFromFile (defaultConfig) { - const configPath = _getConfigPath() + const configPath = configLoader.getAutomaticCompatibleConfigPath() let config if (!fs.existsSync(configPath)) { config = defaultConfig @@ -80,7 +71,7 @@ function _loadFromFile (defaultConfig) { } function _saveConfigToFile () { - const filePath = _getConfigPath() + const filePath = configLoader.getAutomaticCompatibleConfigPath() try { fs.writeFileSync(filePath, jsonApi.stringify(config)) log.info('保存 automaticCompatibleConfig.json 成功:', filePath)