lint all files
parent
47608ffef9
commit
64795cc509
|
|
@ -5,9 +5,11 @@ labels: Bug
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- 如果搜索过但未找到,请将 `[ ]` 替换为 `[x]` -->
|
<!-- 如果搜索过但未找到,请将 `[ ]` 替换为 `[x]` -->
|
||||||
|
|
||||||
- [ ] 你是否在现有 [Issue列表](/docmirror/dev-sidecar/issues) 中搜索过相同问题,但未找到?
|
- [ ] 你是否在现有 [Issue列表](/docmirror/dev-sidecar/issues) 中搜索过相同问题,但未找到?
|
||||||
|
|
||||||
### Ⅰ. 请说明操作系统及DS的版本号:
|
### Ⅰ. 请说明操作系统及DS的版本号:
|
||||||
|
|
||||||
1. 操作系统:?
|
1. 操作系统:?
|
||||||
2. DS版本号:? <!-- 如:`1.8.6-node17` -->
|
2. DS版本号:? <!-- 如:`1.8.6-node17` -->
|
||||||
|
|
||||||
|
|
@ -22,10 +24,15 @@ labels: Bug
|
||||||
3. xxx
|
3. xxx
|
||||||
|
|
||||||
### Ⅴ. 请提供相关的错误日志,尽可能的详细:(日志文件在 `${user.home}/.dev-sidecar/logs/` 目录下)
|
### Ⅴ. 请提供相关的错误日志,尽可能的详细:(日志文件在 `${user.home}/.dev-sidecar/logs/` 目录下)
|
||||||
|
|
||||||
```log
|
```log
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ⅵ. 有必要时,请提供 `${user.home}/.dev-sidecar/running.json` 文件内容:
|
### Ⅵ. 有必要时,请提供 `${user.home}/.dev-sidecar/running.json` 文件内容:
|
||||||
|
|
||||||
<!-- 请将 'running.json' 文件的内容粘贴在这里,方便我们排查问题是否由配置错误导致。 -->
|
<!-- 请将 'running.json' 文件的内容粘贴在这里,方便我们排查问题是否由配置错误导致。 -->
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@ labels: Style Issue
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- 如果搜索过但未找到,请将 `[ ]` 替换为 `[x]` -->
|
<!-- 如果搜索过但未找到,请将 `[ ]` 替换为 `[x]` -->
|
||||||
|
|
||||||
- [ ] 你是否在现有 [Issue列表](/docmirror/dev-sidecar/issues) 中搜索过相同问题,但未找到?
|
- [ ] 你是否在现有 [Issue列表](/docmirror/dev-sidecar/issues) 中搜索过相同问题,但未找到?
|
||||||
|
|
||||||
### Ⅰ. 请说明操作系统及DS的版本号:
|
### Ⅰ. 请说明操作系统及DS的版本号:
|
||||||
|
|
||||||
1. 操作系统:?
|
1. 操作系统:?
|
||||||
2. DS版本号:? <!-- 如:`1.8.6-node17` -->
|
2. DS版本号:? <!-- 如:`1.8.6-node17` -->
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ labels: Config Issue
|
||||||
---
|
---
|
||||||
|
|
||||||
### Ⅰ. 你对哪个功能的配置不了解?
|
### Ⅰ. 你对哪个功能的配置不了解?
|
||||||
|
|
||||||
<!-- 请选择一个或多个选项,将前面的 `[ ]` 修改为 `[x]` 即可。 -->
|
<!-- 请选择一个或多个选项,将前面的 `[ ]` 修改为 `[x]` 即可。 -->
|
||||||
|
|
||||||
- [ ] 拦截设置:
|
- [ ] 拦截设置:
|
||||||
|
|
@ -28,6 +29,9 @@ labels: Config Issue
|
||||||
### Ⅱ. 请详细描述你的问题:
|
### Ⅱ. 请详细描述你的问题:
|
||||||
|
|
||||||
### Ⅲ. 有必要时,请提供 `${user.home}/.dev-sidecar/running.json` 文件内容:
|
### Ⅲ. 有必要时,请提供 `${user.home}/.dev-sidecar/running.json` 文件内容:
|
||||||
|
|
||||||
<!-- 请将 'running.json' 文件的内容粘贴在这里,方便我们排查问题是否由配置错误导致。 -->
|
<!-- 请将 'running.json' 文件的内容粘贴在这里,方便我们排查问题是否由配置错误导致。 -->
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,13 @@ labels: Feature Request
|
||||||
---
|
---
|
||||||
|
|
||||||
### Ⅰ. 请描述你想要的新功能:
|
### Ⅰ. 请描述你想要的新功能:
|
||||||
|
|
||||||
<!-- 请简单描述你希望的新功能,例如:"在某某页面,添加一个按钮,点击按钮时,弹出一个某某对话框,用于xxx。" -->
|
<!-- 请简单描述你希望的新功能,例如:"在某某页面,添加一个按钮,点击按钮时,弹出一个某某对话框,用于xxx。" -->
|
||||||
|
|
||||||
### Ⅱ. 请描述你心目中新功能的样子:
|
### Ⅱ. 请描述你心目中新功能的样子:
|
||||||
|
|
||||||
<!-- 可以讲讲你对新功能的看法,可以解释更多关于该功能的输入和输出的信息,或贴上你设想的界面设计。 -->
|
<!-- 可以讲讲你对新功能的看法,可以解释更多关于该功能的输入和输出的信息,或贴上你设想的界面设计。 -->
|
||||||
|
|
||||||
### Ⅲ. 你希望该新功能修复哪个issue?
|
### Ⅲ. 你希望该新功能修复哪个issue?
|
||||||
|
|
||||||
<!-- 请将相关issue的编号填写在下面,格式如:#123 -->
|
<!-- 请将相关issue的编号填写在下面,格式如:#123 -->
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
### Ⅰ. 描述此PR的作用:
|
### Ⅰ. 描述此PR的作用:
|
||||||
|
|
||||||
### Ⅱ. 此PR修复了哪个issue吗?
|
### Ⅱ. 此PR修复了哪个issue吗?
|
||||||
|
|
||||||
<!-- 如果是的话, 请在下一行写上 "fixes #xxx",比如:fixes #97 -->
|
<!-- 如果是的话, 请在下一行写上 "fixes #xxx",比如:fixes #97 -->
|
||||||
|
|
||||||
### Ⅲ. 界面变化截屏
|
### Ⅲ. 界面变化截屏
|
||||||
|
|
||||||
<!-- 如果存在界面上的变化,请截屏展示出来 -->
|
<!-- 如果存在界面上的变化,请截屏展示出来 -->
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: 'Build And Release'
|
name: Build And Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
node:
|
node:
|
||||||
- 22
|
- 22
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout'
|
- name: Checkout
|
||||||
uses: actions/checkout@v4.1.7
|
uses: actions/checkout@v4.1.7
|
||||||
|
|
||||||
- name: 'Setup Node.js "${{ matrix.node }}.x" environment'
|
- name: 'Setup Node.js "${{ matrix.node }}.x" environment'
|
||||||
|
|
@ -30,22 +30,22 @@ jobs:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
registry-url: https://npm.pkg.github.com/
|
registry-url: https://npm.pkg.github.com/
|
||||||
|
|
||||||
- name: 'Setup pnpm'
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
|
|
||||||
- name: 'Setup Python environment (Mac) Because of electron-builder install-app-deps requires Python setup tools'
|
- name: Setup Python environment (Mac) Because of electron-builder install-app-deps requires Python setup tools
|
||||||
if: matrix.os == 'macos'
|
if: matrix.os == 'macos'
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version: '3.10'
|
||||||
|
|
||||||
- name: 'Get package info'
|
- name: Get package info
|
||||||
id: package-info
|
id: package-info
|
||||||
uses: luizfelipelaviola/get-package-info@v1
|
uses: luizfelipelaviola/get-package-info@v1
|
||||||
with:
|
with:
|
||||||
path: ./packages/mitmproxy
|
path: ./packages/mitmproxy
|
||||||
|
|
||||||
- name: 'Print'
|
- name: Print
|
||||||
run: |
|
run: |
|
||||||
echo "version = ${{ steps.package-info.outputs.version }}";
|
echo "version = ${{ steps.package-info.outputs.version }}";
|
||||||
echo "github.ref_type = ${{ github.ref_type }}";
|
echo "github.ref_type = ${{ github.ref_type }}";
|
||||||
|
|
@ -69,7 +69,7 @@ jobs:
|
||||||
echo "--------------------";
|
echo "--------------------";
|
||||||
python --version;
|
python --version;
|
||||||
|
|
||||||
- name: 'pnpm install'
|
- name: pnpm install
|
||||||
run: |
|
run: |
|
||||||
echo "======================================================================";
|
echo "======================================================================";
|
||||||
dir || ls -lah;
|
dir || ls -lah;
|
||||||
|
|
@ -139,10 +139,10 @@ jobs:
|
||||||
needs:
|
needs:
|
||||||
- build-and-upload
|
- build-and-upload
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout'
|
- name: Checkout
|
||||||
uses: actions/checkout@v4.1.7
|
uses: actions/checkout@v4.1.7
|
||||||
|
|
||||||
- name: 'Get package info'
|
- name: Get package info
|
||||||
id: package-info
|
id: package-info
|
||||||
uses: luizfelipelaviola/get-package-info@v1
|
uses: luizfelipelaviola/get-package-info@v1
|
||||||
with:
|
with:
|
||||||
|
|
@ -177,7 +177,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
ls -lah release;
|
ls -lah release;
|
||||||
|
|
||||||
- name: 'Create a draft release'
|
- name: Create a draft release
|
||||||
uses: wangliang181230/github-action-ghr@master
|
uses: wangliang181230/github-action-ghr@master
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
name: 'Test And Upload'
|
name: Test And Upload
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- '1.x'
|
- 1.x
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
node:
|
node:
|
||||||
- 22
|
- 22
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout'
|
- name: Checkout
|
||||||
uses: actions/checkout@v4.1.7
|
uses: actions/checkout@v4.1.7
|
||||||
|
|
||||||
- name: 'Setup Node.js "${{ matrix.node }}.x" environment'
|
- name: 'Setup Node.js "${{ matrix.node }}.x" environment'
|
||||||
|
|
@ -31,22 +31,22 @@ jobs:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
registry-url: https://npm.pkg.github.com/
|
registry-url: https://npm.pkg.github.com/
|
||||||
|
|
||||||
- name: 'Setup pnpm'
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
|
|
||||||
- name: 'Setup Python environment (Mac) Because of electron-builder install-app-deps requires Python setup tools'
|
- name: Setup Python environment (Mac) Because of electron-builder install-app-deps requires Python setup tools
|
||||||
if: matrix.os == 'macos'
|
if: matrix.os == 'macos'
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version: '3.10'
|
||||||
|
|
||||||
- name: 'Get package info'
|
- name: Get package info
|
||||||
id: package-info
|
id: package-info
|
||||||
uses: luizfelipelaviola/get-package-info@v1
|
uses: luizfelipelaviola/get-package-info@v1
|
||||||
with:
|
with:
|
||||||
path: ./packages/mitmproxy
|
path: ./packages/mitmproxy
|
||||||
|
|
||||||
- name: 'Print'
|
- name: Print
|
||||||
run: |
|
run: |
|
||||||
echo "version = ${{ steps.package-info.outputs.version }}";
|
echo "version = ${{ steps.package-info.outputs.version }}";
|
||||||
echo "github.ref_type = ${{ github.ref_type }}";
|
echo "github.ref_type = ${{ github.ref_type }}";
|
||||||
|
|
@ -70,7 +70,7 @@ jobs:
|
||||||
echo "--------------------";
|
echo "--------------------";
|
||||||
python --version;
|
python --version;
|
||||||
|
|
||||||
- name: 'pnpm install'
|
- name: pnpm install
|
||||||
run: |
|
run: |
|
||||||
echo "======================================================================";
|
echo "======================================================================";
|
||||||
dir || ls -lah;
|
dir || ls -lah;
|
||||||
|
|
|
||||||
176
README.md
176
README.md
|
|
@ -5,80 +5,77 @@
|
||||||
|
|
||||||
<a href='https://github.com/docmirror/dev-sidecar'><img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"></a>
|
<a href='https://github.com/docmirror/dev-sidecar'><img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"></a>
|
||||||
|
|
||||||
>
|
|
||||||
> Gitee上的同步项目已被封禁,此项目将不再更新与维护 【狗头保命】
|
> Gitee上的同步项目已被封禁,此项目将不再更新与维护 【狗头保命】
|
||||||
>
|
>
|
||||||
> 我将继续奋战在开源一线,为社区贡献更多更好的开源项目。
|
> 我将继续奋战在开源一线,为社区贡献更多更好的开源项目。
|
||||||
> 感兴趣的可以关注我的主页 [【github】](https://github.com/greper) [【gitee】](https://gitee.com/greper)
|
> 感兴趣的可以关注我的主页 [【github】](https://github.com/greper) [【gitee】](https://gitee.com/greper)
|
||||||
>
|
|
||||||
## 打个广告
|
## 打个广告
|
||||||
>
|
|
||||||
> <https://github.com/certd/certd>
|
> <https://github.com/certd/certd>
|
||||||
> 我的开源证书管理工具项目,全自动申请和部署证书,有需求的可以去试试,帮忙点个star
|
> 我的开源证书管理工具项目,全自动申请和部署证书,有需求的可以去试试,帮忙点个star
|
||||||
|
|
||||||
## 重要提醒
|
## 重要提醒
|
||||||
>
|
|
||||||
> ------------------------------重要提醒1---------------------------------
|
> ------------------------------重要提醒1---------------------------------
|
||||||
>
|
>
|
||||||
> 注意:由于electron无法监听windows的关机事件,开着ds情况下直接重启电脑,会导致无法上网,你可以手动启动ds即可恢复网络,你也可以将ds设置为开机自启。
|
> 注意:由于electron无法监听windows的关机事件,开着ds情况下直接重启电脑,会导致无法上网,你可以手动启动ds即可恢复网络,你也可以将ds设置为开机自启。
|
||||||
>
|
>
|
||||||
> 关于此问题的更多讨论请前往:
|
> 关于此问题的更多讨论请前往:
|
||||||
> <https://github.com/docmirror/dev-sidecar/issues/109>
|
> <https://github.com/docmirror/dev-sidecar/issues/109>
|
||||||
>
|
|
||||||
|
|
||||||
> ------------------------------重要提醒2---------------------------------
|
> ------------------------------重要提醒2---------------------------------
|
||||||
>
|
>
|
||||||
> 注意:本应用启动会自动修改系统代理,所以会与其他代理软件有冲突,请务必不要一起使用。
|
> 注意:本应用启动会自动修改系统代理,所以会与其他代理软件有冲突,请务必不要一起使用。
|
||||||
> 本应用主要目的在于直连访问github,如果你已经有飞机了,那建议还是不要用这个自行车(ds)了
|
> 本应用主要目的在于直连访问github,如果你已经有飞机了,那建议还是不要用这个自行车(ds)了
|
||||||
>
|
|
||||||
|
|
||||||
## 一、 特性
|
## 一、 特性
|
||||||
|
|
||||||
### 1.1、 dns优选(解决***污染问题)
|
### 1.1、 dns优选(解决\*\*\*污染问题)
|
||||||
|
|
||||||
* 根据网络状况智能解析最佳域名ip地址,获取最佳网络速度
|
- 根据网络状况智能解析最佳域名ip地址,获取最佳网络速度
|
||||||
* 解决一些网站和库无法访问或访问速度慢的问题
|
- 解决一些网站和库无法访问或访问速度慢的问题
|
||||||
* 建议遇到打开比较慢的国外网站,可以优先尝试将该域名添加到dns设置中(注意:被***封杀的无效)
|
- 建议遇到打开比较慢的国外网站,可以优先尝试将该域名添加到dns设置中(注意:被\*\*\*封杀的无效)
|
||||||
|
|
||||||
### 1.2、 请求拦截
|
### 1.2、 请求拦截
|
||||||
|
|
||||||
* 拦截打不开的网站,代理到加速镜像站点上去。
|
- 拦截打不开的网站,代理到加速镜像站点上去。
|
||||||
* 可配置多个镜像站作为备份
|
- 可配置多个镜像站作为备份
|
||||||
* 具备测速机制,当访问失败或超时之后,自动切换到备用站点,使得目标服务高可用
|
- 具备测速机制,当访问失败或超时之后,自动切换到备用站点,使得目标服务高可用
|
||||||
|
|
||||||
### 1.3、 github加速
|
### 1.3、 github加速
|
||||||
|
|
||||||
* github 直连加速 (通过修改sni实现,感谢 [fastGithub](https://github.com/dotnetcore/FastGithub) 提供的思路)
|
- github 直连加速 (通过修改sni实现,感谢 [fastGithub](https://github.com/dotnetcore/FastGithub) 提供的思路)
|
||||||
* release、source、zip下载加速
|
- release、source、zip下载加速
|
||||||
* clone 加速
|
- clone 加速
|
||||||
* 头像加速
|
- 头像加速
|
||||||
* 解决readme中图片引用无法加载的问题
|
- 解决readme中图片引用无法加载的问题
|
||||||
* gist.github.com 加速
|
- gist.github.com 加速
|
||||||
* 解决git push 偶尔失败需要输入账号密码的问题(fatal: TaskCanceledException encountered / fatal: HttpRequestException encountered)
|
- 解决git push 偶尔失败需要输入账号密码的问题(fatal: TaskCanceledException encountered / fatal: HttpRequestException encountered)
|
||||||
* raw/blame加速
|
- raw/blame加速
|
||||||
|
|
||||||
> 以上部分功能通过`X.I.U`的油猴脚本实现, 以下是仓库和脚本下载链接,大家可以去支持一下。
|
> 以上部分功能通过`X.I.U`的油猴脚本实现, 以下是仓库和脚本下载链接,大家可以去支持一下。
|
||||||
>
|
>
|
||||||
> * <https://github.com/XIU2/UserScript>
|
> - <https://github.com/XIU2/UserScript>
|
||||||
> * <https://greasyfork.org/scripts/412245>
|
> - <https://greasyfork.org/scripts/412245>
|
||||||
>
|
>
|
||||||
> 由于此脚本在ds中是打包在本地的,更新会不及时,你可以直接通过浏览器安装油猴插件使用此脚本,从而获得最新更新(ds本地的可以通过`加速服务->基本设置->启用脚本`进行关闭)。
|
> 由于此脚本在ds中是打包在本地的,更新会不及时,你可以直接通过浏览器安装油猴插件使用此脚本,从而获得最新更新(ds本地的可以通过`加速服务->基本设置->启用脚本`进行关闭)。
|
||||||
|
|
||||||
### 1.4、 Stack Overflow 加速
|
### 1.4、 Stack Overflow 加速
|
||||||
|
|
||||||
* 将ajax.google.com代理到加速CDN上
|
- 将ajax.google.com代理到加速CDN上
|
||||||
* recaptcha 图片验证码加速
|
- recaptcha 图片验证码加速
|
||||||
|
|
||||||
### 1.5、 npm加速
|
### 1.5、 npm加速
|
||||||
|
|
||||||
* 支持开启npm代理
|
- 支持开启npm代理
|
||||||
* 官方与淘宝npm registry一键切换,
|
- 官方与淘宝npm registry一键切换,
|
||||||
* 某些npm install的时候,并且使用cnpm也无法安装时,可以尝试开启npm代理再试
|
- 某些npm install的时候,并且使用cnpm也无法安装时,可以尝试开启npm代理再试
|
||||||
|
|
||||||
***安全警告***:
|
**_安全警告_**:
|
||||||
|
|
||||||
* 请勿使用来源不明的服务地址,有隐私和账号泄露风险
|
- 请勿使用来源不明的服务地址,有隐私和账号泄露风险
|
||||||
* 本应用及服务端承诺不收集任何信息。介意者请使用安全模式。
|
- 本应用及服务端承诺不收集任何信息。介意者请使用安全模式。
|
||||||
|
|
||||||
## 二、快速开始
|
## 二、快速开始
|
||||||
|
|
||||||
|
|
@ -88,8 +85,8 @@
|
||||||
|
|
||||||
#### 1)下载安装包
|
#### 1)下载安装包
|
||||||
|
|
||||||
* release下载
|
- release下载
|
||||||
[Github Release](https://github.com/docmirror/dev-sidecar/releases)
|
[Github Release](https://github.com/docmirror/dev-sidecar/releases)
|
||||||
|
|
||||||
> Windows: 请选择DevSidecar-x.x.x.exe
|
> Windows: 请选择DevSidecar-x.x.x.exe
|
||||||
> Mac: 请选择DevSidecar-x.x.x.dmg
|
> Mac: 请选择DevSidecar-x.x.x.dmg
|
||||||
|
|
@ -123,50 +120,52 @@
|
||||||
|
|
||||||
### 2.2、开启前 vs 开启后
|
### 2.2、开启前 vs 开启后
|
||||||
|
|
||||||
| | 开启前 | 开启后 |
|
| | 开启前 | 开启后 |
|
||||||
| ---- | ---- | ---- |
|
| -------- | ------------------------------ | ------------------------------------------------- |
|
||||||
|头像|  | |
|
| 头像 |  |  |
|
||||||
|clone | | |
|
| clone |  |  |
|
||||||
|zip 下载 | |秒下的,实在截不到速度的图 |
|
| zip 下载 |  | 秒下的,实在截不到速度的图 |
|
||||||
|
|
||||||
## 三、模式说明
|
## 三、模式说明
|
||||||
|
|
||||||
### 3.1、安全模式
|
### 3.1、安全模式
|
||||||
|
|
||||||
* 此模式:关闭拦截、关闭增强、开启dns优选、开启测速
|
- 此模式:关闭拦截、关闭增强、开启dns优选、开启测速
|
||||||
* 最安全,无需安装证书,可以在浏览器地址栏左侧查看域名证书
|
- 最安全,无需安装证书,可以在浏览器地址栏左侧查看域名证书
|
||||||
* 功能也最弱,只有特性1,相当于查询github的国外ip,手动改hosts一个意思。
|
- 功能也最弱,只有特性1,相当于查询github的国外ip,手动改hosts一个意思。
|
||||||
* github的可访问性不稳定,取决于IP测速,如果有绿色ip存在,就 `有可能` 可以直连访问。
|
- github的可访问性不稳定,取决于IP测速,如果有绿色ip存在,就 `有可能` 可以直连访问。
|
||||||

|

|
||||||
|
|
||||||
### 3.2、默认模式
|
### 3.2、默认模式
|
||||||
|
|
||||||
* 此模式:开启拦截、关闭增强、开启dns优选、开启测速
|
- 此模式:开启拦截、关闭增强、开启dns优选、开启测速
|
||||||
* 需要安装证书,通过修改sni直连访问github
|
- 需要安装证书,通过修改sni直连访问github
|
||||||
* 功能上包含特性1/2/3/4。
|
- 功能上包含特性1/2/3/4。
|
||||||
|
|
||||||
## 四、 最佳实践
|
## 四、 最佳实践
|
||||||
|
|
||||||
* 把dev-sidecar一直开着就行了(注意windows下开着ds重启电脑,会无法上网,重新打开ds即可。)
|
- 把dev-sidecar一直开着就行了(注意windows下开着ds重启电脑,会无法上网,重新打开ds即可。)
|
||||||
* 建议遇到打开比较慢的国外网站,可以尝试将该域名添加到dns设置中(注意:被***封杀的无效)
|
- 建议遇到打开比较慢的国外网站,可以尝试将该域名添加到dns设置中(注意:被\*\*\*封杀的无效)
|
||||||
|
|
||||||
### 其他加速
|
### 其他加速
|
||||||
|
|
||||||
#### 1)git clone 加速
|
#### 1)git clone 加速
|
||||||
|
|
||||||
方式1:快捷复制:
|
方式1:快捷复制:
|
||||||
> 开启脚本支持,然后在复制clone链接下方,即可复制到加速链接
|
|
||||||
|
|
||||||
方式2:
|
> 开启脚本支持,然后在复制clone链接下方,即可复制到加速链接
|
||||||
> 使用方式用实际的名称替换{}的内容,即可加速clone
|
|
||||||
> <https://hub.fastgit.org/{username}/{reponame}.git>
|
方式2:
|
||||||
> clone 出来的 remote "origin" 为fastgit的地址,需要手动改回来
|
|
||||||
> 你也可以直接使用他们的clone加速工具 [fgit-go](https://github.com/FastGitORG/fgit-go)
|
> 使用方式用实际的名称替换{}的内容,即可加速clone
|
||||||
|
> <https://hub.fastgit.org/{username}/{reponame}.git>
|
||||||
|
> clone 出来的 remote "origin" 为fastgit的地址,需要手动改回来
|
||||||
|
> 你也可以直接使用他们的clone加速工具 [fgit-go](https://github.com/FastGitORG/fgit-go)
|
||||||
|
|
||||||
#### 2)github.com的镜像网站(注意:不能登录)
|
#### 2)github.com的镜像网站(注意:不能登录)
|
||||||
>
|
|
||||||
> 1. [hub.fastgit.org](https://hub.fastgit.org/)
|
> 1. [hub.fastgit.org](https://hub.fastgit.org/)
|
||||||
> 2. [github.com.cnpmjs.org](https://github.com.cnpmjs.org/) 这个很容易超限
|
> 2. [github.com.cnpmjs.org](https://github.com.cnpmjs.org/) 这个很容易超限
|
||||||
|
|
||||||
## 五、api
|
## 五、api
|
||||||
|
|
||||||
|
|
@ -252,16 +251,16 @@ networksetup -setwebproxy 'WiFi' 127.0.0.1 31181
|
||||||
|
|
||||||
如果有上面的错误提示,请尝试如下方法:
|
如果有上面的错误提示,请尝试如下方法:
|
||||||
|
|
||||||
>取消访问偏好设置需要管理员密码
|
> 取消访问偏好设置需要管理员密码
|
||||||
>系统偏好设置—>安全性与隐私—> 通用—> 高级—> 访问系统范围的偏好设置需要输入管理员密码(取消勾选)
|
> 系统偏好设置—>安全性与隐私—> 通用—> 高级—> 访问系统范围的偏好设置需要输入管理员密码(取消勾选)
|
||||||
|
|
||||||
### 6.2、没有加速效果
|
### 6.2、没有加速效果
|
||||||
|
|
||||||
>本应用仅支持https加速,请务必确认你访问的网站地址是https开头的
|
> 本应用仅支持https加速,请务必确认你访问的网站地址是https开头的
|
||||||
|
|
||||||
1. 本应用仅支持https加速
|
1. 本应用仅支持https加速
|
||||||
请务必确认你访问的地址是https开头的
|
请务必确认你访问的地址是https开头的
|
||||||
比如: <https://github.com/>
|
比如: <https://github.com/>
|
||||||
|
|
||||||
2. 检查浏览器是否装了什么插件,与ds有冲突
|
2. 检查浏览器是否装了什么插件,与ds有冲突
|
||||||
|
|
||||||
|
|
@ -269,10 +268,10 @@ networksetup -setwebproxy 'WiFi' 127.0.0.1 31181
|
||||||
|
|
||||||
4. 请确认浏览器的代理设置为使用IE代理/或者使用系统代理状态
|
4. 请确认浏览器的代理设置为使用IE代理/或者使用系统代理状态
|
||||||
|
|
||||||
6. 可以尝试换个浏览器试试
|
5. 可以尝试换个浏览器试试
|
||||||
|
|
||||||
7. 请确认网络代理设置处于勾选状态
|
6. 请确认网络代理设置处于勾选状态
|
||||||
正常情况下ds在“系统代理”开关打开时,会自动设置系统代理。
|
正常情况下ds在“系统代理”开关打开时,会自动设置系统代理。
|
||||||
|
|
||||||
### 6.3、浏览器打开提示证书不受信任
|
### 6.3、浏览器打开提示证书不受信任
|
||||||
|
|
||||||
|
|
@ -293,8 +292,7 @@ networksetup -setwebproxy 'WiFi' 127.0.0.1 31181
|
||||||
### 6.4、打开github显示连接超时
|
### 6.4、打开github显示连接超时
|
||||||
|
|
||||||
```html
|
```html
|
||||||
DevSidecar Warning:
|
DevSidecar Warning: Error: www.github.com:443, 代理请求超时
|
||||||
Error: www.github.com:443, 代理请求超时
|
|
||||||
```
|
```
|
||||||
|
|
||||||
1、检查测速界面github.com是否有ip ,如果没有ip,则可能是由于你的网络提供商封锁了dns服务商的ip(试试能否ping通:1.1.1.1 / 9.9.9.9 )
|
1、检查测速界面github.com是否有ip ,如果没有ip,则可能是由于你的网络提供商封锁了dns服务商的ip(试试能否ping通:1.1.1.1 / 9.9.9.9 )
|
||||||
|
|
@ -303,8 +301,8 @@ Error: www.github.com:443, 代理请求超时
|
||||||
|
|
||||||
### 6.5、查看日志是否有报错
|
### 6.5、查看日志是否有报错
|
||||||
|
|
||||||
如果还是不行,请在下方加作者好友,将服务日志发送给作者进行分析
|
如果还是不行,请在下方加作者好友,将服务日志发送给作者进行分析
|
||||||
日志打开方式:加速服务->右边日志按钮->打开日志文件夹
|
日志打开方式:加速服务->右边日志按钮->打开日志文件夹
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
@ -318,10 +316,10 @@ Error: www.github.com:443, 代理请求超时
|
||||||
应用开启后会自动修改系统代理设置,正常退出会自动关闭系统代理
|
应用开启后会自动修改系统代理设置,正常退出会自动关闭系统代理
|
||||||
当应用意外关闭时,可能会因为没有将系统代理恢复,从而导致完全无法上网。
|
当应用意外关闭时,可能会因为没有将系统代理恢复,从而导致完全无法上网。
|
||||||
|
|
||||||
对于此问题有如下几种解决方案可供选择:
|
对于此问题有如下几种解决方案可供选择:
|
||||||
1、重新打开应用即可(右键应用托盘图标可完全退出,将会正常关闭系统代理设置)
|
1、重新打开应用即可(右键应用托盘图标可完全退出,将会正常关闭系统代理设置)
|
||||||
2、如果应用被卸载了,此时需要[手动关闭系统代理设置](./doc/recover.md)
|
2、如果应用被卸载了,此时需要[手动关闭系统代理设置](./doc/recover.md)
|
||||||
3、如果你是因为开着ds的情况下重启电脑导致无法上网,你可以设置ds为开机自启
|
3、如果你是因为开着ds的情况下重启电脑导致无法上网,你可以设置ds为开机自启
|
||||||
|
|
||||||
### 6.8、卸载应用后上不了网,git请求不了
|
### 6.8、卸载应用后上不了网,git请求不了
|
||||||
|
|
||||||
|
|
@ -345,7 +343,7 @@ npm config delete https-proxy
|
||||||
|
|
||||||
## 七、在其他程序使用
|
## 七、在其他程序使用
|
||||||
|
|
||||||
* [java程序使用](./doc/other.md#Java程序使用)
|
- [java程序使用](./doc/other.md#Java程序使用)
|
||||||
|
|
||||||
## 八、贡献代码
|
## 八、贡献代码
|
||||||
|
|
||||||
|
|
@ -358,6 +356,7 @@ npm config delete https-proxy
|
||||||
#### 2)安装 `lerna`
|
#### 2)安装 `lerna`
|
||||||
|
|
||||||
运行如下命令即可安装所需依赖:
|
运行如下命令即可安装所需依赖:
|
||||||
|
|
||||||
> 注:lerna指定为6.x版本,更高版本会导致打包失败(不兼容导致)
|
> 注:lerna指定为6.x版本,更高版本会导致打包失败(不兼容导致)
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
@ -407,19 +406,20 @@ npm run electron:build
|
||||||
欢迎bug反馈,需求建议,技术交流等
|
欢迎bug反馈,需求建议,技术交流等
|
||||||
|
|
||||||
1、 加群(请备注dev-sidecar,或简称DS)
|
1、 加群(请备注dev-sidecar,或简称DS)
|
||||||
* QQ 1群:390691483,人数:500 / 500(满)
|
|
||||||
* QQ 2群:[667666069](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=n4nksr4sji93vZtD5e8YEHRT6qbh6VyQ&authKey=XKBZnzmoiJrAFyOT4V%2BCrgX5c13ds59b84g%2FVRhXAIQd%2FlAiilsuwDRGWJct%2B570&noverify=0&group_code=667666069),人数:447 / 500
|
- QQ 1群:390691483,人数:500 / 500(满)
|
||||||
* QQ 3群:419807815,人数:500 / 500(满)
|
- QQ 2群:[667666069](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=n4nksr4sji93vZtD5e8YEHRT6qbh6VyQ&authKey=XKBZnzmoiJrAFyOT4V%2BCrgX5c13ds59b84g%2FVRhXAIQd%2FlAiilsuwDRGWJct%2B570&noverify=0&group_code=667666069),人数:447 / 500
|
||||||
* QQ 4群:[438148299](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=i_NCBB5f_Bkm2JsEV1tLs2TkQ79UlCID&authKey=nMsVJbJ6P%2FGNO7Q6vsVUadXRKnULUURwR8zvUZJnP3IgzhHYPhYdcBCHvoOh8vYr&noverify=0&group_code=438148299),人数:203 / 1000
|
- QQ 3群:419807815,人数:500 / 500(满)
|
||||||
* QQ 5群:[767622917](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=nAWi_Rxj7mM4Unp5LMiatmUWhGimtbcB&authKey=aswmlWGjbt3GIWXtvjB2GJqqAKuv7hWjk6UBs3MTb%2Biyvr%2Fsbb1kA9CjF6sK7Hgg&noverify=0&group_code=767622917),人数:016 / 200(new)
|
- QQ 4群:[438148299](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=i_NCBB5f_Bkm2JsEV1tLs2TkQ79UlCID&authKey=nMsVJbJ6P%2FGNO7Q6vsVUadXRKnULUURwR8zvUZJnP3IgzhHYPhYdcBCHvoOh8vYr&noverify=0&group_code=438148299),人数:203 / 1000
|
||||||
|
- QQ 5群:[767622917](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=nAWi_Rxj7mM4Unp5LMiatmUWhGimtbcB&authKey=aswmlWGjbt3GIWXtvjB2GJqqAKuv7hWjk6UBs3MTb%2Biyvr%2Fsbb1kA9CjF6sK7Hgg&noverify=0&group_code=767622917),人数:016 / 200(new)
|
||||||
|
|
||||||
## 十、求star
|
## 十、求star
|
||||||
|
|
||||||
我的其他项目求star
|
我的其他项目求star
|
||||||
|
|
||||||
* [fast-crud](https://github.com/fast-crud/fast-crud) : 开发crud快如闪电
|
- [fast-crud](https://github.com/fast-crud/fast-crud) : 开发crud快如闪电
|
||||||
* [certd](https://github.com/certd/certd) : 让你的证书永不过期
|
- [certd](https://github.com/certd/certd) : 让你的证书永不过期
|
||||||
* [trident-sync](https://github.com/handsfree-work/trident-sync) : 二次开发项目同步升级工具
|
- [trident-sync](https://github.com/handsfree-work/trident-sync) : 二次开发项目同步升级工具
|
||||||
|
|
||||||
## 十一、感谢
|
## 十一、感谢
|
||||||
|
|
||||||
|
|
@ -429,14 +429,14 @@ npm run electron:build
|
||||||
|
|
||||||
本项目参考如下开源项目
|
本项目参考如下开源项目
|
||||||
|
|
||||||
* [node-mitmproxy](https://github.com/wuchangming/node-mitmproxy)
|
- [node-mitmproxy](https://github.com/wuchangming/node-mitmproxy)
|
||||||
* [ReplaceGoogleCDN](https://github.com/justjavac/ReplaceGoogleCDN)
|
- [ReplaceGoogleCDN](https://github.com/justjavac/ReplaceGoogleCDN)
|
||||||
|
|
||||||
特别感谢
|
特别感谢
|
||||||
|
|
||||||
* [github增强油猴脚本](https://greasyfork.org/zh-CN/scripts/412245-github-%E5%A2%9E%E5%BC%BA-%E9%AB%98%E9%80%9F%E4%B8%8B%E8%BD%BD) 本项目部分加速功能完全复制该脚本。
|
- [github增强油猴脚本](https://greasyfork.org/zh-CN/scripts/412245-github-%E5%A2%9E%E5%BC%BA-%E9%AB%98%E9%80%9F%E4%B8%8B%E8%BD%BD) 本项目部分加速功能完全复制该脚本。
|
||||||
* [中国域名白名单](https://github.com/pluwen/china-domain-allowlist),本项目的系统代理排除域名功能中,使用了该白名单。
|
- [中国域名白名单](https://github.com/pluwen/china-domain-allowlist),本项目的系统代理排除域名功能中,使用了该白名单。
|
||||||
|
|
||||||
本项目部分加速资源由如下组织提供
|
本项目部分加速资源由如下组织提供
|
||||||
|
|
||||||
* [FastGit UK](https://fastgit.org/)
|
- [FastGit UK](https://fastgit.org/)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
## 一、为什么要信任根证书。
|
## 一、为什么要信任根证书。
|
||||||
|
|
||||||
要回答这个问题需要先掌握下面两个知识点
|
要回答这个问题需要先掌握下面两个知识点
|
||||||
|
|
||||||
### 知识点1:什么是根证书
|
### 知识点1:什么是根证书
|
||||||
|
|
||||||
[百度百科-什么是根证书](https://baike.baidu.com/item/%E6%A0%B9%E8%AF%81%E4%B9%A6/9874620?fr=aladdin)
|
[百度百科-什么是根证书](https://baike.baidu.com/item/%E6%A0%B9%E8%AF%81%E4%B9%A6/9874620?fr=aladdin)
|
||||||
|
|
||||||
当访问目标网站是https协议时,服务器会发送一个由根证书签发的网站ssl证书给浏览器,让浏览器用这个ssl证书给数据加密。
|
当访问目标网站是https协议时,服务器会发送一个由根证书签发的网站ssl证书给浏览器,让浏览器用这个ssl证书给数据加密。
|
||||||
|
|
@ -14,6 +16,7 @@
|
||||||
windows、mac、linux或者浏览器他们都内置了市面上可信的大型证书颁发机构的根证书。
|
windows、mac、linux或者浏览器他们都内置了市面上可信的大型证书颁发机构的根证书。
|
||||||
|
|
||||||
### 知识点2:中间人攻击
|
### 知识点2:中间人攻击
|
||||||
|
|
||||||
本应用的实现原理如下图:
|
本应用的实现原理如下图:
|
||||||
|
|
||||||

|

|
||||||
|
|
@ -29,7 +32,7 @@ windows、mac、linux或者浏览器他们都内置了市面上可信的大型
|
||||||
|
|
||||||
例如加速github就需要修改如下几处
|
例如加速github就需要修改如下几处
|
||||||
|
|
||||||
1. 直连访问github需要修改tls握手时的sni域名,规避***的sni阻断问题。
|
1. 直连访问github需要修改tls握手时的sni域名,规避\*\*\*的sni阻断问题。
|
||||||
2. asserts.github.com等静态资源拦截替换成fastgit.org的镜像地址
|
2. asserts.github.com等静态资源拦截替换成fastgit.org的镜像地址
|
||||||
|
|
||||||
DevSidecar在第一次启动时会在本地随机生成一份根证书,当有用户访问github时,就用这份根证书来签发一份假的叫github.com的证书。
|
DevSidecar在第一次启动时会在本地随机生成一份根证书,当有用户访问github时,就用这份根证书来签发一份假的叫github.com的证书。
|
||||||
|
|
@ -50,7 +53,7 @@ DevSidecar在第一次启动时会在本地随机生成一份根证书,当有
|
||||||
> 或者从源码自行编译安装
|
> 或者从源码自行编译安装
|
||||||
|
|
||||||
> 对于拦截配置里的替代网站风险:
|
> 对于拦截配置里的替代网站风险:
|
||||||
|
>
|
||||||
> 1. 尽量缩小替代配置的范围
|
> 1. 尽量缩小替代配置的范围
|
||||||
> 2. 不使用来源不明的镜像地址,尽量使用知名度较高的镜像地址
|
> 2. 不使用来源不明的镜像地址,尽量使用知名度较高的镜像地址
|
||||||
> 3. 你甚至可以将其他拦截配置全部删除,只保留github相关配置
|
> 3. 你甚至可以将其他拦截配置全部删除,只保留github相关配置
|
||||||
>
|
|
||||||
|
|
|
||||||
35
doc/linux.md
35
doc/linux.md
|
|
@ -1,4 +1,5 @@
|
||||||
# linux 支持
|
# linux 支持
|
||||||
|
|
||||||
`linux`使用说明,目前仅支持`ubuntu_x64(GNOME)`,其他`linux`未测试
|
`linux`使用说明,目前仅支持`ubuntu_x64(GNOME)`,其他`linux`未测试
|
||||||
|
|
||||||
> 注意:需要开启[sudo免密支持](https://www.jianshu.com/p/5d02428f313d)
|
> 注意:需要开启[sudo免密支持](https://www.jianshu.com/p/5d02428f313d)
|
||||||
|
|
@ -6,30 +7,38 @@
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
### 1. ubuntu
|
### 1. ubuntu
|
||||||
* 下载`DevSidecar-x.x.x.deb`
|
|
||||||
* 执行命令安装 `dpkg -i DevSidecar-x.x.x.deb`
|
- 下载`DevSidecar-x.x.x.deb`
|
||||||
* 去应用列表里面找到dev-sidecar应用,打开即可
|
- 执行命令安装 `dpkg -i DevSidecar-x.x.x.deb`
|
||||||
|
- 去应用列表里面找到dev-sidecar应用,打开即可
|
||||||
|
|
||||||
### 2. 其他linux系统(未测试)
|
### 2. 其他linux系统(未测试)
|
||||||
* 下载 `DevSidecar-x.x.x.AppImage`
|
|
||||||
* 设置可执行权限 `sudo chmod +X DevSidecar-x.x.x.AppImage`
|
- 下载 `DevSidecar-x.x.x.AppImage`
|
||||||
* 双击运行
|
- 设置可执行权限 `sudo chmod +X DevSidecar-x.x.x.AppImage`
|
||||||
|
- 双击运行
|
||||||
|
|
||||||
## 证书安装
|
## 证书安装
|
||||||
|
|
||||||
默认模式和增强模式需要系统信任CA证书。
|
默认模式和增强模式需要系统信任CA证书。
|
||||||
由于linux上火狐和chrome都不走系统证书,所以除了安装系统证书之外,还需要给浏览器安装证书
|
由于linux上火狐和chrome都不走系统证书,所以除了安装系统证书之外,还需要给浏览器安装证书
|
||||||
|
|
||||||
### 1. 系统证书安装
|
### 1. 系统证书安装
|
||||||
|
|
||||||
根据弹出的提示:
|
根据弹出的提示:
|
||||||
* 点击首页右上角“安装根证书”按钮
|
|
||||||
* 点击“点此去安装”
|
- 点击首页右上角“安装根证书”按钮
|
||||||
* 提示安装成功即可
|
- 点击“点此去安装”
|
||||||
|
- 提示安装成功即可
|
||||||
|
|
||||||
### 2. 火狐浏览器安装证书
|
### 2. 火狐浏览器安装证书
|
||||||
* 火狐浏览器->选项->隐私与安全->证书->查看证书
|
|
||||||
* 证书颁发机构->导入
|
- 火狐浏览器->选项->隐私与安全->证书->查看证书
|
||||||
* 选择证书文件在`~/.dev-sidecar`目录下
|
- 证书颁发机构->导入
|
||||||
* 勾选信任由此证书颁发机构来标识网站,确定即可
|
- 选择证书文件在`~/.dev-sidecar`目录下
|
||||||
|
- 勾选信任由此证书颁发机构来标识网站,确定即可
|
||||||
|
|
||||||
### 3. chrome浏览器安装证书
|
### 3. chrome浏览器安装证书
|
||||||
|
|
||||||
证书文件目录为`~/.dev-sidecar`
|
证书文件目录为`~/.dev-sidecar`
|
||||||

|

|
||||||
|
|
|
||||||
14
doc/other.md
14
doc/other.md
|
|
@ -1,13 +1,15 @@
|
||||||
# 其他程序使用
|
# 其他程序使用
|
||||||
|
|
||||||
## Java程序使用
|
## Java程序使用
|
||||||
> 由[Enaium](https://github.com/Enaium) 提供,未做验证,可供参考
|
|
||||||
|
> 由[Enaium](https://github.com/Enaium) 提供,未做验证,可供参考
|
||||||
>
|
>
|
||||||
需要先通过keytool安装证书
|
> 需要先通过keytool安装证书
|
||||||
`keytool -import -alias dev-sidecar -keystore "jdk路径\security\cacerts" -file 用户目录\.dev-sidecar\dev-sidecar.ca.crt`默认密码为`changeit`
|
> `keytool -import -alias dev-sidecar -keystore "jdk路径\security\cacerts" -file 用户目录\.dev-sidecar\dev-sidecar.ca.crt`默认密码为`changeit`
|
||||||
启动时还需要设置参数
|
> 启动时还需要设置参数
|
||||||
`-Dhttp.proxyHost=localhost -Dhttp.proxyPort=31181 -Dhttps.proxyHost=localhost -Dhttps.proxyPort=31181`
|
> `-Dhttp.proxyHost=localhost -Dhttp.proxyPort=31181 -Dhttps.proxyHost=localhost -Dhttps.proxyPort=31181`
|
||||||
Gradle还需在`用户目录/.gradle/gradle.properties`创建配置文件
|
> Gradle还需在`用户目录/.gradle/gradle.properties`创建配置文件
|
||||||
|
|
||||||
```properties
|
```properties
|
||||||
systemProp.http.proxyHost=localhost
|
systemProp.http.proxyHost=localhost
|
||||||
systemProp.http.proxyPort=31181
|
systemProp.http.proxyPort=31181
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,26 @@
|
||||||
# 卸载与恢复网络
|
# 卸载与恢复网络
|
||||||
|
|
||||||
由于应用启动后会自动设置系统代理,正常退出时会关闭系统代理。
|
由于应用启动后会自动设置系统代理,正常退出时会关闭系统代理。
|
||||||
当应用意外关闭,或者未正常退出后被卸载,此时会因为系统代理没有恢复从而导致完全上不了网。
|
当应用意外关闭,或者未正常退出后被卸载,此时会因为系统代理没有恢复从而导致完全上不了网。
|
||||||
目前electron在windows系统上无法监听系统重启事件。更多相关资料 [electron issues](https://github.com/electron/electron/pull/24261)
|
目前electron在windows系统上无法监听系统重启事件。更多相关资料 [electron issues](https://github.com/electron/electron/pull/24261)
|
||||||
|
|
||||||
## 恢复代理设置
|
## 恢复代理设置
|
||||||
|
|
||||||
### 1、windows 代理关闭
|
### 1、windows 代理关闭
|
||||||
|
|
||||||
如何打开查看windows代理设置:
|
如何打开查看windows代理设置:
|
||||||
* win10: 开始->设置->网络和Internet->最下方代理
|
|
||||||
* win7: 开始->控制面板->网络和Internet->网络和共享中心->左下角Internet选项->连接选项卡->局域网设置
|
- win10: 开始->设置->网络和Internet->最下方代理
|
||||||
|
- win7: 开始->控制面板->网络和Internet->网络和共享中心->左下角Internet选项->连接选项卡->局域网设置
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 2、mac 代理关闭
|
### 2、mac 代理关闭
|
||||||
|
|
||||||
网络->网卡->代理->去掉http和https的两个勾
|
网络->网卡->代理->去掉http和https的两个勾
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 3、Linux(Ubuntu)
|
### 3、Linux(Ubuntu)
|
||||||
|
|
||||||
网络->代理->选择禁用
|
网络->代理->选择禁用
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,20 @@ export default antfu({
|
||||||
vueVersion: 2,
|
vueVersion: 2,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
"style/space-before-function-paren": ["error", "always"],
|
'style/space-before-function-paren': ['error', 'always'],
|
||||||
"no-console": 'off'
|
'node/prefer-global/buffer': 'off',
|
||||||
|
'node/prefer-global/process': 'off',
|
||||||
|
'no-console': 'off',
|
||||||
},
|
},
|
||||||
isInEditor: true,
|
|
||||||
ignore: [
|
ignore: [
|
||||||
'**/test/**',
|
'**/node_modules/*',
|
||||||
|
'**/build/*',
|
||||||
|
'**/test/*',
|
||||||
|
'**/dist_electron/*',
|
||||||
],
|
],
|
||||||
formatters: {
|
formatters: {
|
||||||
css: true,
|
css: true,
|
||||||
html: true,
|
html: true,
|
||||||
markdown: 'prettier',
|
markdown: 'prettier',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
12
package.json
12
package.json
|
|
@ -1,17 +1,17 @@
|
||||||
{
|
{
|
||||||
"name": "dev-sidecar-parent",
|
"name": "dev-sidecar-parent",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@9.13.2",
|
|
||||||
"private": false,
|
"private": false,
|
||||||
|
"packageManager": "pnpm@9.13.2",
|
||||||
"author": "Greper",
|
"author": "Greper",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^9.15.0",
|
|
||||||
"@antfu/eslint-config": "^3.9.1",
|
|
||||||
"eslint-plugin-format": "^0.1.2"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"lint:fix": "eslint . --fix"
|
"lint:fix": "eslint . --fix"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@antfu/eslint-config": "^3.9.1",
|
||||||
|
"eslint": "^9.15.0",
|
||||||
|
"eslint-plugin-format": "^0.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
"google加速",
|
"google加速",
|
||||||
"代理"
|
"代理"
|
||||||
],
|
],
|
||||||
"bin": "./cli.js",
|
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
|
"bin": "./cli.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./src"
|
"start": "node ./src"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
|
||||||
const DevSidecar = require('@docmirror/dev-sidecar')
|
const DevSidecar = require('@docmirror/dev-sidecar')
|
||||||
|
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
||||||
|
|
||||||
// 启动服务
|
// 启动服务
|
||||||
const mitmproxyPath = './src/mitmproxy'
|
const mitmproxyPath = './src/mitmproxy'
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const server = require('@docmirror/mitmproxy')
|
const server = require('@docmirror/mitmproxy')
|
||||||
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
||||||
const log = require('../src/utils/util.log')
|
const log = require('../src/utils/util.log')
|
||||||
|
|
@ -9,7 +9,8 @@ const home = process.env.USER_HOME || process.env.HOME || 'C:/Users/Administrato
|
||||||
let configPath
|
let configPath
|
||||||
if (process.argv && process.argv.length > 3) {
|
if (process.argv && process.argv.length > 3) {
|
||||||
configPath = process.argv[2]
|
configPath = process.argv[2]
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
configPath = path.join(home, '.dev-sidecar/running.json')
|
configPath = path.join(home, '.dev-sidecar/running.json')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
"test": "mocha"
|
"test": "mocha"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"spawn-sync": "^2.0.0",
|
|
||||||
"fix-path": "^3.0.0",
|
"fix-path": "^3.0.0",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"log4js": "^6.9.1",
|
"log4js": "^6.9.1",
|
||||||
"node-powershell": "^4.0.0",
|
"node-powershell": "^4.0.0",
|
||||||
|
"spawn-sync": "^2.0.0",
|
||||||
"winreg": "^1.2.5"
|
"winreg": "^1.2.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
||||||
const lodash = require('lodash')
|
const lodash = require('lodash')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
|
|
@ -30,7 +30,8 @@ function _getConfigPath () {
|
||||||
const dir = getDefaultConfigBasePath()
|
const dir = getDefaultConfigBasePath()
|
||||||
if (!fs.existsSync(dir)) {
|
if (!fs.existsSync(dir)) {
|
||||||
fs.mkdirSync(dir)
|
fs.mkdirSync(dir)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 兼容1.7.3及以下版本的配置文件处理逻辑
|
// 兼容1.7.3及以下版本的配置文件处理逻辑
|
||||||
const newFilePath = path.join(dir, '/config.json')
|
const newFilePath = path.join(dir, '/config.json')
|
||||||
const oldFilePath = path.join(dir, '/config.json5')
|
const oldFilePath = path.join(dir, '/config.json5')
|
||||||
|
|
@ -52,7 +53,8 @@ const configApi = {
|
||||||
try {
|
try {
|
||||||
await configApi.downloadRemoteConfig()
|
await configApi.downloadRemoteConfig()
|
||||||
configApi.reload()
|
configApi.reload()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('定时下载远程配置并重载配置失败', e)
|
log.error('定时下载远程配置并重载配置失败', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +104,8 @@ const configApi = {
|
||||||
log.warn('下载远程配置成功,但内容为空:', remoteConfigUrl)
|
log.warn('下载远程配置成功,但内容为空:', remoteConfigUrl)
|
||||||
resolve()
|
resolve()
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('下载远程配置成功:', remoteConfigUrl)
|
log.info('下载远程配置成功:', remoteConfigUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +113,8 @@ const configApi = {
|
||||||
let remoteConfig
|
let remoteConfig
|
||||||
try {
|
try {
|
||||||
remoteConfig = jsonApi.parse(body)
|
remoteConfig = jsonApi.parse(body)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error(`远程配置内容格式不正确, url: ${remoteConfigUrl}, body: ${body}`)
|
log.error(`远程配置内容格式不正确, url: ${remoteConfigUrl}, body: ${body}`)
|
||||||
remoteConfig = null
|
remoteConfig = null
|
||||||
}
|
}
|
||||||
|
|
@ -119,18 +123,21 @@ const configApi = {
|
||||||
const remoteSavePath = _getRemoteSavePath(suffix)
|
const remoteSavePath = _getRemoteSavePath(suffix)
|
||||||
fs.writeFileSync(remoteSavePath, body)
|
fs.writeFileSync(remoteSavePath, body)
|
||||||
log.info('保存远程配置文件成功:', remoteSavePath)
|
log.info('保存远程配置文件成功:', remoteSavePath)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.warn('远程配置对象为空:', remoteConfigUrl)
|
log.warn('远程配置对象为空:', remoteConfigUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve()
|
resolve()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.error(`下载远程配置失败: ${remoteConfigUrl}, response:`, response, ', body:', body)
|
log.error(`下载远程配置失败: ${remoteConfigUrl}, response:`, response, ', body:', body)
|
||||||
|
|
||||||
let message
|
let message
|
||||||
if (response) {
|
if (response) {
|
||||||
message = `下载远程配置失败: ${remoteConfigUrl}, message: ${response.message}, code: ${response.statusCode}`
|
message = `下载远程配置失败: ${remoteConfigUrl}, message: ${response.message}, code: ${response.statusCode}`
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
message = `下载远程配置失败: response: ${response}`
|
message = `下载远程配置失败: response: ${response}`
|
||||||
}
|
}
|
||||||
reject(new Error(message))
|
reject(new Error(message))
|
||||||
|
|
@ -154,7 +161,8 @@ const configApi = {
|
||||||
if (!get().app.remoteConfig.personalUrl) {
|
if (!get().app.remoteConfig.personalUrl) {
|
||||||
return '{}'
|
return '{}'
|
||||||
}
|
}
|
||||||
} else if (suffix === '') {
|
}
|
||||||
|
else if (suffix === '') {
|
||||||
if (!get().app.remoteConfig.url) {
|
if (!get().app.remoteConfig.url) {
|
||||||
return '{}'
|
return '{}'
|
||||||
}
|
}
|
||||||
|
|
@ -167,10 +175,12 @@ const configApi = {
|
||||||
const file = fs.readFileSync(path)
|
const file = fs.readFileSync(path)
|
||||||
log.info('读取远程配置文件内容成功:', path)
|
log.info('读取远程配置文件内容成功:', path)
|
||||||
return file.toString()
|
return file.toString()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.warn('远程配置文件不存在:', path)
|
log.warn('远程配置文件不存在:', path)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('读取远程配置文件内容失败:', e)
|
log.error('读取远程配置文件内容失败:', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,7 +230,8 @@ const configApi = {
|
||||||
if (!fs.existsSync(configPath)) {
|
if (!fs.existsSync(configPath)) {
|
||||||
userConfig = {}
|
userConfig = {}
|
||||||
log.info('config.json 文件不存在:', configPath)
|
log.info('config.json 文件不存在:', configPath)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const file = fs.readFileSync(configPath)
|
const file = fs.readFileSync(configPath)
|
||||||
log.info('读取 config.json 成功:', configPath)
|
log.info('读取 config.json 成功:', configPath)
|
||||||
const fileStr = file.toString()
|
const fileStr = file.toString()
|
||||||
|
|
@ -265,7 +276,8 @@ const configApi = {
|
||||||
if (get().app.remoteConfig.personalUrl) {
|
if (get().app.remoteConfig.personalUrl) {
|
||||||
mergeApi.doMerge(merged, personalRemoteConfig) // 再合并一次个人远程配置,使配置生效
|
mergeApi.doMerge(merged, personalRemoteConfig) // 再合并一次个人远程配置,使配置生效
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
mergeApi.doMerge(merged, defConfig) // 合并默认配置
|
mergeApi.doMerge(merged, defConfig) // 合并默认配置
|
||||||
}
|
}
|
||||||
if (newConfig != null) {
|
if (newConfig != null) {
|
||||||
|
|
@ -306,7 +318,8 @@ const configApi = {
|
||||||
configApi.load(null)
|
configApi.load(null)
|
||||||
|
|
||||||
return true // 删除并重新加载配置成功
|
return true // 删除并重新加载配置成功
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false // config.json 文件不存在
|
return false // config.json 文件不存在
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -315,7 +328,8 @@ const configApi = {
|
||||||
let value = lodash.get(defConfig, key)
|
let value = lodash.get(defConfig, key)
|
||||||
value = lodash.cloneDeep(value)
|
value = lodash.cloneDeep(value)
|
||||||
lodash.set(configTarget, key, value)
|
lodash.set(configTarget, key, value)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
configTarget = lodash.cloneDeep(defConfig)
|
configTarget = lodash.cloneDeep(defConfig)
|
||||||
}
|
}
|
||||||
return configTarget
|
return configTarget
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
|
|
||||||
function getUserBasePath () {
|
function getUserBasePath () {
|
||||||
const userHome = process.env.USERPROFILE || process.env.HOME || '/'
|
const userHome = process.env.USERPROFILE || process.env.HOME || '/'
|
||||||
|
|
|
||||||
|
|
@ -1,226 +1,226 @@
|
||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"compatible": {
|
"compatible": {
|
||||||
"connect": {
|
"connect": {
|
||||||
"218.18.106.132:443": {
|
"218.18.106.132:443": {
|
||||||
"ssl": true
|
"ssl": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request": {
|
"request": {
|
||||||
"218.18.106.132:443": {
|
"218.18.106.132:443": {
|
||||||
"rejectUnauthorized": false
|
"rejectUnauthorized": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"intercepts": {
|
"intercepts": {
|
||||||
"github.com": {
|
"github.com": {
|
||||||
"^(/[\\w-.]+){2,}/?(\\?.*)?$": {
|
"^(/[\\w-.]+){2,}/?(\\?.*)?$": {
|
||||||
"tampermonkeyScript": "https://gitee.com/wangliang181230/dev-sidecar/raw/scripts/tampermonkey.js",
|
"tampermonkeyScript": "https://gitee.com/wangliang181230/dev-sidecar/raw/scripts/tampermonkey.js",
|
||||||
"script": "https://gitee.com/wangliang181230/dev-sidecar/raw/scripts/GithubEnhanced-High-Speed-Download.user.js"
|
"script": "https://gitee.com/wangliang181230/dev-sidecar/raw/scripts/GithubEnhanced-High-Speed-Download.user.js"
|
||||||
},
|
},
|
||||||
"^(/[^/]+){2}/releases/download/.*$": {
|
"^(/[^/]+){2}/releases/download/.*$": {
|
||||||
"redirect": "ghp.ci/https://github.com",
|
"redirect": "ghp.ci/https://github.com",
|
||||||
"desc": "release文件加速下载重定向地址"
|
"desc": "release文件加速下载重定向地址"
|
||||||
},
|
},
|
||||||
"^(/[^/]+){2}/archive/.*\\.(zip|tar.gz)$": {
|
"^(/[^/]+){2}/archive/.*\\.(zip|tar.gz)$": {
|
||||||
"redirect": "ghp.ci/https://github.com",
|
"redirect": "ghp.ci/https://github.com",
|
||||||
"desc": "release源代码加速下载重定向地址"
|
"desc": "release源代码加速下载重定向地址"
|
||||||
},
|
},
|
||||||
"^((/[^/]+){2,})/raw((/[^/]+)+\\.(jpg|jpeg|png|gif))(\\?.*)?$": {
|
"^((/[^/]+){2,})/raw((/[^/]+)+\\.(jpg|jpeg|png|gif))(\\?.*)?$": {
|
||||||
"sni": "baidu.com" // proxy拦截器不会使用 .* 中的sni配置,故补充此配置
|
"sni": "baidu.com" // proxy拦截器不会使用 .* 中的sni配置,故补充此配置
|
||||||
},
|
},
|
||||||
"^((/[^/]+){2,})/raw((/[^/]+)+\\.js)(\\?.*)?$": {
|
"^((/[^/]+){2,})/raw((/[^/]+)+\\.js)(\\?.*)?$": {
|
||||||
"sni": "baidu.com" // proxy拦截器不会使用 .* 中的sni配置,故补充此配置
|
"sni": "baidu.com" // proxy拦截器不会使用 .* 中的sni配置,故补充此配置
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"api.github.com": {
|
"api.github.com": {
|
||||||
".*": {
|
".*": {
|
||||||
"sni": "baidu.com"
|
"sni": "baidu.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"github.githubassets.com": {
|
"github.githubassets.com": {
|
||||||
".*": {
|
".*": {
|
||||||
"sni": "baidu.com"
|
"sni": "baidu.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"avatars.githubusercontent.com": {
|
"avatars.githubusercontent.com": {
|
||||||
".*": {
|
".*": {
|
||||||
"sni": "baidu.com"
|
"sni": "baidu.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"camo.githubusercontent.com": {
|
"camo.githubusercontent.com": {
|
||||||
".*": {
|
".*": {
|
||||||
"sni": "baidu.com"
|
"sni": "baidu.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"collector.github.com": {
|
"collector.github.com": {
|
||||||
".*": {
|
".*": {
|
||||||
"sni": "baidu.com"
|
"sni": "baidu.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"www.gstatic.com": {
|
"www.gstatic.com": {
|
||||||
"/recaptcha/.*": {
|
"/recaptcha/.*": {
|
||||||
"proxy": "www.recaptcha.net"
|
"proxy": "www.recaptcha.net"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"preSetIpList": {
|
"preSetIpList": {
|
||||||
"github.com": [
|
"github.com": [
|
||||||
"4.237.22.38",
|
"4.237.22.38",
|
||||||
"20.26.156.215",
|
"20.26.156.215",
|
||||||
"20.27.177.113",
|
"20.27.177.113",
|
||||||
"20.87.245.0",
|
"20.87.245.0",
|
||||||
"20.200.245.247",
|
"20.200.245.247",
|
||||||
"20.201.28.151",
|
"20.201.28.151",
|
||||||
"20.205.243.166",
|
"20.205.243.166",
|
||||||
"140.82.113.3",
|
"140.82.113.3",
|
||||||
"140.82.114.4",
|
"140.82.114.4",
|
||||||
"140.82.116.3",
|
"140.82.116.3",
|
||||||
"140.82.116.4",
|
"140.82.116.4",
|
||||||
"140.82.121.3",
|
"140.82.121.3",
|
||||||
"140.82.121.4"
|
"140.82.121.4"
|
||||||
],
|
],
|
||||||
"hub.docker.com": null // 1.8.2版本中,该域名的预设IP有问题,现在远程配置中删除
|
"hub.docker.com": null // 1.8.2版本中,该域名的预设IP有问题,现在远程配置中删除
|
||||||
},
|
},
|
||||||
"dns": {
|
"dns": {
|
||||||
"mapping": {
|
"mapping": {
|
||||||
"*.jetbrains.com": "quad9",
|
"*.jetbrains.com": "quad9",
|
||||||
"*.azureedge.net": "quad9",
|
"*.azureedge.net": "quad9",
|
||||||
"*.stackoverflow.com": "quad9"
|
"*.stackoverflow.com": "quad9"
|
||||||
},
|
},
|
||||||
"speedTest": {
|
"speedTest": {
|
||||||
"interval": 300000
|
"interval": 300000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"whiteList": {
|
"whiteList": {
|
||||||
"*.icloud.com": true,
|
"*.icloud.com": true,
|
||||||
"*.lenovo.net": true
|
"*.lenovo.net": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"proxy": {
|
"proxy": {
|
||||||
"remoteDomesticDomainAllowListFileUrl": "https://raw.kkgithub.com/pluwen/china-domain-allowlist/main/allow-list.sorl",
|
"remoteDomesticDomainAllowListFileUrl": "https://raw.kkgithub.com/pluwen/china-domain-allowlist/main/allow-list.sorl",
|
||||||
"excludeIpList": {
|
"excludeIpList": {
|
||||||
// Github文件上传所使用的域名,被DS代理会导致文件上传经常失败,从系统代理中排除掉
|
// Github文件上传所使用的域名,被DS代理会导致文件上传经常失败,从系统代理中排除掉
|
||||||
"objects-origin.githubusercontent.com": true,
|
"objects-origin.githubusercontent.com": true,
|
||||||
// Github通过Actions上传的文件,下载时所需的域名,从系统代理中排除掉,否则下载会失败
|
// Github通过Actions上传的文件,下载时所需的域名,从系统代理中排除掉,否则下载会失败
|
||||||
"*.windows.net": true,
|
"*.windows.net": true,
|
||||||
// Github下载release文件的高速镜像地址
|
// Github下载release文件的高速镜像地址
|
||||||
"*.ghproxy.net": true,
|
"*.ghproxy.net": true,
|
||||||
"*.ghp.ci": true,
|
"*.ghp.ci": true,
|
||||||
"*.kkgithub.com": true,
|
"*.kkgithub.com": true,
|
||||||
|
|
||||||
// Github建站域名
|
// Github建站域名
|
||||||
"*.github.io": true,
|
"*.github.io": true,
|
||||||
|
|
||||||
// bilibili相关
|
// bilibili相关
|
||||||
"*.bilicomic.com": true,
|
"*.bilicomic.com": true,
|
||||||
|
|
||||||
// 中国移动云盘登录API
|
// 中国移动云盘登录API
|
||||||
"[2049:8c54:813:10c::140]": true,
|
"[2049:8c54:813:10c::140]": true,
|
||||||
"[2409:8a0c:a442:ff40:a51f:4b9c:8b41:25ea]": true,
|
"[2409:8a0c:a442:ff40:a51f:4b9c:8b41:25ea]": true,
|
||||||
"[2606:2800:147:120f:30c:1ba0:fc6:265a]": true,
|
"[2606:2800:147:120f:30c:1ba0:fc6:265a]": true,
|
||||||
// 移动云盘相关
|
// 移动云盘相关
|
||||||
"*.cmicapm.com": true,
|
"*.cmicapm.com": true,
|
||||||
|
|
||||||
// cloudflare:排除以下域名,cloudflare的人机校验会更快,成功率更高。
|
// cloudflare:排除以下域名,cloudflare的人机校验会更快,成功率更高。
|
||||||
"*.cloudflare.com": true,
|
"*.cloudflare.com": true,
|
||||||
"*.cloudflare-cn.com": true,
|
"*.cloudflare-cn.com": true,
|
||||||
|
|
||||||
// VS相关
|
// VS相关
|
||||||
"*.microsoftonline.com": true, // 此域名不排除的话,部分功能将出现异常
|
"*.microsoftonline.com": true, // 此域名不排除的话,部分功能将出现异常
|
||||||
"*.msecnd.net": true,
|
"*.msecnd.net": true,
|
||||||
"*.msedge.net": true,
|
"*.msedge.net": true,
|
||||||
|
|
||||||
// 卡巴斯基升级域名
|
// 卡巴斯基升级域名
|
||||||
"*kaspersky*.com": true,
|
"*kaspersky*.com": true,
|
||||||
"*.upd.kaspersky.com": true,
|
"*.upd.kaspersky.com": true,
|
||||||
|
|
||||||
// sandbox沙盒域名
|
// sandbox沙盒域名
|
||||||
"*.sandboxie-plus.com": true,
|
"*.sandboxie-plus.com": true,
|
||||||
|
|
||||||
// 无忧论坛
|
// 无忧论坛
|
||||||
"*.wuyou.net": true,
|
"*.wuyou.net": true,
|
||||||
|
|
||||||
// python建图包域名(浏览器)
|
// python建图包域名(浏览器)
|
||||||
"*.pyecharts.org": true,
|
"*.pyecharts.org": true,
|
||||||
|
|
||||||
// 教育网站
|
// 教育网站
|
||||||
"*.bcloudlink.com": true,
|
"*.bcloudlink.com": true,
|
||||||
|
|
||||||
// 奇迹秀(资源)
|
// 奇迹秀(资源)
|
||||||
"*.qijishow.com": true,
|
"*.qijishow.com": true,
|
||||||
|
|
||||||
// Z-Library
|
// Z-Library
|
||||||
"*.z-lib.fo": true,
|
"*.z-lib.fo": true,
|
||||||
|
|
||||||
// Finalshell(Linux学习网)
|
// Finalshell(Linux学习网)
|
||||||
"*.finalshell.com": true,
|
"*.finalshell.com": true,
|
||||||
|
|
||||||
// MineBBS(我的世界中文论坛)
|
// MineBBS(我的世界中文论坛)
|
||||||
"*.minebbs.com": true,
|
"*.minebbs.com": true,
|
||||||
|
|
||||||
// 我的世界插件网
|
// 我的世界插件网
|
||||||
"*.spigotmc.org": true,
|
"*.spigotmc.org": true,
|
||||||
|
|
||||||
// bd测试
|
// bd测试
|
||||||
"*.virustotal.com": true,
|
"*.virustotal.com": true,
|
||||||
|
|
||||||
// 未知
|
// 未知
|
||||||
"*.youdemai.com": true,
|
"*.youdemai.com": true,
|
||||||
"*.casualthink.com": true,
|
"*.casualthink.com": true,
|
||||||
"44.239.165.12": true,
|
"44.239.165.12": true,
|
||||||
"3.164.110.117": true
|
"3.164.110.117": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugin": {
|
"plugin": {
|
||||||
"overwall": {
|
"overwall": {
|
||||||
"targets": {
|
"targets": {
|
||||||
"*.github.com": true,
|
"*.github.com": true,
|
||||||
"*github*.com": true,
|
"*github*.com": true,
|
||||||
"*.nodejs.org": true,
|
"*.nodejs.org": true,
|
||||||
"*.npmjs.com": true,
|
"*.npmjs.com": true,
|
||||||
"*.wikimedia.org": true,
|
"*.wikimedia.org": true,
|
||||||
"*.v2ex.com": true,
|
"*.v2ex.com": true,
|
||||||
"*.azureedge.net": true,
|
"*.azureedge.net": true,
|
||||||
"*.cloudfront.net": true,
|
"*.cloudfront.net": true,
|
||||||
"*.bing.com": true,
|
"*.bing.com": true,
|
||||||
"*.discourse-cdn.com": true,
|
"*.discourse-cdn.com": true,
|
||||||
"*.gravatar.com": true,
|
"*.gravatar.com": true,
|
||||||
"*.docker.com": true,
|
"*.docker.com": true,
|
||||||
"*.vueuse.org": true,
|
"*.vueuse.org": true,
|
||||||
"*.elastic.co": true,
|
"*.elastic.co": true,
|
||||||
"*.optimizely.com": true,
|
"*.optimizely.com": true,
|
||||||
"*.stackpathcdn.com": true,
|
"*.stackpathcdn.com": true,
|
||||||
"*.fastly.net": true,
|
"*.fastly.net": true,
|
||||||
"*.cloudflare.com": true,
|
"*.cloudflare.com": true,
|
||||||
"*.233v2.com": true,
|
"*.233v2.com": true,
|
||||||
"*.v2fly.org": true,
|
"*.v2fly.org": true,
|
||||||
"*.telegram.org": true,
|
"*.telegram.org": true,
|
||||||
"*.amazon.com": true,
|
"*.amazon.com": true,
|
||||||
"*.googleapis.com": true,
|
"*.googleapis.com": true,
|
||||||
"*.google-analytics.com": true,
|
"*.google-analytics.com": true,
|
||||||
"*.cloudflareinsights.com": true,
|
"*.cloudflareinsights.com": true,
|
||||||
"*.intlify.dev": true,
|
"*.intlify.dev": true,
|
||||||
"*.segment.io": true,
|
"*.segment.io": true,
|
||||||
"*.shields.io": true,
|
"*.shields.io": true,
|
||||||
"*.jsdelivr.net": true,
|
"*.jsdelivr.net": true,
|
||||||
"*.z-library.sk": true,
|
"*.z-library.sk": true,
|
||||||
"*.zlibrary*.se": true,
|
"*.zlibrary*.se": true,
|
||||||
|
|
||||||
// 维基百科
|
// 维基百科
|
||||||
"*.wikipedia-on-ipfs.org": true,
|
"*.wikipedia-on-ipfs.org": true,
|
||||||
|
|
||||||
// ChatGPT
|
// ChatGPT
|
||||||
"*.oaiusercontent.com": true, // 在ChatGPT中生成文件并下载所需的域名
|
"*.oaiusercontent.com": true, // 在ChatGPT中生成文件并下载所需的域名
|
||||||
|
|
||||||
// Pixiv相关
|
// Pixiv相关
|
||||||
"*.pixiv.org": true,
|
"*.pixiv.org": true,
|
||||||
"*.fanbox.cc": true,
|
"*.fanbox.cc": true,
|
||||||
"*.onesignal.com": true // pixiv站点,会加载该域名下的js脚本
|
"*.onesignal.com": true // pixiv站点,会加载该域名下的js脚本
|
||||||
},
|
},
|
||||||
"pac": {
|
"pac": {
|
||||||
"pacFileUpdateUrl": "https://raw.kkgithub.com/gfwlist/gfwlist/master/gfwlist.txt"
|
"pacFileUpdateUrl": "https://raw.kkgithub.com/gfwlist/gfwlist/master/gfwlist.txt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,14 +46,16 @@ async function startup ({ mitmproxyPath }) {
|
||||||
if (conf.server.enabled) {
|
if (conf.server.enabled) {
|
||||||
try {
|
try {
|
||||||
await server.start({ mitmproxyPath })
|
await server.start({ mitmproxyPath })
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error('代理服务启动失败:', err)
|
log.error('代理服务启动失败:', err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (conf.proxy.enabled) {
|
if (conf.proxy.enabled) {
|
||||||
try {
|
try {
|
||||||
await proxy.start()
|
await proxy.start()
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error('开启系统代理失败:', err)
|
log.error('开启系统代理失败:', err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +67,8 @@ async function startup ({ mitmproxyPath }) {
|
||||||
try {
|
try {
|
||||||
await plugin[key].start()
|
await plugin[key].start()
|
||||||
log.info(`插件【${key}】已启动`)
|
log.info(`插件【${key}】已启动`)
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error(`插件【${key}】启动失败:`, err)
|
log.error(`插件【${key}】启动失败:`, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +78,8 @@ async function startup ({ mitmproxyPath }) {
|
||||||
if (plugins && plugins.length > 0) {
|
if (plugins && plugins.length > 0) {
|
||||||
await Promise.all(plugins)
|
await Promise.all(plugins)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error('开启插件失败:', err)
|
log.error('开启插件失败:', err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +93,8 @@ async function shutdown () {
|
||||||
try {
|
try {
|
||||||
await plugin[key].close()
|
await plugin[key].close()
|
||||||
log.info(`插件【${key}】已关闭`)
|
log.info(`插件【${key}】已关闭`)
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error(`插件【${key}】关闭失败:`, err)
|
log.error(`插件【${key}】关闭失败:`, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +104,8 @@ async function shutdown () {
|
||||||
if (plugins.length > 0) {
|
if (plugins.length > 0) {
|
||||||
await Promise.all(plugins)
|
await Promise.all(plugins)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
log.error('插件关闭失败:', error)
|
log.error('插件关闭失败:', error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +113,8 @@ async function shutdown () {
|
||||||
try {
|
try {
|
||||||
await proxy.close()
|
await proxy.close()
|
||||||
log.info('系统代理已关闭')
|
log.info('系统代理已关闭')
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error('系统代理关闭失败:', err)
|
log.error('系统代理关闭失败:', err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +122,8 @@ async function shutdown () {
|
||||||
try {
|
try {
|
||||||
await server.close()
|
await server.close()
|
||||||
log.info('代理服务已关闭')
|
log.info('代理服务已关闭')
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error('代理服务关闭失败:', err)
|
log.error('代理服务关闭失败:', err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,13 +56,15 @@ const Plugin = function (context) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await shell.exec(['git config --global --unset https.proxy '], { type: 'cmd' })
|
await shell.exec(['git config --global --unset https.proxy '], { type: 'cmd' })
|
||||||
} catch (ignore) {
|
}
|
||||||
|
catch (ignore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.get().plugin.git.setting.sslVerify === true) {
|
if (config.get().plugin.git.setting.sslVerify === true) {
|
||||||
try {
|
try {
|
||||||
await shell.exec(['git config --global --unset http.sslVerify '], { type: 'cmd' })
|
await shell.exec(['git config --global --unset http.sslVerify '], { type: 'cmd' })
|
||||||
} catch (ignore) {
|
}
|
||||||
|
catch (ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +72,8 @@ const Plugin = function (context) {
|
||||||
for (const url in config.get().plugin.git.setting.noProxyUrls) {
|
for (const url in config.get().plugin.git.setting.noProxyUrls) {
|
||||||
try {
|
try {
|
||||||
await shell.exec([`git config --global --unset http."${url}".proxy `], { type: 'cmd' })
|
await shell.exec([`git config --global --unset http."${url}".proxy `], { type: 'cmd' })
|
||||||
} catch (ignore) {
|
}
|
||||||
|
catch (ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ const NodePlugin = function (context) {
|
||||||
async start () {
|
async start () {
|
||||||
try {
|
try {
|
||||||
await nodeApi.setVariables()
|
await nodeApi.setVariables()
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.warn('set variables error:', err)
|
log.warn('set variables error:', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +48,8 @@ const NodePlugin = function (context) {
|
||||||
for (const item of list) {
|
for (const item of list) {
|
||||||
if (item.value != null && item.value.length > 0 && item.value !== 'default' && item.value !== 'null') {
|
if (item.value != null && item.value.length > 0 && item.value !== 'default' && item.value !== 'null') {
|
||||||
cmds.push(`${command} config set ${item.key} ${item.value}`)
|
cmds.push(`${command} config set ${item.key} ${item.value}`)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
cmds.push(`${command} config delete ${item.key}`)
|
cmds.push(`${command} config delete ${item.key}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +72,8 @@ const NodePlugin = function (context) {
|
||||||
for (const item of list) {
|
for (const item of list) {
|
||||||
if (item.value != null && item.value.length > 0 && item.value !== 'default' && item.value !== 'null') {
|
if (item.value != null && item.value.length > 0 && item.value !== 'default' && item.value !== 'null') {
|
||||||
cmds.push(`yarn config set ${item.key} ${item.value}`)
|
cmds.push(`yarn config set ${item.key} ${item.value}`)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
cmds.push(`yarn config delete ${item.key}`)
|
cmds.push(`yarn config delete ${item.key}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +118,8 @@ const NodePlugin = function (context) {
|
||||||
async setRegistry ({ registry, type }) {
|
async setRegistry ({ registry, type }) {
|
||||||
if (type === 'npm') {
|
if (type === 'npm') {
|
||||||
await nodeApi.setNpmEnv([{ key: 'registry', value: registry }])
|
await nodeApi.setNpmEnv([{ key: 'registry', value: registry }])
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
await nodeApi.setYarnEnv([{ key: 'registry', value: registry }])
|
await nodeApi.setYarnEnv([{ key: 'registry', value: registry }])
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ const Plugin = function (context) {
|
||||||
for (const key in server) {
|
for (const key in server) {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
main = key
|
main = key
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
backup.push(key)
|
backup.push(key)
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ const PipPlugin = function (context) {
|
||||||
for (const item of list) {
|
for (const item of list) {
|
||||||
if (item.value != null) {
|
if (item.value != null) {
|
||||||
cmds.push(`${command} config set global.${item.key} ${item.value}`)
|
cmds.push(`${command} config set global.${item.key} ${item.value}`)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
cmds.push(`${command} config unset global.${item.key}`)
|
cmds.push(`${command} config unset global.${item.key}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ const ProxyPlugin = function (context) {
|
||||||
event.fire('status', { key: 'proxy.enabled', value: false })
|
event.fire('status', { key: 'proxy.enabled', value: false })
|
||||||
log.info('关闭系统代理成功')
|
log.info('关闭系统代理成功')
|
||||||
return true
|
return true
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.error('关闭系统代理失败:', err)
|
log.error('关闭系统代理失败:', err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ const lodash = require('lodash')
|
||||||
const config = require('../../config')
|
const config = require('../../config')
|
||||||
const event = require('../../event')
|
const event = require('../../event')
|
||||||
const status = require('../../status')
|
const status = require('../../status')
|
||||||
const fork = require('child_process').fork
|
const fork = require('node:child_process').fork
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
||||||
const log = require('../../utils/util.log')
|
const log = require('../../utils/util.log')
|
||||||
|
|
||||||
|
|
@ -102,14 +102,16 @@ const serverApi = {
|
||||||
log.info('收到子进程消息:', JSON.stringify(msg))
|
log.info('收到子进程消息:', JSON.stringify(msg))
|
||||||
if (msg.type === 'status') {
|
if (msg.type === 'status') {
|
||||||
fireStatus(msg.event)
|
fireStatus(msg.event)
|
||||||
} else if (msg.type === 'error') {
|
}
|
||||||
|
else if (msg.type === 'error') {
|
||||||
let code = ''
|
let code = ''
|
||||||
if (msg.event.code) {
|
if (msg.event.code) {
|
||||||
code = msg.event.code
|
code = msg.event.code
|
||||||
}
|
}
|
||||||
fireStatus(false) // 启动失败
|
fireStatus(false) // 启动失败
|
||||||
event.fire('error', { key: 'server', value: code, error: msg.event, message: msg.message })
|
event.fire('error', { key: 'server', value: code, error: msg.event, message: msg.message })
|
||||||
} else if (msg.type === 'speed') {
|
}
|
||||||
|
else if (msg.type === 'speed') {
|
||||||
event.fire('speed', msg.event)
|
event.fire('speed', msg.event)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -139,12 +141,14 @@ const serverApi = {
|
||||||
}
|
}
|
||||||
log.warn('代理服务关闭失败:', err)
|
log.warn('代理服务关闭失败:', err)
|
||||||
reject(err)
|
reject(err)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('代理服务关闭成功')
|
log.info('代理服务关闭成功')
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('server is null')
|
log.info('server is null')
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
|
|
||||||
function getExtraPath () {
|
function getExtraPath () {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
|
const fs = require('node:fs')
|
||||||
|
const path = require('node:path')
|
||||||
|
const request = require('request')
|
||||||
/**
|
/**
|
||||||
* 获取环境变量
|
* 获取环境变量
|
||||||
*/
|
*/
|
||||||
const Registry = require('winreg')
|
const Registry = require('winreg')
|
||||||
const Shell = require('../../shell')
|
|
||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const request = require('request')
|
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
|
const Shell = require('../../shell')
|
||||||
const extraPath = require('../extra-path/index')
|
const extraPath = require('../extra-path/index')
|
||||||
|
|
||||||
const execute = Shell.execute
|
const execute = Shell.execute
|
||||||
|
|
@ -44,7 +44,8 @@ async function _winUnsetProxy (exec, setEnv) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('删除环境变量 HTTPS_PROXY、HTTP_PROXY 失败:', e)
|
log.error('删除环境变量 HTTPS_PROXY、HTTP_PROXY 失败:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +68,8 @@ async function downloadDomesticDomainAllowListAsync () {
|
||||||
if (body == null || body.length < 100) {
|
if (body == null || body.length < 100) {
|
||||||
log.warn('下载远程 domestic-domain-allowlist.txt 文件成功,但内容为空或内容太短,判断为无效的 domestic-domain-allowlist.txt 文件:', remoteFileUrl, ', body:', body)
|
log.warn('下载远程 domestic-domain-allowlist.txt 文件成功,但内容为空或内容太短,判断为无效的 domestic-domain-allowlist.txt 文件:', remoteFileUrl, ', body:', body)
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('下载远程 domestic-domain-allowlist.txt 文件成功:', remoteFileUrl)
|
log.info('下载远程 domestic-domain-allowlist.txt 文件成功:', remoteFileUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +79,8 @@ async function downloadDomesticDomainAllowListAsync () {
|
||||||
fileTxt = Buffer.from(fileTxt, 'base64').toString('utf8')
|
fileTxt = Buffer.from(fileTxt, 'base64').toString('utf8')
|
||||||
// log.debug('解析 base64 后的 domestic-domain-allowlist:', fileTxt)
|
// log.debug('解析 base64 后的 domestic-domain-allowlist:', fileTxt)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
if (!fileTxt.includes('*.')) {
|
if (!fileTxt.includes('*.')) {
|
||||||
log.error(`远程 domestic-domain-allowlist.txt 文件内容即不是base64格式,也不是要求的格式,url: ${remoteFileUrl},body: ${body}`)
|
log.error(`远程 domestic-domain-allowlist.txt 文件内容即不是base64格式,也不是要求的格式,url: ${remoteFileUrl},body: ${body}`)
|
||||||
return
|
return
|
||||||
|
|
@ -86,7 +89,8 @@ async function downloadDomesticDomainAllowListAsync () {
|
||||||
|
|
||||||
// 保存到本地
|
// 保存到本地
|
||||||
saveDomesticDomainAllowListFile(fileTxt)
|
saveDomesticDomainAllowListFile(fileTxt)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.error(`下载远程 domestic-domain-allowlist.txt 文件失败: ${remoteFileUrl}, response:`, response, ', body:', body)
|
log.error(`下载远程 domestic-domain-allowlist.txt 文件失败: ${remoteFileUrl}, response:`, response, ', body:', body)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -97,7 +101,8 @@ function loadLastModifiedTimeFromTxt (fileTxt) {
|
||||||
if (matched && matched.length > 0) {
|
if (matched && matched.length > 0) {
|
||||||
try {
|
try {
|
||||||
return new Date(matched[0])
|
return new Date(matched[0])
|
||||||
} catch (ignore) {
|
}
|
||||||
|
catch (ignore) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +127,8 @@ function saveDomesticDomainAllowListFile (fileTxt) {
|
||||||
fs.utimes(filePath, lastModifiedTime, lastModifiedTime, (utimesErr) => {
|
fs.utimes(filePath, lastModifiedTime, lastModifiedTime, (utimesErr) => {
|
||||||
if (utimesErr) {
|
if (utimesErr) {
|
||||||
log.error('修改 domestic-domain-allowlist.txt 文件时间失败:', utimesErr)
|
log.error('修改 domestic-domain-allowlist.txt 文件时间失败:', utimesErr)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`'${filePath}' 文件的修改时间已更新为其最近更新时间 '${formatDate(lastModifiedTime)}'`)
|
log.info(`'${filePath}' 文件的修改时间已更新为其最近更新时间 '${formatDate(lastModifiedTime)}'`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -163,19 +169,22 @@ function getDomesticDomainAllowList () {
|
||||||
// 如果临时文件已存在,则使用临时文件
|
// 如果临时文件已存在,则使用临时文件
|
||||||
fileAbsolutePath = tmpFilePath
|
fileAbsolutePath = tmpFilePath
|
||||||
log.info('读取已下载的 domestic-domain-allowlist.txt 文件:', fileAbsolutePath)
|
log.info('读取已下载的 domestic-domain-allowlist.txt 文件:', fileAbsolutePath)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 如果临时文件不存在,则使用内置文件
|
// 如果临时文件不存在,则使用内置文件
|
||||||
log.info('__dirname:', __dirname)
|
log.info('__dirname:', __dirname)
|
||||||
fileAbsolutePath = path.join(__dirname, '../', config.get().proxy.domesticDomainAllowListFilePath)
|
fileAbsolutePath = path.join(__dirname, '../', config.get().proxy.domesticDomainAllowListFilePath)
|
||||||
log.info('读取内置的 domestic-domain-allowlist.txt 文件:', fileAbsolutePath)
|
log.info('读取内置的 domestic-domain-allowlist.txt 文件:', fileAbsolutePath)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('读取自定义路径的 domestic-domain-allowlist.txt 文件:', fileAbsolutePath)
|
log.info('读取自定义路径的 domestic-domain-allowlist.txt 文件:', fileAbsolutePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return fs.readFileSync(fileAbsolutePath).toString()
|
return fs.readFileSync(fileAbsolutePath).toString()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error(`读取 domestic-domain-allowlist.txt 文件失败: ${fileAbsolutePath}, error:`, e)
|
log.error(`读取 domestic-domain-allowlist.txt 文件失败: ${fileAbsolutePath}, error:`, e)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
@ -198,11 +207,13 @@ function getProxyExcludeIpStr (split) {
|
||||||
if (domesticDomainAllowList) {
|
if (domesticDomainAllowList) {
|
||||||
excludeIpStr += domesticDomainAllowList
|
excludeIpStr += domesticDomainAllowList
|
||||||
log.info('系统代理排除列表拼接国内域名')
|
log.info('系统代理排除列表拼接国内域名')
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('国内域名为空,不进行系统代理排除列表拼接国内域名')
|
log.info('国内域名为空,不进行系统代理排除列表拼接国内域名')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('系统代理排除列表拼接国内域名失败:', e)
|
log.error('系统代理排除列表拼接国内域名失败:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -246,7 +257,8 @@ async function _winSetProxy (exec, ip, port, setEnv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// await addClearScriptIni()
|
// await addClearScriptIni()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('设置环境变量 HTTPS_PROXY、HTTP_PROXY 失败:', e)
|
log.error('设置环境变量 HTTPS_PROXY、HTTP_PROXY 失败:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -260,7 +272,8 @@ const executor = {
|
||||||
if (ip != null) { // 设置代理
|
if (ip != null) { // 设置代理
|
||||||
log.info('设置windows系统代理:', ip, port, setEnv)
|
log.info('设置windows系统代理:', ip, port, setEnv)
|
||||||
return _winSetProxy(exec, ip, port, setEnv)
|
return _winSetProxy(exec, ip, port, setEnv)
|
||||||
} else { // 关闭代理
|
}
|
||||||
|
else { // 关闭代理
|
||||||
log.info('关闭windows系统代理')
|
log.info('关闭windows系统代理')
|
||||||
return _winUnsetProxy(exec, setEnv)
|
return _winUnsetProxy(exec, setEnv)
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +294,8 @@ const executor = {
|
||||||
if (config.get().proxy.proxyHttp) {
|
if (config.get().proxy.proxyHttp) {
|
||||||
setProxyCmd.push(`gsettings set org.gnome.system.proxy.http host ${ip}`)
|
setProxyCmd.push(`gsettings set org.gnome.system.proxy.http host ${ip}`)
|
||||||
setProxyCmd.push(`gsettings set org.gnome.system.proxy.http port ${port - 1}`)
|
setProxyCmd.push(`gsettings set org.gnome.system.proxy.http port ${port - 1}`)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
setProxyCmd.push('gsettings set org.gnome.system.proxy.http host \'\'')
|
setProxyCmd.push('gsettings set org.gnome.system.proxy.http host \'\'')
|
||||||
setProxyCmd.push('gsettings set org.gnome.system.proxy.http port 0')
|
setProxyCmd.push('gsettings set org.gnome.system.proxy.http port 0')
|
||||||
}
|
}
|
||||||
|
|
@ -291,7 +305,8 @@ const executor = {
|
||||||
setProxyCmd.push(`gsettings set org.gnome.system.proxy ignore-hosts "['${excludeIpStr}']"`)
|
setProxyCmd.push(`gsettings set org.gnome.system.proxy ignore-hosts "['${excludeIpStr}']"`)
|
||||||
|
|
||||||
await exec(setProxyCmd)
|
await exec(setProxyCmd)
|
||||||
} else { // 关闭代理
|
}
|
||||||
|
else { // 关闭代理
|
||||||
const setProxyCmd = [
|
const setProxyCmd = [
|
||||||
'gsettings set org.gnome.system.proxy mode none',
|
'gsettings set org.gnome.system.proxy mode none',
|
||||||
]
|
]
|
||||||
|
|
@ -313,7 +328,8 @@ const executor = {
|
||||||
// http
|
// http
|
||||||
if (config.get().proxy.proxyHttp) {
|
if (config.get().proxy.proxyHttp) {
|
||||||
await exec(`networksetup -setwebproxy "${wifiAdaptor}" ${ip} ${port - 1}`)
|
await exec(`networksetup -setwebproxy "${wifiAdaptor}" ${ip} ${port - 1}`)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
await exec(`networksetup -setwebproxystate "${wifiAdaptor}" off`)
|
await exec(`networksetup -setwebproxystate "${wifiAdaptor}" off`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -328,7 +344,8 @@ const executor = {
|
||||||
// source ~/.zshrc
|
// source ~/.zshrc
|
||||||
// `
|
// `
|
||||||
// await exec(setEnv)
|
// await exec(setEnv)
|
||||||
} else { // 关闭代理
|
}
|
||||||
|
else { // 关闭代理
|
||||||
// https
|
// https
|
||||||
await exec(`networksetup -setsecurewebproxystate "${wifiAdaptor}" off`)
|
await exec(`networksetup -setsecurewebproxystate "${wifiAdaptor}" off`)
|
||||||
// http
|
// http
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const childProcess = require('child_process')
|
const childProcess = require('node:child_process')
|
||||||
const os = require('os')
|
const os = require('node:os')
|
||||||
const fixPath = require('fix-path')
|
const fixPath = require('fix-path')
|
||||||
const iconv = require('iconv-lite')
|
const iconv = require('iconv-lite')
|
||||||
const PowerShell = require('node-powershell')
|
const PowerShell = require('node-powershell')
|
||||||
|
|
@ -60,10 +60,12 @@ class WindowsSystemShell extends SystemShell {
|
||||||
const ret = await ps.invoke()
|
const ret = await ps.invoke()
|
||||||
// log.info('ps complete', cmds)
|
// log.info('ps complete', cmds)
|
||||||
return ret
|
return ret
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
ps.dispose()
|
ps.dispose()
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
let compose = 'echo "test" ' // 'chcp 65001 '
|
let compose = 'echo "test" ' // 'chcp 65001 '
|
||||||
for (const cmd of cmds) {
|
for (const cmd of cmds) {
|
||||||
compose += ` && ${cmd}`
|
compose += ` && ${cmd}`
|
||||||
|
|
@ -78,7 +80,7 @@ class WindowsSystemShell extends SystemShell {
|
||||||
|
|
||||||
function _childExec (composeCmds, options = {}) {
|
function _childExec (composeCmds, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const childProcess = require('child_process')
|
const childProcess = require('node:child_process')
|
||||||
log.info('shell:', composeCmds)
|
log.info('shell:', composeCmds)
|
||||||
childProcess.exec(composeCmds, options, (error, stdout, stderr) => {
|
childProcess.exec(composeCmds, options, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
@ -86,7 +88,8 @@ function _childExec (composeCmds, options = {}) {
|
||||||
log.error('cmd 命令执行错误:\n===>\ncommands:', composeCmds, '\n error:', error, '\n<===')
|
log.error('cmd 命令执行错误:\n===>\ncommands:', composeCmds, '\n error:', error, '\n<===')
|
||||||
}
|
}
|
||||||
reject(new Error(stderr))
|
reject(new Error(stderr))
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// log.info('cmd 命令完成:', stdout)
|
// log.info('cmd 命令完成:', stdout)
|
||||||
resolve(stdout)
|
resolve(stdout)
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +104,7 @@ function childExec (composeCmds, options = {}) {
|
||||||
const encoding = 'cp936'
|
const encoding = 'cp936'
|
||||||
const binaryEncoding = 'binary'
|
const binaryEncoding = 'binary'
|
||||||
|
|
||||||
const childProcess = require('child_process')
|
const childProcess = require('node:child_process')
|
||||||
log.info('shell:', composeCmds)
|
log.info('shell:', composeCmds)
|
||||||
childProcess.exec(composeCmds, { encoding: binaryEncoding }, (error, stdout, stderr) => {
|
childProcess.exec(composeCmds, { encoding: binaryEncoding }, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
@ -111,7 +114,8 @@ function childExec (composeCmds, options = {}) {
|
||||||
log.error('cmd 命令执行错误:\n------------------------------\ncommands:', composeCmds, '\n message:', message, '\n error:', error, '\n------------------------------')
|
log.error('cmd 命令执行错误:\n------------------------------\ncommands:', composeCmds, '\n message:', message, '\n error:', error, '\n------------------------------')
|
||||||
}
|
}
|
||||||
reject(new Error(message))
|
reject(new Error(message))
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// log.info('cmd 命令完成:', stdout)
|
// log.info('cmd 命令完成:', stdout)
|
||||||
const message = iconv.decode(Buffer.from(stdout, binaryEncoding), encoding)
|
const message = iconv.decode(Buffer.from(stdout, binaryEncoding), encoding)
|
||||||
resolve(message)
|
resolve(message)
|
||||||
|
|
@ -167,7 +171,8 @@ async function execFile (file, args, options) {
|
||||||
log.debug('文件执行成功:', file)
|
log.debug('文件执行成功:', file)
|
||||||
resolve(stdout)
|
resolve(stdout)
|
||||||
})
|
})
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('文件执行出错:', file, e)
|
log.error('文件执行出错:', file, e)
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
// console.error(e)
|
// console.error(e)
|
||||||
// })
|
// })
|
||||||
|
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
|
|
||||||
request({
|
request({
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const log4js = require('log4js')
|
const log4js = require('log4js')
|
||||||
const config = require('../config/index')
|
const config = require('../config/index')
|
||||||
|
|
||||||
|
|
@ -13,17 +13,17 @@ const guiLogFilename = path.join(getDefaultConfigBasePath(), '/logs/gui.log')
|
||||||
const serverLogFilename = path.join(getDefaultConfigBasePath(), '/logs/server.log')
|
const serverLogFilename = path.join(getDefaultConfigBasePath(), '/logs/server.log')
|
||||||
|
|
||||||
log4js.configure({
|
log4js.configure({
|
||||||
appenders: {
|
appenders: {
|
||||||
std: { type: 'stdout' },
|
std: { type: 'stdout' },
|
||||||
core: { type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename: coreLogFilename },
|
core: { type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename: coreLogFilename },
|
||||||
gui: { type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename: guiLogFilename },
|
gui: { type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename: guiLogFilename },
|
||||||
server: { level: 'debug', type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename: serverLogFilename }
|
server: { level: 'debug', type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename: serverLogFilename },
|
||||||
},
|
},
|
||||||
categories: {
|
categories: {
|
||||||
default: { appenders: ['std'], level },
|
default: { appenders: ['std'], level },
|
||||||
core: { appenders: ['core', 'std'], level },
|
core: { appenders: ['core', 'std'], level },
|
||||||
gui: { appenders: ['gui', 'std'], level },
|
gui: { appenders: ['gui', 'std'], level },
|
||||||
server: { appenders: ['server', 'std'], level }
|
server: { appenders: ['server', 'std'], level },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const https = require('https')
|
const https = require('node:https')
|
||||||
|
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,29 @@
|
||||||
# dev-sidecar-gui
|
# dev-sidecar-gui
|
||||||
|
|
||||||
## Project setup
|
## Project setup
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compiles and hot-reloads for development
|
### Compiles and hot-reloads for development
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn serve
|
yarn serve
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compiles and minifies for production
|
### Compiles and minifies for production
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn build
|
yarn build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Lints and fixes files
|
### Lints and fixes files
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn lint
|
yarn lint
|
||||||
```
|
```
|
||||||
|
|
||||||
### Customize configuration
|
### Customize configuration
|
||||||
|
|
||||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [
|
||||||
'@vue/babel-preset-jsx'
|
'@vue/babel-preset-jsx',
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const pkg = require('../package.json')
|
const pkg = require('../package.json')
|
||||||
|
|
||||||
function appendIntro (context, systemType, latest) {
|
function appendIntro (context, systemType, latest) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const AdmZip = require('adm-zip')
|
const AdmZip = require('adm-zip')
|
||||||
const pkg = require('../package.json')
|
const pkg = require('../package.json')
|
||||||
|
|
||||||
|
|
@ -24,11 +24,13 @@ exports.default = async function (context) {
|
||||||
if (context.packager.platform.nodeName === 'darwin') {
|
if (context.packager.platform.nodeName === 'darwin') {
|
||||||
targetPath = path.join(context.appOutDir, `${context.packager.appInfo.productName}.app/Contents/Resources`)
|
targetPath = path.join(context.appOutDir, `${context.packager.appInfo.productName}.app/Contents/Resources`)
|
||||||
systemType = 'mac'
|
systemType = 'mac'
|
||||||
} else if (context.packager.platform.nodeName === 'linux') {
|
}
|
||||||
|
else if (context.packager.platform.nodeName === 'linux') {
|
||||||
targetPath = path.join(context.appOutDir, './resources')
|
targetPath = path.join(context.appOutDir, './resources')
|
||||||
systemType = 'linux'
|
systemType = 'linux'
|
||||||
writeAppUpdateYmlForLinux()
|
writeAppUpdateYmlForLinux()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
targetPath = path.join(context.appOutDir, './resources')
|
targetPath = path.join(context.appOutDir, './resources')
|
||||||
systemType = 'win'
|
systemType = 'win'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en" style="height:100%">
|
<html lang="en" style="height: 100%">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
<script type="application/javascript">window.config = {}</script>
|
<script type="application/javascript">
|
||||||
|
window.config = {}
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body style="height:100%">
|
<body style="height: 100%">
|
||||||
<div id="app" style="height:100%">
|
<div id="app" style="height: 100%">
|
||||||
<div style="display: flex;align-items: center;justify-content: center;height:100%;width:100%"><img src="loading-spin.svg"></div>
|
<div style="display: flex; align-items: center; justify-content: center; height: 100%; width: 100%">
|
||||||
|
<img src="loading-spin.svg" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
/* global __static */
|
/* global __static */
|
||||||
import path from 'path'
|
import path from 'node:path'
|
||||||
import DevSidecar from '@docmirror/dev-sidecar'
|
import DevSidecar from '@docmirror/dev-sidecar'
|
||||||
import { app, BrowserWindow, dialog, globalShortcut, ipcMain, Menu, nativeImage, nativeTheme, powerMonitor, protocol, Tray } from 'electron'
|
import { app, BrowserWindow, dialog, globalShortcut, ipcMain, Menu, nativeImage, nativeTheme, powerMonitor, protocol, Tray } from 'electron'
|
||||||
import minimist from 'minimist'
|
import minimist from 'minimist'
|
||||||
|
|
@ -34,7 +34,8 @@ function openDevTools () {
|
||||||
log.debug('尝试打开 `开发者工具`')
|
log.debug('尝试打开 `开发者工具`')
|
||||||
win.webContents.openDevTools()
|
win.webContents.openDevTools()
|
||||||
log.debug('打开 `开发者工具` 成功')
|
log.debug('打开 `开发者工具` 成功')
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('打开 `开发者工具` 失败:', e)
|
log.error('打开 `开发者工具` 失败:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +45,8 @@ function closeDevTools () {
|
||||||
log.debug('尝试关闭 `开发者工具`')
|
log.debug('尝试关闭 `开发者工具`')
|
||||||
win.webContents.closeDevTools()
|
win.webContents.closeDevTools()
|
||||||
log.debug('关闭 `开发者工具` 成功')
|
log.debug('关闭 `开发者工具` 成功')
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('关闭 `开发者工具` 失败:', e)
|
log.error('关闭 `开发者工具` 失败:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -55,7 +57,8 @@ function switchDevTools () {
|
||||||
}
|
}
|
||||||
if (win.webContents.isDevToolsOpened()) {
|
if (win.webContents.isDevToolsOpened()) {
|
||||||
closeDevTools()
|
closeDevTools()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
openDevTools()
|
openDevTools()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +105,8 @@ function setTray () {
|
||||||
if (nativeTheme.shouldUseDarkColors) {
|
if (nativeTheme.shouldUseDarkColors) {
|
||||||
console.log('i am dark.')
|
console.log('i am dark.')
|
||||||
tray.setImage(iconWhitePath)
|
tray.setImage(iconWhitePath)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
console.log('i am light.')
|
console.log('i am light.')
|
||||||
tray.setImage(iconBlackPath)
|
tray.setImage(iconBlackPath)
|
||||||
// tray.setPressedImage(iconWhitePath)
|
// tray.setPressedImage(iconWhitePath)
|
||||||
|
|
@ -200,7 +204,8 @@ function createWindow (startHideWindow) {
|
||||||
if (!process.env.IS_TEST) {
|
if (!process.env.IS_TEST) {
|
||||||
setTimeout(openDevTools, 2000)
|
setTimeout(openDevTools, 2000)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
createProtocol('app')
|
createProtocol('app')
|
||||||
// Load the index.html when not in development
|
// Load the index.html when not in development
|
||||||
win.loadURL('app://./index.html')
|
win.loadURL('app://./index.html')
|
||||||
|
|
@ -219,7 +224,8 @@ function createWindow (startHideWindow) {
|
||||||
ipcMain.on('close', async (event, message) => {
|
ipcMain.on('close', async (event, message) => {
|
||||||
if (message.value === 1) {
|
if (message.value === 1) {
|
||||||
quit()
|
quit()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
hideWin()
|
hideWin()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -239,10 +245,12 @@ function createWindow (startHideWindow) {
|
||||||
if (closeStrategy === 0) {
|
if (closeStrategy === 0) {
|
||||||
// 弹窗提示,选择关闭策略
|
// 弹窗提示,选择关闭策略
|
||||||
win.webContents.send('close.showTip', closeStrategy)
|
win.webContents.send('close.showTip', closeStrategy)
|
||||||
} else if (closeStrategy === 1) {
|
}
|
||||||
|
else if (closeStrategy === 1) {
|
||||||
// 直接退出
|
// 直接退出
|
||||||
quit()
|
quit()
|
||||||
} else if (closeStrategy === 2) {
|
}
|
||||||
|
else if (closeStrategy === 2) {
|
||||||
// 隐藏窗口
|
// 隐藏窗口
|
||||||
hideWin()
|
hideWin()
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +328,8 @@ function registerShowHideShortcut (showHideShortcut) {
|
||||||
if (winIsHidden) {
|
if (winIsHidden) {
|
||||||
showWin()
|
showWin()
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// linux,快捷键不关闭窗口
|
// linux,快捷键不关闭窗口
|
||||||
if (!isLinux()) {
|
if (!isLinux()) {
|
||||||
hideWin()
|
hideWin()
|
||||||
|
|
@ -330,10 +339,12 @@ function registerShowHideShortcut (showHideShortcut) {
|
||||||
|
|
||||||
if (registerSuccess) {
|
if (registerSuccess) {
|
||||||
log.info('注册快捷键成功:', DevSidecar.api.config.get().app.showHideShortcut)
|
log.info('注册快捷键成功:', DevSidecar.api.config.get().app.showHideShortcut)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.error('注册快捷键失败:', DevSidecar.api.config.get().app.showHideShortcut)
|
log.error('注册快捷键失败:', DevSidecar.api.config.get().app.showHideShortcut)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('注册快捷键异常:', DevSidecar.api.config.get().app.showHideShortcut, ', error:', e)
|
log.error('注册快捷键异常:', DevSidecar.api.config.get().app.showHideShortcut, ', error:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -359,7 +370,8 @@ app.disableHardwareAcceleration() // 禁用gpu
|
||||||
let startHideWindow = !DevSidecar.api.config.get().app.startShowWindow
|
let startHideWindow = !DevSidecar.api.config.get().app.startShowWindow
|
||||||
if (app.getLoginItemSettings().wasOpenedAsHidden) {
|
if (app.getLoginItemSettings().wasOpenedAsHidden) {
|
||||||
startHideWindow = true
|
startHideWindow = true
|
||||||
} else if (process.argv) {
|
}
|
||||||
|
else if (process.argv) {
|
||||||
const args = minimist(process.argv)
|
const args = minimist(process.argv)
|
||||||
log.info('start args:', args)
|
log.info('start args:', args)
|
||||||
|
|
||||||
|
|
@ -367,7 +379,8 @@ if (app.getLoginItemSettings().wasOpenedAsHidden) {
|
||||||
const hideWindowArg = `${args.hideWindow}`
|
const hideWindowArg = `${args.hideWindow}`
|
||||||
if (hideWindowArg === 'true' || hideWindowArg === '1') {
|
if (hideWindowArg === 'true' || hideWindowArg === '1') {
|
||||||
startHideWindow = true
|
startHideWindow = true
|
||||||
} else if (hideWindowArg === 'false' || hideWindowArg === '0') {
|
}
|
||||||
|
else if (hideWindowArg === 'false' || hideWindowArg === '0') {
|
||||||
startHideWindow = false
|
startHideWindow = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +393,8 @@ if (!isFirstInstance) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
app.quit()
|
app.quit()
|
||||||
}, 1000)
|
}, 1000)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
app.on('before-quit', async () => {
|
app.on('before-quit', async () => {
|
||||||
log.info('before-quit')
|
log.info('before-quit')
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
|
|
@ -414,7 +428,8 @@ if (!isFirstInstance) {
|
||||||
// dock icon is clicked and there are no other windows open.
|
// dock icon is clicked and there are no other windows open.
|
||||||
if (win == null) {
|
if (win == null) {
|
||||||
createWindow(false)
|
createWindow(false)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
showWin()
|
showWin()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -437,14 +452,16 @@ if (!isFirstInstance) {
|
||||||
createWindow(startHideWindow)
|
createWindow(startHideWindow)
|
||||||
const context = { win, app, beforeQuit, quit, ipcMain, dialog, log, api: DevSidecar.api, changeAppConfig }
|
const context = { win, app, beforeQuit, quit, ipcMain, dialog, log, api: DevSidecar.api, changeAppConfig }
|
||||||
backend.install(context) // 模块安装
|
backend.install(context) // 模块安装
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.info('error:', err)
|
log.info('error:', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 最小化到托盘
|
// 最小化到托盘
|
||||||
tray = setTray()
|
tray = setTray()
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
log.info('error:', err)
|
log.info('error:', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -472,7 +489,8 @@ if (isDevelopment) {
|
||||||
quit()
|
quit()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
process.on('SIGINT', () => {
|
process.on('SIGINT', () => {
|
||||||
quit()
|
quit()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ class PowerMonitor {
|
||||||
releaseShutdownBlock()
|
releaseShutdownBlock()
|
||||||
this._shutdownCallback = null
|
this._shutdownCallback = null
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return _powerMonitor.removeAllListeners(event)
|
return _powerMonitor.removeAllListeners(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +51,8 @@ class PowerMonitor {
|
||||||
acquireShutdownBlock('正在停止 DevSidecar 代理')
|
acquireShutdownBlock('正在停止 DevSidecar 代理')
|
||||||
}
|
}
|
||||||
this._listeners.push(listener)
|
this._listeners.push(listener)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return _powerMonitor.on(event, listener)
|
return _powerMonitor.on(event, listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +60,8 @@ class PowerMonitor {
|
||||||
off (event, listener) {
|
off (event, listener) {
|
||||||
if (event === 'shutdown' && process.platform === 'win32') {
|
if (event === 'shutdown' && process.platform === 'win32') {
|
||||||
this._listeners = this._listeners.filter(fn => fn !== listener)
|
this._listeners = this._listeners.filter(fn => fn !== listener)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return _powerMonitor.off(event, listener)
|
return _powerMonitor.off(event, listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +69,8 @@ class PowerMonitor {
|
||||||
once (event, listener) {
|
once (event, listener) {
|
||||||
if (event === 'shutdown' && process.platform === 'win32') {
|
if (event === 'shutdown' && process.platform === 'win32') {
|
||||||
return this.on(event, listener)
|
return this.on(event, listener)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return _powerMonitor.once(event, listener)
|
return _powerMonitor.once(event, listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import DevSidecar from '@docmirror/dev-sidecar'
|
||||||
import { ipcMain } from 'electron'
|
import { ipcMain } from 'electron'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
|
||||||
const pk = require('../../../package.json')
|
|
||||||
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
||||||
|
const pk = require('../../../package.json')
|
||||||
const log = require('../../utils/util.log')
|
const log = require('../../utils/util.log')
|
||||||
|
|
||||||
const mitmproxyPath = path.join(__dirname, 'mitmproxy.js')
|
const mitmproxyPath = path.join(__dirname, 'mitmproxy.js')
|
||||||
|
|
@ -66,7 +66,8 @@ const localApi = {
|
||||||
try {
|
try {
|
||||||
setting = jsonApi.parse(file.toString())
|
setting = jsonApi.parse(file.toString())
|
||||||
log.info('读取 setting.json 成功:', settingPath)
|
log.info('读取 setting.json 成功:', settingPath)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('读取 setting.json 失败:', settingPath, ', error:', e)
|
log.error('读取 setting.json 失败:', settingPath, ', error:', e)
|
||||||
}
|
}
|
||||||
if (setting == null) {
|
if (setting == null) {
|
||||||
|
|
@ -130,7 +131,8 @@ function _deepFindFunction (list, parent, parentKey) {
|
||||||
const item = parent[key]
|
const item = parent[key]
|
||||||
if (item instanceof Function) {
|
if (item instanceof Function) {
|
||||||
list.push(parentKey + key)
|
list.push(parentKey + key)
|
||||||
} else if (item instanceof Object) {
|
}
|
||||||
|
else if (item instanceof Object) {
|
||||||
_deepFindFunction(list, item, `${parentKey + key}.`)
|
_deepFindFunction(list, item, `${parentKey + key}.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +142,8 @@ function _getSettingsPath () {
|
||||||
const dir = getDefaultConfigBasePath()
|
const dir = getDefaultConfigBasePath()
|
||||||
if (!fs.existsSync(dir)) {
|
if (!fs.existsSync(dir)) {
|
||||||
fs.mkdirSync(dir)
|
fs.mkdirSync(dir)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 兼容1.7.3及以下版本的配置文件处理逻辑
|
// 兼容1.7.3及以下版本的配置文件处理逻辑
|
||||||
const newFilePath = path.join(dir, '/setting.json')
|
const newFilePath = path.join(dir, '/setting.json')
|
||||||
const oldFilePath = path.join(dir, '/setting.json5')
|
const oldFilePath = path.join(dir, '/setting.json5')
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ Comment=
|
||||||
EOF
|
EOF
|
||||||
`
|
`
|
||||||
await DevSidecar.api.shell.exec(cmd)
|
await DevSidecar.api.shell.exec(cmd)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const removeStart = 'sudo rm ~/.config/autostart/dev-sidecar.desktop -rf'
|
const removeStart = 'sudo rm ~/.config/autostart/dev-sidecar.desktop -rf'
|
||||||
await DevSidecar.api.shell.exec(removeStart)
|
await DevSidecar.api.shell.exec(removeStart)
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +40,8 @@ export default {
|
||||||
if (message.value) {
|
if (message.value) {
|
||||||
if (isLinux) {
|
if (isLinux) {
|
||||||
await setAutoStartForLinux(app, true)
|
await setAutoStartForLinux(app, true)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
app.setLoginItemSettings({
|
app.setLoginItemSettings({
|
||||||
openAtLogin: true,
|
openAtLogin: true,
|
||||||
openAsHidden: true,
|
openAsHidden: true,
|
||||||
|
|
@ -51,10 +53,12 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
event.sender.send('auto-start', { key: 'enabled', value: true })
|
event.sender.send('auto-start', { key: 'enabled', value: true })
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (isLinux) {
|
if (isLinux) {
|
||||||
await setAutoStartForLinux(app, false)
|
await setAutoStartForLinux(app, false)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
app.setLoginItemSettings({
|
app.setLoginItemSettings({
|
||||||
openAtLogin: false,
|
openAtLogin: false,
|
||||||
openAsHidden: false,
|
openAsHidden: false,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ function install (app, api) {
|
||||||
api.ipc.on('auto-start', (event, message) => {
|
api.ipc.on('auto-start', (event, message) => {
|
||||||
if (message.value === true) {
|
if (message.value === true) {
|
||||||
app.$message.info('已添加开机自启')
|
app.$message.info('已添加开机自启')
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
app.$message.info('已取消开机自启')
|
app.$message.info('已取消开机自启')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ function handleServerStartError (message, err, app, api) {
|
||||||
console.log('Cancel')
|
console.log('Cancel')
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
app.$message.error(`加速服务启动失败:${message.message}`)
|
app.$message.error(`加速服务启动失败:${message.message}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ export default {
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.canceled) {
|
if (result.canceled) {
|
||||||
event.sender.send('file-selector', { key: 'canceled' })
|
event.sender.send('file-selector', { key: 'canceled' })
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
event.sender.send('file-selector', { key: 'selected', value: result.filePaths })
|
event.sender.send('file-selector', { key: 'selected', value: result.filePaths })
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ function install (app, api) {
|
||||||
console.log('selector', message)
|
console.log('selector', message)
|
||||||
if (message.key === 'selected') {
|
if (message.key === 'selected') {
|
||||||
resolve(message.value)
|
resolve(message.value)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
reject(new Error('没有选择文件'))
|
reject(new Error('没有选择文件'))
|
||||||
}
|
}
|
||||||
api.ipc.on('file-selector', () => {})
|
api.ipc.on('file-selector', () => {})
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const server = require('@docmirror/mitmproxy')
|
const server = require('@docmirror/mitmproxy')
|
||||||
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
const jsonApi = require('@docmirror/mitmproxy/src/json')
|
||||||
const log = require('../utils/util.log')
|
const log = require('../utils/util.log')
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import fs from 'fs'
|
import fs from 'node:fs'
|
||||||
import path from 'path'
|
import path from 'node:path'
|
||||||
import DevSidecar from '@docmirror/dev-sidecar'
|
import DevSidecar from '@docmirror/dev-sidecar'
|
||||||
import AdmZip from 'adm-zip'
|
import AdmZip from 'adm-zip'
|
||||||
import { ipcMain } from 'electron'
|
import { ipcMain } from 'electron'
|
||||||
|
|
@ -85,14 +85,16 @@ function isNewVersion (version, curVersion) {
|
||||||
if (versionObj.suffix > curVersionObj.suffix) {
|
if (versionObj.suffix > curVersionObj.suffix) {
|
||||||
return 41
|
return 41
|
||||||
}
|
}
|
||||||
} else if (!versionObj.suffix && curVersionObj.suffix) {
|
}
|
||||||
|
else if (!versionObj.suffix && curVersionObj.suffix) {
|
||||||
// 线上版本号没有后缀版本号,说明为正式版本,为更新版本
|
// 线上版本号没有后缀版本号,说明为正式版本,为更新版本
|
||||||
return 42
|
return 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error(`比对版本失败,当前版本号:${curVersion},比对版本号:${version}, error:`, e)
|
log.error(`比对版本失败,当前版本号:${curVersion},比对版本号:${version}, error:`, e)
|
||||||
return -99
|
return -99
|
||||||
}
|
}
|
||||||
|
|
@ -125,9 +127,11 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
|
||||||
// })
|
// })
|
||||||
if (isMac) {
|
if (isMac) {
|
||||||
autoUpdater.updateConfigPath = path.join(__dirname, 'mac/dev-sidecar.app/Contents/Resources/app-update.yml')
|
autoUpdater.updateConfigPath = path.join(__dirname, 'mac/dev-sidecar.app/Contents/Resources/app-update.yml')
|
||||||
} else if (isLinux) {
|
}
|
||||||
|
else if (isLinux) {
|
||||||
autoUpdater.updateConfigPath = path.join(__dirname, 'linux-unpacked/resources/app-update.yml')
|
autoUpdater.updateConfigPath = path.join(__dirname, 'linux-unpacked/resources/app-update.yml')
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
autoUpdater.updateConfigPath = path.join(__dirname, 'win-unpacked/resources/app-update.yml')
|
autoUpdater.updateConfigPath = path.join(__dirname, 'win-unpacked/resources/app-update.yml')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -159,7 +163,8 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
|
||||||
let data
|
let data
|
||||||
try {
|
try {
|
||||||
data = JSON.parse(body)
|
data = JSON.parse(body)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('检查更新失败,github API返回数据格式不正确:', body)
|
log.error('检查更新失败,github API返回数据格式不正确:', body)
|
||||||
win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: '检查更新失败,github API返回数据格式不正确' })
|
win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: '检查更新失败,github API返回数据格式不正确' })
|
||||||
return
|
return
|
||||||
|
|
@ -206,7 +211,8 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
|
||||||
: '无',
|
: '无',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`检查更新:没有新版本,最近发布的版本号为 '${version}',而当前版本号为 '${curVersion}'`)
|
log.info(`检查更新:没有新版本,最近发布的版本号为 '${version}',而当前版本号为 '${curVersion}'`)
|
||||||
win.webContents.send('update', { key: 'notAvailable' })
|
win.webContents.send('update', { key: 'notAvailable' })
|
||||||
}
|
}
|
||||||
|
|
@ -216,25 +222,29 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
|
||||||
|
|
||||||
log.info('检查更新-没有正式版本数据')
|
log.info('检查更新-没有正式版本数据')
|
||||||
win.webContents.send('update', { key: 'notAvailable' })
|
win.webContents.send('update', { key: 'notAvailable' })
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.error('检查更新失败, status:', response.statusCode, ', body:', body)
|
log.error('检查更新失败, status:', response.statusCode, ', body:', body)
|
||||||
|
|
||||||
let bodyObj
|
let bodyObj
|
||||||
try {
|
try {
|
||||||
bodyObj = JSON.parse(body)
|
bodyObj = JSON.parse(body)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
bodyObj = null
|
bodyObj = null
|
||||||
}
|
}
|
||||||
|
|
||||||
let message
|
let message
|
||||||
if (response) {
|
if (response) {
|
||||||
message = `检查更新失败: ${bodyObj && bodyObj.message ? bodyObj.message : response.message}, code: ${response.statusCode}`
|
message = `检查更新失败: ${bodyObj && bodyObj.message ? bodyObj.message : response.message}, code: ${response.statusCode}`
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
message = `检查更新失败: ${bodyObj && bodyObj.message ? bodyObj.message : body}`
|
message = `检查更新失败: ${bodyObj && bodyObj.message ? bodyObj.message : body}`
|
||||||
}
|
}
|
||||||
win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: message })
|
win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: message })
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('检查更新失败:', e)
|
log.error('检查更新失败:', e)
|
||||||
win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: `检查更新失败:${e.message}` })
|
win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: `检查更新失败:${e.message}` })
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +258,8 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
|
||||||
log.info('download dir:', fileDir)
|
log.info('download dir:', fileDir)
|
||||||
try {
|
try {
|
||||||
fs.accessSync(fileDir, fs.constants.F_OK)
|
fs.accessSync(fileDir, fs.constants.F_OK)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
fs.mkdirSync(fileDir)
|
fs.mkdirSync(fileDir)
|
||||||
}
|
}
|
||||||
const filePath = path.join(fileDir, `${value.version}.zip`)
|
const filePath = path.join(fileDir, `${value.version}.zip`)
|
||||||
|
|
@ -288,7 +299,8 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
|
||||||
const zip = new AdmZip(partPackagePath)
|
const zip = new AdmZip(partPackagePath)
|
||||||
zip.extractAllTo(target, true)
|
zip.extractAllTo(target, true)
|
||||||
log.info('安装完成,重启app')
|
log.info('安装完成,重启app')
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
app.exit(0)
|
app.exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -339,18 +351,21 @@ function updateHandle (app, api, win, beforeQuit, quit, log) {
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if (arg.key === 'checkForUpdate') {
|
}
|
||||||
|
else if (arg.key === 'checkForUpdate') {
|
||||||
// 执行自动更新检查
|
// 执行自动更新检查
|
||||||
log.info('autoUpdater checkForUpdates:', arg.fromUser)
|
log.info('autoUpdater checkForUpdates:', arg.fromUser)
|
||||||
|
|
||||||
// 调用 github API,获取release数据,来检查更新
|
// 调用 github API,获取release数据,来检查更新
|
||||||
// autoUpdater.checkForUpdates()
|
// autoUpdater.checkForUpdates()
|
||||||
checkForUpdatesFromGitHub()
|
checkForUpdatesFromGitHub()
|
||||||
} else if (arg.key === 'downloadUpdate') {
|
}
|
||||||
|
else if (arg.key === 'downloadUpdate') {
|
||||||
// 下载新版本
|
// 下载新版本
|
||||||
log.info('autoUpdater downloadUpdate')
|
log.info('autoUpdater downloadUpdate')
|
||||||
autoUpdater.downloadUpdate()
|
autoUpdater.downloadUpdate()
|
||||||
} else if (arg.key === 'downloadPart') {
|
}
|
||||||
|
else if (arg.key === 'downloadPart') {
|
||||||
// 下载增量更新版本
|
// 下载增量更新版本
|
||||||
log.info('autoUpdater downloadPart')
|
log.info('autoUpdater downloadPart')
|
||||||
downloadPart(app, arg.value)
|
downloadPart(app, arg.value)
|
||||||
|
|
|
||||||
|
|
@ -31,23 +31,28 @@ function install (app, api) {
|
||||||
updateParams.checking = false
|
updateParams.checking = false
|
||||||
updateParams.newVersionData = message.value
|
updateParams.newVersionData = message.value
|
||||||
foundNewVersion(message.value)
|
foundNewVersion(message.value)
|
||||||
} else if (type === 'notAvailable') {
|
}
|
||||||
|
else if (type === 'notAvailable') {
|
||||||
updateParams.checking = false
|
updateParams.checking = false
|
||||||
noNewVersion()
|
noNewVersion()
|
||||||
} else if (type === 'downloaded') {
|
}
|
||||||
|
else if (type === 'downloaded') {
|
||||||
// 更新包已下载完成,让用户确认是否更新
|
// 更新包已下载完成,让用户确认是否更新
|
||||||
updateParams.downloading = false
|
updateParams.downloading = false
|
||||||
console.log('updateParams', updateParams)
|
console.log('updateParams', updateParams)
|
||||||
newUpdateIsReady(message.value)
|
newUpdateIsReady(message.value)
|
||||||
} else if (type === 'progress') {
|
}
|
||||||
|
else if (type === 'progress') {
|
||||||
progressUpdate(message.value)
|
progressUpdate(message.value)
|
||||||
} else if (type === 'error') {
|
}
|
||||||
|
else if (type === 'error') {
|
||||||
updateParams.checking = false
|
updateParams.checking = false
|
||||||
updateParams.downloading = false
|
updateParams.downloading = false
|
||||||
if (message.action === 'checkForUpdate' && updateParams.newVersionData) {
|
if (message.action === 'checkForUpdate' && updateParams.newVersionData) {
|
||||||
// 如果检查更新报错了,但刚才成功拿到过一次数据,就拿之前的数据
|
// 如果检查更新报错了,但刚才成功拿到过一次数据,就拿之前的数据
|
||||||
foundNewVersion(updateParams.newVersionData)
|
foundNewVersion(updateParams.newVersionData)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (updateParams.fromUser === false && message.action === 'checkForUpdate') {
|
if (updateParams.fromUser === false && message.action === 'checkForUpdate') {
|
||||||
return // 不是手动检查更新,不提示错误信息,避免打扰
|
return // 不是手动检查更新,不提示错误信息,避免打扰
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +88,12 @@ function install (app, api) {
|
||||||
content: (h) => {
|
content: (h) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>请前往 <a onClick={openGithubUrl}>github项目release页面</a> 下载新版本手动安装</div>
|
<div>
|
||||||
|
请前往
|
||||||
|
<a onClick={openGithubUrl}>github项目release页面</a>
|
||||||
|
{' '}
|
||||||
|
下载新版本手动安装
|
||||||
|
</div>
|
||||||
<div><a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a></div>
|
<div><a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a></div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -154,20 +164,27 @@ function install (app, api) {
|
||||||
const releaseNotes = value.releaseNotes.replace(/\r\n/g, '\n')
|
const releaseNotes = value.releaseNotes.replace(/\r\n/g, '\n')
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>发布公告:<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a></div>
|
<div>
|
||||||
|
发布公告:
|
||||||
|
<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a>
|
||||||
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<pre style="max-height:350px;font-family:auto">
|
<pre style="max-height:350px;font-family:auto">
|
||||||
{releaseNotes}
|
{releaseNotes}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
for (const note of value.releaseNotes) {
|
for (const note of value.releaseNotes) {
|
||||||
notes.push(<li>{note}</li>)
|
notes.push(<li>{note}</li>)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>发布公告:<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a></div>
|
<div>
|
||||||
|
发布公告:
|
||||||
|
<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a>
|
||||||
|
</div>
|
||||||
<div>更新内容:</div>
|
<div>更新内容:</div>
|
||||||
<ol>{notes}</ol>
|
<ol>{notes}</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -200,20 +217,27 @@ function install (app, api) {
|
||||||
const releaseNotes = value.releaseNotes.replace(/\r\n/g, '\n')
|
const releaseNotes = value.releaseNotes.replace(/\r\n/g, '\n')
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>发布公告:<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a></div>
|
<div>
|
||||||
|
发布公告:
|
||||||
|
<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a>
|
||||||
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<pre style="max-height:350px;font-family:auto">
|
<pre style="max-height:350px;font-family:auto">
|
||||||
{releaseNotes}
|
{releaseNotes}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
for (const note of value.releaseNotes) {
|
for (const note of value.releaseNotes) {
|
||||||
notes.push(<li>{note}</li>)
|
notes.push(<li>{note}</li>)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>发布公告:<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a></div>
|
<div>
|
||||||
|
发布公告:
|
||||||
|
<a onClick={openGithubUrl}>https://github.com/docmirror/dev-sidecar/releases</a>
|
||||||
|
</div>
|
||||||
<div>更新内容:</div>
|
<div>更新内容:</div>
|
||||||
<ol>{notes}</ol>
|
<ol>{notes}</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import os from 'os'
|
import os from 'node:os'
|
||||||
import path from 'path'
|
import path from 'node:path'
|
||||||
|
|
||||||
function getSystemPlatform () {
|
function getSystemPlatform () {
|
||||||
switch (os.platform()) {
|
switch (os.platform()) {
|
||||||
|
|
|
||||||
|
|
@ -88,17 +88,17 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
body{
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.mt10{
|
.mt10 {
|
||||||
margin-top:10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
.mt5{
|
.mt5 {
|
||||||
margin-top:5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
.mt20{
|
.mt20 {
|
||||||
margin-top:20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
.ds_layout {
|
.ds_layout {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
|
@ -106,31 +106,33 @@ body{
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.ant-layout-has-sider{
|
.ant-layout-has-sider {
|
||||||
border:1px solid #eee;
|
border: 1px solid #eee;
|
||||||
}
|
}
|
||||||
.ant-layout-sider-children{
|
.ant-layout-sider-children {
|
||||||
border-right:1px solid #eee;
|
border-right: 1px solid #eee;
|
||||||
}
|
}
|
||||||
.ant-layout{
|
.ant-layout {
|
||||||
height:100%
|
height: 100%;
|
||||||
}
|
}
|
||||||
.logo{
|
.logo {
|
||||||
padding:5px;
|
padding: 5px;
|
||||||
border-bottom: #eee solid 1px;
|
border-bottom: #eee solid 1px;
|
||||||
height:60px;
|
height: 60px;
|
||||||
background-image: url("../../public/logo/logo-lang.svg");
|
background-image: url('../../public/logo/logo-lang.svg');
|
||||||
background-size: auto 50px;
|
background-size: auto 50px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 5px center;
|
background-position: 5px center;
|
||||||
}
|
}
|
||||||
.ant-layout-footer{
|
.ant-layout-footer {
|
||||||
padding:10px;
|
padding: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-top:#d6d4d4 solid 1px;
|
border-top: #d6d4d4 solid 1px;
|
||||||
}
|
}
|
||||||
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left{
|
.ant-menu-inline,
|
||||||
border:0;
|
.ant-menu-vertical,
|
||||||
|
.ant-menu-vertical-left {
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,27 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div class="ds-container">
|
<div class="ds-container">
|
||||||
<div class="body-wrapper">
|
<div class="body-wrapper">
|
||||||
<div v-if="$slots.header" class="container-header"><slot name="header" /></div>
|
<div v-if="$slots.header" class="container-header">
|
||||||
<div class="container-body"><slot /></div>
|
<slot name="header" />
|
||||||
<div class="container-footer"><slot name="footer" /></div>
|
</div>
|
||||||
|
<div class="container-body">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
<div class="container-footer">
|
||||||
|
<slot name="footer" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.ds-container{
|
.ds-container {
|
||||||
height:100%;
|
height: 100%;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.body-wrapper{
|
.body-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
|
|
@ -32,21 +38,21 @@ export default {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container-header{
|
.container-header {
|
||||||
padding:15px;
|
padding: 15px;
|
||||||
border-bottom: 1px solid #EEE;
|
border-bottom: 1px solid #eee;
|
||||||
background: #FFF;
|
background: #fff;
|
||||||
height:60px;
|
height: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.container-body{
|
.container-body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 0;
|
height: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding:15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,11 @@ export default {
|
||||||
setupImage () {
|
setupImage () {
|
||||||
if (this.systemPlatform === 'mac') {
|
if (this.systemPlatform === 'mac') {
|
||||||
return '/setup-mac.png'
|
return '/setup-mac.png'
|
||||||
} else if (this.systemPlatform === 'linux') {
|
}
|
||||||
|
else if (this.systemPlatform === 'linux') {
|
||||||
return '/setup-linux.png'
|
return '/setup-linux.png'
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return '/setup.png'
|
return '/setup.png'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ export default {
|
||||||
await this.applyBefore()
|
await this.applyBefore()
|
||||||
await this.saveConfig()
|
await this.saveConfig()
|
||||||
await this.applyAfter()
|
await this.applyAfter()
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
this.applyLoading = false
|
this.applyLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -73,7 +74,8 @@ export default {
|
||||||
await this.ready(this.config)
|
await this.ready(this.config)
|
||||||
}
|
}
|
||||||
await this.apply()
|
await this.apply()
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
this.resetDefaultLoading = false
|
this.resetDefaultLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -125,7 +127,8 @@ export default {
|
||||||
await this.$api.plugin.git.start()
|
await this.$api.plugin.git.start()
|
||||||
}
|
}
|
||||||
this.$message.success('代理服务和系统代理重启成功')
|
this.$message.success('代理服务和系统代理重启成功')
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.$message.info('代理服务和系统代理未启动,无需重启')
|
this.$message.info('代理服务和系统代理未启动,无需重启')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ export default {
|
||||||
doClick: () => {
|
doClick: () => {
|
||||||
if (this.status.server.enabled) {
|
if (this.status.server.enabled) {
|
||||||
this.apiCall(this.startup, this.$api.shutdown)
|
this.apiCall(this.startup, this.$api.shutdown)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.apiCall(this.startup, this.$api.startup)
|
this.apiCall(this.startup, this.$api.startup)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -75,11 +76,13 @@ export default {
|
||||||
this.config.server.intercept.enabled = false
|
this.config.server.intercept.enabled = false
|
||||||
this.config.server.dns.speedTest.enabled = true
|
this.config.server.dns.speedTest.enabled = true
|
||||||
this.config.plugin.overwall.enabled = false
|
this.config.plugin.overwall.enabled = false
|
||||||
} else if (mode === 'default') {
|
}
|
||||||
|
else if (mode === 'default') {
|
||||||
this.config.server.intercept.enabled = true
|
this.config.server.intercept.enabled = true
|
||||||
this.config.server.dns.speedTest.enabled = true
|
this.config.server.dns.speedTest.enabled = true
|
||||||
this.config.plugin.overwall.enabled = false
|
this.config.plugin.overwall.enabled = false
|
||||||
} else if (mode === 'ow') {
|
}
|
||||||
|
else if (mode === 'ow') {
|
||||||
console.log('event', event)
|
console.log('event', event)
|
||||||
if (!this.setting.overwall) {
|
if (!this.setting.overwall) {
|
||||||
this.wantOW()
|
this.wantOW()
|
||||||
|
|
@ -201,10 +204,12 @@ export default {
|
||||||
const ret = await api(param)
|
const ret = await api(param)
|
||||||
console.log('this status', this.status)
|
console.log('this status', this.status)
|
||||||
return ret
|
return ret
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
btn.loading = false // 有时候记录日志会卡死,先设置为false
|
btn.loading = false // 有时候记录日志会卡死,先设置为false
|
||||||
console.log('api invoke error:', err)
|
console.log('api invoke error:', err)
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
btn.loading = false
|
btn.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -212,7 +217,8 @@ export default {
|
||||||
onSwitchClick (btn, openApi, closeApi, checked) {
|
onSwitchClick (btn, openApi, closeApi, checked) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
return this.apiCall(btn, openApi)
|
return this.apiCall(btn, openApi)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return this.apiCall(btn, closeApi)
|
return this.apiCall(btn, closeApi)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -386,7 +392,7 @@ export default {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding:10px;
|
padding: 10px;
|
||||||
.donate {
|
.donate {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ export default {
|
||||||
if (this.status.plugin.git.enabled) {
|
if (this.status.plugin.git.enabled) {
|
||||||
await this.$api.plugin.git.close()
|
await this.$api.plugin.git.close()
|
||||||
this.needRestart = true
|
this.needRestart = true
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.needRestart = false
|
this.needRestart = false
|
||||||
}
|
}
|
||||||
this.submitNoProxyUrls()
|
this.submitNoProxyUrls()
|
||||||
|
|
@ -115,8 +116,12 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<div class="footer-bar">
|
<div class="footer-bar">
|
||||||
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">恢复默认</a-button>
|
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">
|
||||||
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">应用</a-button>
|
恢复默认
|
||||||
|
</a-button>
|
||||||
|
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">
|
||||||
|
应用
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ds-container>
|
</ds-container>
|
||||||
|
|
|
||||||
|
|
@ -136,8 +136,12 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<div class="footer-bar">
|
<div class="footer-bar">
|
||||||
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">恢复默认</a-button>
|
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">
|
||||||
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">应用</a-button>
|
恢复默认
|
||||||
|
</a-button>
|
||||||
|
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">
|
||||||
|
应用
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ds-container>
|
</ds-container>
|
||||||
|
|
|
||||||
|
|
@ -213,8 +213,12 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<div class="footer-bar">
|
<div class="footer-bar">
|
||||||
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">恢复默认</a-button>
|
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">
|
||||||
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">应用</a-button>
|
恢复默认
|
||||||
|
</a-button>
|
||||||
|
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">
|
||||||
|
应用
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ds-container>
|
</ds-container>
|
||||||
|
|
|
||||||
|
|
@ -120,8 +120,12 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<div class="footer-bar">
|
<div class="footer-bar">
|
||||||
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">恢复默认</a-button>
|
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">
|
||||||
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">应用</a-button>
|
恢复默认
|
||||||
|
</a-button>
|
||||||
|
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">
|
||||||
|
应用
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ds-container>
|
</ds-container>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ export default {
|
||||||
async openEnableLoopback () {
|
async openEnableLoopback () {
|
||||||
try {
|
try {
|
||||||
await this.$api.proxy.setEnableLoopback()
|
await this.$api.proxy.setEnableLoopback()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
if (e.message.includes('EACCES')) {
|
if (e.message.includes('EACCES')) {
|
||||||
this.$message.error('请将DevSidecar关闭后,以管理员身份重新打开,再尝试此操作')
|
this.$message.error('请将DevSidecar关闭后,以管理员身份重新打开,再尝试此操作')
|
||||||
return
|
return
|
||||||
|
|
@ -113,7 +114,9 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="isWindows()" label="设置loopback" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form-item v-if="isWindows()" label="设置loopback" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
<a-button @click="loopbackVisible = true">去设置</a-button>
|
<a-button @click="loopbackVisible = true">
|
||||||
|
去设置
|
||||||
|
</a-button>
|
||||||
<div class="form-help">
|
<div class="form-help">
|
||||||
解决<code>OneNote</code>、<code>MicrosoftStore</code>、<code>Outlook</code>等<code>UWP应用</code>开启代理后无法访问网络的问题
|
解决<code>OneNote</code>、<code>MicrosoftStore</code>、<code>Outlook</code>等<code>UWP应用</code>开启代理后无法访问网络的问题
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -162,8 +165,12 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<div class="footer-bar">
|
<div class="footer-bar">
|
||||||
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">恢复默认</a-button>
|
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">
|
||||||
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">应用</a-button>
|
恢复默认
|
||||||
|
</a-button>
|
||||||
|
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">
|
||||||
|
应用
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -179,7 +186,9 @@ export default {
|
||||||
>
|
>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
设置Loopback
|
设置Loopback
|
||||||
<a-button style="float:right;margin-right:10px;" @click="openEnableLoopback()">打开EnableLoopback</a-button>
|
<a-button style="float:right;margin-right:10px;" @click="openEnableLoopback()">
|
||||||
|
打开EnableLoopback
|
||||||
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<div>
|
||||||
<div>1、此设置用于解决OneNote、MicrosoftStore、Outlook等UWP应用无法访问网络的问题。</div>
|
<div>1、此设置用于解决OneNote、MicrosoftStore、Outlook等UWP应用无法访问网络的问题。</div>
|
||||||
|
|
|
||||||
|
|
@ -407,8 +407,12 @@ export default {
|
||||||
<a-divider />
|
<a-divider />
|
||||||
<a-row :gutter="10" class="mt10">
|
<a-row :gutter="10" class="mt10">
|
||||||
<a-col span="24">
|
<a-col span="24">
|
||||||
<a-button type="primary" icon="plus" @click="reSpeedTest()">立即重新测速</a-button>
|
<a-button type="primary" icon="plus" @click="reSpeedTest()">
|
||||||
<a-button class="md-ml-10" type="primary" icon="reload" @click="reloadAllSpeedTester()">刷新</a-button>
|
立即重新测速
|
||||||
|
</a-button>
|
||||||
|
<a-button class="md-ml-10" type="primary" icon="reload" @click="reloadAllSpeedTester()">
|
||||||
|
刷新
|
||||||
|
</a-button>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
|
|
@ -434,8 +438,12 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<div class="footer-bar">
|
<div class="footer-bar">
|
||||||
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">恢复默认</a-button>
|
<a-button :loading="resetDefaultLoading" class="md-mr-10" icon="sync" @click="resetDefault()">
|
||||||
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">应用</a-button>
|
恢复默认
|
||||||
|
</a-button>
|
||||||
|
<a-button :loading="applyLoading" icon="check" type="primary" @click="apply()">
|
||||||
|
应用
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ds-container>
|
</ds-container>
|
||||||
|
|
@ -454,7 +462,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-vue {
|
.jsoneditor-vue {
|
||||||
height: 100%
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-tabs {
|
.ant-tabs {
|
||||||
|
|
|
||||||
|
|
@ -218,10 +218,12 @@ export default {
|
||||||
await this.$api.config.downloadRemoteConfig()
|
await this.$api.config.downloadRemoteConfig()
|
||||||
this.$message.info('下载远程配置成功,开始重启代理服务和系统代理')
|
this.$message.info('下载远程配置成功,开始重启代理服务和系统代理')
|
||||||
await this.reloadConfigAndRestart()
|
await this.reloadConfigAndRestart()
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
this.reloadLoading = false
|
this.reloadLoading = false
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.$message.info('远程配置已关闭,开始重启代理服务和系统代理')
|
this.$message.info('远程配置已关闭,开始重启代理服务和系统代理')
|
||||||
await this.reloadConfigAndRestart()
|
await this.reloadConfigAndRestart()
|
||||||
}
|
}
|
||||||
|
|
@ -244,11 +246,13 @@ export default {
|
||||||
if (remoteConfig.old1 === remoteConfig.new1 && remoteConfig.old2 === remoteConfig.new2) {
|
if (remoteConfig.old1 === remoteConfig.new1 && remoteConfig.old2 === remoteConfig.new2) {
|
||||||
this.$message.info('远程配置没有变化,不做任何处理。')
|
this.$message.info('远程配置没有变化,不做任何处理。')
|
||||||
this.$message.warn('如果您确实修改了远程配置,请稍等片刻再重试!')
|
this.$message.warn('如果您确实修改了远程配置,请稍等片刻再重试!')
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.$message.success('获取到了最新的远程配置,开始重启代理服务和系统代理')
|
this.$message.success('获取到了最新的远程配置,开始重启代理服务和系统代理')
|
||||||
await this.reloadConfigAndRestart()
|
await this.reloadConfigAndRestart()
|
||||||
}
|
}
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
this.reloadLoading = false
|
this.reloadLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -256,7 +260,7 @@ export default {
|
||||||
this.$confirm({
|
this.$confirm({
|
||||||
title: '确定要恢复出厂设置吗?',
|
title: '确定要恢复出厂设置吗?',
|
||||||
width: 610,
|
width: 610,
|
||||||
content: (h) => (
|
content: h => (
|
||||||
<div class="restore-factory-settings">
|
<div class="restore-factory-settings">
|
||||||
<hr />
|
<hr />
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -276,7 +280,9 @@ export default {
|
||||||
1. 找到备份文件,路径:
|
1. 找到备份文件,路径:
|
||||||
<span>~/.dev-sidecar/config.json.时间戳.bak.json</span>
|
<span>~/.dev-sidecar/config.json.时间戳.bak.json</span>
|
||||||
<br />
|
<br />
|
||||||
2. 将该备份文件重命名为<span>config.json</span>,再重启软件即可恢复个性化配置。
|
2. 将该备份文件重命名为
|
||||||
|
<span>config.json</span>
|
||||||
|
,再重启软件即可恢复个性化配置。
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -291,10 +297,12 @@ export default {
|
||||||
this.config = await this.$api.config.get()
|
this.config = await this.$api.config.get()
|
||||||
this.$message.success('恢复出厂设置成功,开始重启代理服务和系统代理')
|
this.$message.success('恢复出厂设置成功,开始重启代理服务和系统代理')
|
||||||
await this.reloadConfigAndRestart()
|
await this.reloadConfigAndRestart()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.$message.info('已是出厂设置,无需恢复')
|
this.$message.info('已是出厂设置,无需恢复')
|
||||||
}
|
}
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
this.removeUserConfigLoading = false
|
this.removeUserConfigLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -316,7 +324,9 @@ export default {
|
||||||
<a-checkbox v-model="config.app.autoStart.enabled" @change="onAutoStartChange">
|
<a-checkbox v-model="config.app.autoStart.enabled" @change="onAutoStartChange">
|
||||||
本应用开机自启
|
本应用开机自启
|
||||||
</a-checkbox>
|
</a-checkbox>
|
||||||
<a-button class="md-mr-10" icon="profile" @click="openLog()">日志</a-button>
|
<a-button class="md-mr-10" icon="profile" @click="openLog()">
|
||||||
|
日志
|
||||||
|
</a-button>
|
||||||
<div class="form-help">
|
<div class="form-help">
|
||||||
windows下建议开启开机自启。<a @click="openExternal('https://github.com/docmirror/dev-sidecar/blob/master/doc/recover.md')">更多说明参考</a>
|
windows下建议开启开机自启。<a @click="openExternal('https://github.com/docmirror/dev-sidecar/blob/master/doc/recover.md')">更多说明参考</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,93 @@
|
||||||
.footer-bar{
|
.footer-bar {
|
||||||
padding:10px;
|
padding: 10px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
border-top:#eee 1px solid;
|
border-top: #eee 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-l-r{
|
.flex-l-r {
|
||||||
align-content: center;
|
align-content: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
&>a{
|
& > a {
|
||||||
align-content: center;
|
align-content: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.md-mr-5{margin-right: 5px;}
|
.md-mr-5 {
|
||||||
.md-mr-10{margin-right: 10px;}
|
margin-right: 5px;
|
||||||
.md-mr-15{margin-right: 15px;}
|
}
|
||||||
.md-mr-20{margin-right: 20px;}
|
.md-mr-10 {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.md-mr-15 {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
.md-mr-20 {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.md-mt-5{margin-top: 5px;}
|
.md-mt-5 {
|
||||||
.md-mt-10{margin-top: 10px;}
|
margin-top: 5px;
|
||||||
.md-mt-15{margin-top: 15px;}
|
}
|
||||||
.md-mt-20{margin-top: 20px;}
|
.md-mt-10 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.md-mt-15 {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
.md-mt-20 {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-ml-5 {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.md-ml-10 {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.md-ml-15 {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
.md-ml-20 {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.md-ml-5{margin-left: 5px;}
|
.md-mb-5 {
|
||||||
.md-ml-10{margin-left: 10px;}
|
margin-bottom: 5px;
|
||||||
.md-ml-15{margin-left: 15px;}
|
}
|
||||||
.md-ml-20{margin-left: 20px;}
|
.md-mb-10 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.md-mb-15 {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.md-mb-20 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.md-mb-5{margin-bottom: 5px;}
|
ol {
|
||||||
.md-mb-10{margin-bottom: 10px;}
|
|
||||||
.md-mb-15{margin-bottom: 15px;}
|
|
||||||
.md-mb-20{margin-bottom: 20px;}
|
|
||||||
|
|
||||||
ol{
|
|
||||||
margin-block-start: 0em;
|
margin-block-start: 0em;
|
||||||
margin-block-end: 0em;
|
margin-block-end: 0em;
|
||||||
padding-inline-start: 20px;
|
padding-inline-start: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-help{
|
.form-help {
|
||||||
font-size:12px;
|
font-size: 12px;
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
color: #a1a1a1;
|
color: #a1a1a1;
|
||||||
|
|
||||||
i{
|
i {
|
||||||
font-family: "Microsoft YaHei", serif;
|
font-family: 'Microsoft YaHei', serif;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
padding: 0 .4em;
|
padding: 0 0.4em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,13 +97,13 @@ code {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: #888;
|
color: #888;
|
||||||
background-color: #f1f1f1;
|
background-color: #f1f1f1;
|
||||||
margin-left: .2em;
|
margin-left: 0.2em;
|
||||||
margin-right: .2em;
|
margin-right: 0.2em;
|
||||||
padding: .2em .4em;
|
padding: 0.2em 0.4em;
|
||||||
white-space: break-spaces;
|
white-space: break-spaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_search_form .ace_searchbtn{
|
.ace_search_form .ace_searchbtn {
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 27px;
|
min-width: 27px;
|
||||||
}
|
}
|
||||||
|
|
@ -106,4 +137,4 @@ hr {
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
margin: 0 5px 5px 5px;
|
margin: 0 5px 5px 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,28 @@
|
||||||
/* 暗色主题 */
|
/* 暗色主题 */
|
||||||
$dark-logo: url("../../../../public/logo/logo-lang-light.svg");
|
$dark-logo: url('../../../../public/logo/logo-lang-light.svg');
|
||||||
$dark-bg: #1e1f22; //背景
|
$dark-bg: #1e1f22; //背景
|
||||||
$dark-bg-highlight: #333; //高亮块:背景
|
$dark-bg-highlight: #333; //高亮块:背景
|
||||||
$dark-text: #ddd; //字体颜色
|
$dark-text: #ddd; //字体颜色
|
||||||
$dark-bd: #333; //边框和分隔线
|
$dark-bd: #333; //边框和分隔线
|
||||||
$dark-btn: #444; //按钮:边框和背景颜色
|
$dark-btn: #444; //按钮:边框和背景颜色
|
||||||
$dark-input: #777; //输入框:背景色
|
$dark-input: #777; //输入框:背景色
|
||||||
.theme-dark{
|
.theme-dark {
|
||||||
hr {
|
hr {
|
||||||
border-color: $dark-bd;
|
border-color: $dark-bd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 背景色和字体颜色 */
|
/* 背景色和字体颜色 */
|
||||||
.ds_layout, .ant-layout,
|
.ds_layout,
|
||||||
.ds-container, .ds-container .container-header,
|
.ant-layout,
|
||||||
.ant-layout-footer{
|
.ds-container,
|
||||||
|
.ds-container .container-header,
|
||||||
|
.ant-layout-footer {
|
||||||
background: $dark-bg;
|
background: $dark-bg;
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
}
|
}
|
||||||
div, span, label {
|
div,
|
||||||
|
span,
|
||||||
|
label {
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
}
|
}
|
||||||
.form-help {
|
.form-help {
|
||||||
|
|
@ -31,7 +35,7 @@ $dark-input: #777; //输入框:背景色
|
||||||
|
|
||||||
/* 高亮块:背景色和字体颜色 */
|
/* 高亮块:背景色和字体颜色 */
|
||||||
/* 警告类型 */
|
/* 警告类型 */
|
||||||
.ant-alert-warning{
|
.ant-alert-warning {
|
||||||
background: $dark-bg-highlight;
|
background: $dark-bg-highlight;
|
||||||
border-color: $dark-bg-highlight;
|
border-color: $dark-bg-highlight;
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
|
|
@ -41,7 +45,7 @@ $dark-input: #777; //输入框:背景色
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* 消息类型 */
|
/* 消息类型 */
|
||||||
.ant-alert-info{
|
.ant-alert-info {
|
||||||
background: $dark-bg-highlight;
|
background: $dark-bg-highlight;
|
||||||
border-color: $dark-bg-highlight;
|
border-color: $dark-bg-highlight;
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
|
|
@ -55,7 +59,7 @@ $dark-input: #777; //输入框:背景色
|
||||||
.footer-bar,
|
.footer-bar,
|
||||||
.ant-layout-footer,
|
.ant-layout-footer,
|
||||||
.ant-tabs .ant-tabs-left-bar,
|
.ant-tabs .ant-tabs-left-bar,
|
||||||
.ant-tabs .ant-tabs-left-content{
|
.ant-tabs .ant-tabs-left-content {
|
||||||
border-color: $dark-bd;
|
border-color: $dark-bd;
|
||||||
}
|
}
|
||||||
.ant-radio-button-wrapper:not(:first-child)::before {
|
.ant-radio-button-wrapper:not(:first-child)::before {
|
||||||
|
|
@ -67,138 +71,146 @@ $dark-input: #777; //输入框:背景色
|
||||||
|
|
||||||
/* 左侧 */
|
/* 左侧 */
|
||||||
/** 背景色 **/
|
/** 背景色 **/
|
||||||
.ant-layout-sider{
|
.ant-layout-sider {
|
||||||
background: $dark-bg;
|
background: $dark-bg;
|
||||||
}
|
}
|
||||||
/** Logo **/
|
/** Logo **/
|
||||||
.logo{
|
.logo {
|
||||||
background-image: $dark-logo; /* logo使用亮色的 */
|
background-image: $dark-logo; /* logo使用亮色的 */
|
||||||
}
|
}
|
||||||
/** 菜单 **/
|
/** 菜单 **/
|
||||||
.ant-menu{
|
.ant-menu {
|
||||||
background: $dark-bg;
|
background: $dark-bg;
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
}
|
}
|
||||||
/* 菜单选中时,或鼠标移到菜单上时的样式 */
|
/* 菜单选中时,或鼠标移到菜单上时的样式 */
|
||||||
.ant-menu-item:hover,
|
.ant-menu-item:hover,
|
||||||
.ant-menu-submenu .ant-menu-submenu-title:hover,
|
.ant-menu-submenu .ant-menu-submenu-title:hover,
|
||||||
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{
|
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
|
||||||
background: $dark-bg-highlight;
|
background: $dark-bg-highlight;
|
||||||
color: #1890ff;
|
color: #1890ff;
|
||||||
span{ color: #1890ff; }
|
span {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 输入框、下拉框 */
|
/* 输入框、下拉框 */
|
||||||
.ant-input,
|
.ant-input,
|
||||||
.ant-input-number-input, .ant-input-number,
|
.ant-input-number-input,
|
||||||
|
.ant-input-number,
|
||||||
.ant-select-selection,
|
.ant-select-selection,
|
||||||
.ant-input-group-addon{
|
.ant-input-group-addon {
|
||||||
background: $dark-input;
|
background: $dark-input;
|
||||||
border-color: #aaa;
|
border-color: #aaa;
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
&:hover, &:focus{
|
&:hover,
|
||||||
|
&:focus {
|
||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 卡片消息:IP测速 */
|
/* 卡片消息:IP测速 */
|
||||||
.ant-card{
|
.ant-card {
|
||||||
background: $dark-input;
|
background: $dark-input;
|
||||||
border-color: $dark-input;
|
border-color: $dark-input;
|
||||||
.ant-card-head{
|
.ant-card-head {
|
||||||
border-bottom-color: #929292;
|
border-bottom-color: #929292;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 标签:未启用 */
|
/* 标签:未启用 */
|
||||||
.ant-tag-red{
|
.ant-tag-red {
|
||||||
background: #4f4749;
|
background: #4f4749;
|
||||||
border-color: #4f4749;
|
border-color: #4f4749;
|
||||||
color: #bf8285;
|
color: #bf8285;
|
||||||
}
|
}
|
||||||
/* 标签:已启用 */
|
/* 标签:已启用 */
|
||||||
.ant-tag-green{
|
.ant-tag-green {
|
||||||
background: #505f5f;
|
background: #505f5f;
|
||||||
border-color: #505f5f;
|
border-color: #505f5f;
|
||||||
color: #90cb9f;
|
color: #90cb9f;
|
||||||
}
|
}
|
||||||
/* 标签:警告 */
|
/* 标签:警告 */
|
||||||
.ant-tag-orange{
|
.ant-tag-orange {
|
||||||
background: #5a5750;
|
background: #5a5750;
|
||||||
border-color: #5a5750;
|
border-color: #5a5750;
|
||||||
color: #cfa572;
|
color: #cfa572;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 按钮 */
|
/* 按钮 */
|
||||||
.ant-btn:not(.ant-btn-danger, .ant-btn-primary){
|
.ant-btn:not(.ant-btn-danger, .ant-btn-primary) {
|
||||||
background: $dark-btn;
|
background: $dark-btn;
|
||||||
border-color: $dark-btn;
|
border-color: $dark-btn;
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
&:hover{
|
&:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 单选框:开关式 */
|
/* 单选框:开关式 */
|
||||||
.ant-switch:not(.ant-switch-checked){
|
.ant-switch:not(.ant-switch-checked) {
|
||||||
background: $dark-btn;
|
background: $dark-btn;
|
||||||
border-color: $dark-btn;
|
border-color: $dark-btn;
|
||||||
&:hover{
|
&:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* 单选框:按钮式 */
|
/* 单选框:按钮式 */
|
||||||
.ant-radio-button-wrapper{
|
.ant-radio-button-wrapper {
|
||||||
background: $dark-btn;
|
background: $dark-btn;
|
||||||
border-color: $dark-btn;
|
border-color: $dark-btn;
|
||||||
color: $dark-text;
|
color: $dark-text;
|
||||||
&:hover{
|
&:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* JSON编辑器:应用于拦截设置 */
|
/* JSON编辑器:应用于拦截设置 */
|
||||||
.jsoneditor-vue{
|
.jsoneditor-vue {
|
||||||
/*整个编辑框:背景色和边框*/
|
/*整个编辑框:背景色和边框*/
|
||||||
div.jsoneditor{
|
div.jsoneditor {
|
||||||
background: $dark-bg-highlight;
|
background: $dark-bg-highlight;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
/* 头部菜单栏:边框 */
|
/* 头部菜单栏:边框 */
|
||||||
div.jsoneditor-menu{
|
div.jsoneditor-menu {
|
||||||
background: $dark-bg-highlight;
|
background: $dark-bg-highlight;
|
||||||
border-color: $dark-bg-highlight;
|
border-color: $dark-bg-highlight;
|
||||||
}
|
}
|
||||||
/* 内容区域左边:行号 */
|
/* 内容区域左边:行号 */
|
||||||
.ace_gutter{
|
.ace_gutter {
|
||||||
background: #444;
|
background: #444;
|
||||||
.ace_gutter-cell { color: #aaa; }
|
.ace_gutter-cell {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* 内容区域右边:JSON内容 */
|
/* 内容区域右边:JSON内容 */
|
||||||
.ace_scroller{
|
.ace_scroller {
|
||||||
background: #555;
|
background: #555;
|
||||||
}
|
}
|
||||||
/* key的颜色 */
|
/* key的颜色 */
|
||||||
.ace_variable, .ace_text-layer{
|
.ace_variable,
|
||||||
|
.ace_text-layer {
|
||||||
color: #eee;
|
color: #eee;
|
||||||
}
|
}
|
||||||
/* 字符串值的颜色 */
|
/* 字符串值的颜色 */
|
||||||
.ace_string, .ace_cjk{
|
.ace_string,
|
||||||
|
.ace_cjk {
|
||||||
color: #a6eaa6;
|
color: #a6eaa6;
|
||||||
}
|
}
|
||||||
.ace_constant{
|
.ace_constant {
|
||||||
/* 数字的颜色 */
|
/* 数字的颜色 */
|
||||||
&.ace_numeric{
|
&.ace_numeric {
|
||||||
color: #ec9999;
|
color: #ec9999;
|
||||||
}
|
}
|
||||||
/* 布尔值的颜色 */
|
/* 布尔值的颜色 */
|
||||||
&.ace_language{
|
&.ace_language {
|
||||||
color: #f4c995;
|
color: #f4c995;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* 当前行高亮样式 */
|
/* 当前行高亮样式 */
|
||||||
.ace_gutter-active-line,
|
.ace_gutter-active-line,
|
||||||
.ace_marker-layer .ace_active-line{
|
.ace_marker-layer .ace_active-line {
|
||||||
background: #838774;
|
background: #838774;
|
||||||
}
|
}
|
||||||
/* 选中行高亮样式 */
|
/* 选中行高亮样式 */
|
||||||
|
|
@ -213,7 +225,9 @@ $dark-input: #777; //输入框:背景色
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* 搜索框 */
|
/* 搜索框 */
|
||||||
.ace_button, button, .ace_search_field {
|
.ace_button,
|
||||||
|
button,
|
||||||
|
.ace_search_field {
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
/* 搜索结果 */
|
/* 搜索结果 */
|
||||||
|
|
@ -221,4 +235,4 @@ $dark-input: #777; //输入框:背景色
|
||||||
border-color: #8b2929;
|
border-color: #8b2929;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const webpack = require('webpack')
|
|
||||||
const { defineConfig } = require('@vue/cli-service')
|
const { defineConfig } = require('@vue/cli-service')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
const publishUrl = process.env.VUE_APP_PUBLISH_URL
|
const publishUrl = process.env.VUE_APP_PUBLISH_URL
|
||||||
const publishProvider = process.env.VUE_APP_PUBLISH_PROVIDER
|
const publishProvider = process.env.VUE_APP_PUBLISH_PROVIDER
|
||||||
|
|
@ -33,7 +33,7 @@ module.exports = defineConfig({
|
||||||
},
|
},
|
||||||
pluginOptions: {
|
pluginOptions: {
|
||||||
electronBuilder: {
|
electronBuilder: {
|
||||||
mainProcessFile: "./src/background.js",
|
mainProcessFile: './src/background.js',
|
||||||
// Ref: https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/1891
|
// Ref: https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/1891
|
||||||
customFileProtocol: './',
|
customFileProtocol: './',
|
||||||
externals: [
|
externals: [
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ function registerProcessListener () {
|
||||||
log.info('child get msg:', JSON.stringify(msg))
|
log.info('child get msg:', JSON.stringify(msg))
|
||||||
if (msg.type === 'action') {
|
if (msg.type === 'action') {
|
||||||
api[msg.event.key](msg.event.params)
|
api[msg.event.key](msg.event.params)
|
||||||
} else if (msg.type === 'speed') {
|
}
|
||||||
|
else if (msg.type === 'speed') {
|
||||||
speedTest.action(msg.event)
|
speedTest.action(msg.event)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -61,7 +62,8 @@ const api = {
|
||||||
|
|
||||||
if (proxyOptions.setting && proxyOptions.setting.NODE_TLS_REJECT_UNAUTHORIZED === false) {
|
if (proxyOptions.setting && proxyOptions.setting.NODE_TLS_REJECT_UNAUTHORIZED === false) {
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'
|
||||||
}
|
}
|
||||||
// log.info('启动代理服务时的配置:', JSON.stringify(proxyOptions, null, '\t'))
|
// log.info('启动代理服务时的配置:', JSON.stringify(proxyOptions, null, '\t'))
|
||||||
|
|
@ -98,7 +100,8 @@ const api = {
|
||||||
if (err.code === 'ERR_SERVER_NOT_RUNNING') {
|
if (err.code === 'ERR_SERVER_NOT_RUNNING') {
|
||||||
log.info('代理服务未运行,无需关闭')
|
log.info('代理服务未运行,无需关闭')
|
||||||
resolve()
|
resolve()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.error('代理服务关闭失败:', err)
|
log.error('代理服务关闭失败:', err)
|
||||||
reject(err)
|
reject(err)
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +113,8 @@ const api = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
servers = []
|
servers = []
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('server is null, no need to close.')
|
log.info('server is null, no need to close.')
|
||||||
fireStatus(false)
|
fireStatus(false)
|
||||||
resolve()
|
resolve()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const log = require('./utils/util.log')
|
|
||||||
let JSON5 = require('json5')
|
let JSON5 = require('json5')
|
||||||
|
const log = require('./utils/util.log')
|
||||||
|
|
||||||
if (JSON5.default) {
|
if (JSON5.default) {
|
||||||
JSON5 = JSON5.default
|
JSON5 = JSON5.default
|
||||||
}
|
}
|
||||||
|
|
@ -16,10 +17,12 @@ module.exports = {
|
||||||
stringify2 (obj) {
|
stringify2 (obj) {
|
||||||
try {
|
try {
|
||||||
return JSON.stringify(obj)
|
return JSON.stringify(obj)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
try {
|
try {
|
||||||
return JSON5.stringify(obj)
|
return JSON5.stringify(obj)
|
||||||
} catch (e2) {
|
}
|
||||||
|
catch (e2) {
|
||||||
log.debug('转换为JSON字符串失败, error:', e, ', obj:', obj)
|
log.debug('转换为JSON字符串失败, error:', e, ', obj:', obj)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,8 @@ class DynamicChoice {
|
||||||
if (this.backupList.length > 0) {
|
if (this.backupList.length > 0) {
|
||||||
this.value = this.backupList.shift()
|
this.value = this.backupList.shift()
|
||||||
log.info(`切换backup完成: ${this.key}, ip: ${valueBackup} ➜ ${this.value}, this:`, this)
|
log.info(`切换backup完成: ${this.key}, ip: ${valueBackup} ➜ ${this.value}, this:`, this)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.value = null
|
this.value = null
|
||||||
log.info(`切换backup完成: ${this.key}, backupList为空了,设置this.value: from '${valueBackup}' to null. this:`, this)
|
log.info(`切换backup完成: ${this.key}, backupList为空了,设置this.value: from '${valueBackup}' to null. this:`, this)
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +110,8 @@ class DynamicChoice {
|
||||||
// 失败次数+1,累计连续失败次数+1
|
// 失败次数+1,累计连续失败次数+1
|
||||||
count.error++
|
count.error++
|
||||||
count.keepErrorCount++
|
count.keepErrorCount++
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 总次数+1
|
// 总次数+1
|
||||||
count.total++
|
count.total++
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ module.exports = class BaseDNS {
|
||||||
ipCache.doCount(ipCache.value, false)
|
ipCache.doCount(ipCache.value, false)
|
||||||
return ipCache.value
|
return ipCache.value
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
ipCache = new IpCache(hostname)
|
ipCache = new IpCache(hostname)
|
||||||
this.cache.set(hostname, ipCache)
|
this.cache.set(hostname, ipCache)
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +61,8 @@ module.exports = class BaseDNS {
|
||||||
log.info(`[DNS]: ${hostname} ➜ ${ipCache.value} (${new Date() - t} ms), ipList: ${JSON.stringify(ipList)}, ipCache:`, JSON.stringify(ipCache))
|
log.info(`[DNS]: ${hostname} ➜ ${ipCache.value} (${new Date() - t} ms), ipList: ${JSON.stringify(ipList)}, ipCache:`, JSON.stringify(ipCache))
|
||||||
|
|
||||||
return ipCache.value
|
return ipCache.value
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
log.error(`[DNS] cannot resolve hostname ${hostname} (${error})`, error)
|
log.error(`[DNS] cannot resolve hostname ${hostname} (${error})`, error)
|
||||||
return hostname
|
return hostname
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const { promisify } = require('util')
|
const { promisify } = require('node:util')
|
||||||
const doh = require('dns-over-http')
|
const doh = require('dns-over-http')
|
||||||
const log = require('../../utils/util.log')
|
const log = require('../../utils/util.log')
|
||||||
const matchUtil = require('../../utils/util.match')
|
const matchUtil = require('../../utils/util.match')
|
||||||
|
|
@ -30,7 +30,8 @@ module.exports = class DNSOverHTTPS extends BaseDNS {
|
||||||
if (hostnamePreSetIpList && (hostnamePreSetIpList.length > 0 || hostnamePreSetIpList.length === undefined)) {
|
if (hostnamePreSetIpList && (hostnamePreSetIpList.length > 0 || hostnamePreSetIpList.length === undefined)) {
|
||||||
if (hostnamePreSetIpList.length > 0) {
|
if (hostnamePreSetIpList.length > 0) {
|
||||||
hostnamePreSetIpList = hostnamePreSetIpList.slice()
|
hostnamePreSetIpList = hostnamePreSetIpList.slice()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
hostnamePreSetIpList = mapToList(hostnamePreSetIpList)
|
hostnamePreSetIpList = mapToList(hostnamePreSetIpList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,11 +53,13 @@ module.exports = class DNSOverHTTPS extends BaseDNS {
|
||||||
const ret = result.answers.filter(item => item.type === 'A').map(item => item.data)
|
const ret = result.answers.filter(item => item.type === 'A').map(item => item.data)
|
||||||
if (ret.length === 0) {
|
if (ret.length === 0) {
|
||||||
log.info('该域名没有IPv4地址解析:', hostname, ', cost:', (new Date() - start), 'ms')
|
log.info('该域名没有IPv4地址解析:', hostname, ', cost:', (new Date() - start), 'ms')
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('获取到域名地址:', hostname, JSON.stringify(ret), ', cost:', (new Date() - start), 'ms')
|
log.info('获取到域名地址:', hostname, JSON.stringify(ret), ', cost:', (new Date() - start), 'ms')
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.warn('DNS query error:', hostname, ', dns:', this.dnsServer, ', cost:', (new Date() - start), 'ms, error:', e)
|
log.warn('DNS query error:', hostname, ', dns:', this.dnsServer, ', cost:', (new Date() - start), 'ms, error:', e)
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,11 @@ module.exports = {
|
||||||
|
|
||||||
if (conf.type === 'ipaddress') {
|
if (conf.type === 'ipaddress') {
|
||||||
dnsMap[provider] = new DNSOverIpAddress(conf.server)
|
dnsMap[provider] = new DNSOverIpAddress(conf.server)
|
||||||
} else if (conf.type === 'https') {
|
}
|
||||||
|
else if (conf.type === 'https') {
|
||||||
dnsMap[provider] = new DNSOverHTTPS(conf.server, preSetIpList)
|
dnsMap[provider] = new DNSOverHTTPS(conf.server, preSetIpList)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
dnsMap[provider] = new DNSOverTLS(conf.server)
|
dnsMap[provider] = new DNSOverTLS(conf.server)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ module.exports = class DNSOverIpAddress extends BaseDNS {
|
||||||
}
|
}
|
||||||
const ret = res.data
|
const ret = res.data
|
||||||
|
|
||||||
const regexp = /<tr><th>IP Address<\/th><td><ul class="comma-separated"><li>([^<]*)<\/li><\/ul><\/td><\/tr>/gm
|
const regexp = /<tr><th>IP Address<\/th><td><ul class="comma-separated"><li>([^<]*)<\/li><\/ul><\/td><\/tr>/g
|
||||||
const matched = regexp.exec(ret)
|
const matched = regexp.exec(ret)
|
||||||
let ip = null
|
let ip = null
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ module.exports = class DNSOverPreSetIpList extends BaseDNS {
|
||||||
if (hostnamePreSetIpList && (hostnamePreSetIpList.length > 0 || hostnamePreSetIpList.length === undefined)) {
|
if (hostnamePreSetIpList && (hostnamePreSetIpList.length > 0 || hostnamePreSetIpList.length === undefined)) {
|
||||||
if (hostnamePreSetIpList.length > 0) {
|
if (hostnamePreSetIpList.length > 0) {
|
||||||
hostnamePreSetIpList = hostnamePreSetIpList.slice()
|
hostnamePreSetIpList = hostnamePreSetIpList.slice()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
hostnamePreSetIpList = mapToList(hostnamePreSetIpList)
|
hostnamePreSetIpList = mapToList(hostnamePreSetIpList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ function readConfig (config, defaultConfig) {
|
||||||
if (Object.isArray(config)) {
|
if (Object.isArray(config)) {
|
||||||
config = config.join(',')
|
config = config.join(',')
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
config = defaultConfig
|
config = defaultConfig
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,8 @@ function getConfig (interceptOpt, tryCount, log) {
|
||||||
if (count >= 100000) {
|
if (count >= 100000) {
|
||||||
count = 0
|
count = 0
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
config = interceptOpt.baiduOcr
|
config = interceptOpt.baiduOcr
|
||||||
tryCount = null // 将tryCount设置为null代表只有一个配置
|
tryCount = null // 将tryCount设置为null代表只有一个配置
|
||||||
}
|
}
|
||||||
|
|
@ -83,11 +84,13 @@ function getConfig (interceptOpt, tryCount, log) {
|
||||||
if (config.api == null) {
|
if (config.api == null) {
|
||||||
if (tryCount == null) {
|
if (tryCount == null) {
|
||||||
return null // 只配置了一个账号,没有更多账号可以选择了,直接返回null
|
return null // 只配置了一个账号,没有更多账号可以选择了,直接返回null
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (tryCount < interceptOpt.baiduOcr.length) {
|
if (tryCount < interceptOpt.baiduOcr.length) {
|
||||||
// 递归找到有效的配置
|
// 递归找到有效的配置
|
||||||
return getConfig(interceptOpt, tryCount + 1, log)
|
return getConfig(interceptOpt, tryCount + 1, log)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -164,7 +167,8 @@ module.exports = {
|
||||||
limitConfig(config.id, config.api)
|
limitConfig(config.id, config.api)
|
||||||
log.error(`当前百度云账号的接口 ${config.api},已达到当日调用次数上限,暂时禁用它,明天会自动放开:`, config)
|
log.error(`当前百度云账号的接口 ${config.api},已达到当日调用次数上限,暂时禁用它,明天会自动放开:`, config)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('baiduOcr success:', result)
|
log.info('baiduOcr success:', result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ function getLastModifiedTimeFromIfModifiedSince (rOptions, log) {
|
||||||
try {
|
try {
|
||||||
// 尝试解析 lastModified,并获取time
|
// 尝试解析 lastModified,并获取time
|
||||||
return new Date(lastModified).getTime()
|
return new Date(lastModified).getTime()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
// 为数字时,直接返回
|
// 为数字时,直接返回
|
||||||
if (/\\d+/.test(lastModified)) {
|
if (/\\d+/.test(lastModified)) {
|
||||||
return lastModified - 0
|
return lastModified - 0
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const url = require('url')
|
const url = require('node:url')
|
||||||
const lodash = require('lodash')
|
const lodash = require('lodash')
|
||||||
|
|
||||||
// 替换占位符
|
// 替换占位符
|
||||||
|
|
@ -27,9 +27,11 @@ function buildTargetUrl (rOptions, urlConf, interceptOpt, matched) {
|
||||||
if (interceptOpt && interceptOpt.replace) {
|
if (interceptOpt && interceptOpt.replace) {
|
||||||
const regexp = new RegExp(interceptOpt.replace)
|
const regexp = new RegExp(interceptOpt.replace)
|
||||||
targetUrl = rOptions.path.replace(regexp, urlConf)
|
targetUrl = rOptions.path.replace(regexp, urlConf)
|
||||||
} else if (urlConf.indexOf('http:') === 0 || urlConf.indexOf('https:') === 0) {
|
}
|
||||||
|
else if (urlConf.indexOf('http:') === 0 || urlConf.indexOf('https:') === 0) {
|
||||||
targetUrl = urlConf
|
targetUrl = urlConf
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
let uri = rOptions.path
|
let uri = rOptions.path
|
||||||
if (uri.indexOf('http:') === 0 || uri.indexOf('https:') === 0) {
|
if (uri.indexOf('http:') === 0 || uri.indexOf('https:') === 0) {
|
||||||
// eslint-disable-next-line node/no-deprecated-api
|
// eslint-disable-next-line node/no-deprecated-api
|
||||||
|
|
@ -95,7 +97,8 @@ module.exports = {
|
||||||
}
|
}
|
||||||
if (count.value == null) {
|
if (count.value == null) {
|
||||||
log.error('`count.value` is null, the count:', count)
|
log.error('`count.value` is null, the count:', count)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
count.doCount(count.value)
|
count.doCount(count.value)
|
||||||
proxyConf = count.value
|
proxyConf = count.value
|
||||||
context.requestCount = {
|
context.requestCount = {
|
||||||
|
|
@ -124,7 +127,8 @@ module.exports = {
|
||||||
}
|
}
|
||||||
res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}, sni: ${interceptOpt.sni}${unVerifySsl ? ', unVerifySsl' : ''}`)
|
res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}, sni: ${interceptOpt.sni}${unVerifySsl ? ', unVerifySsl' : ''}`)
|
||||||
log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget, ', sni replace servername:', rOptions.servername, (unVerifySsl ? ', unVerifySsl' : ''))
|
log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget, ', sni replace servername:', rOptions.servername, (unVerifySsl ? ', unVerifySsl' : ''))
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}`)
|
res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}`)
|
||||||
log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget)
|
log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ function replaceRequestHeaders (rOptions, headers, log) {
|
||||||
if (value) {
|
if (value) {
|
||||||
log.debug(`[DS-RequestReplace-Interceptor] replace '${key}': '${rOptions.headers[key.toLowerCase()]}' -> '${value}'`)
|
log.debug(`[DS-RequestReplace-Interceptor] replace '${key}': '${rOptions.headers[key.toLowerCase()]}' -> '${value}'`)
|
||||||
rOptions.headers[key.toLowerCase()] = value
|
rOptions.headers[key.toLowerCase()] = value
|
||||||
} else if (rOptions.headers[key.toLowerCase()]) {
|
}
|
||||||
|
else if (rOptions.headers[key.toLowerCase()]) {
|
||||||
log.debug(`[DS-RequestReplace-Interceptor] remove '${key}': '${rOptions.headers[key.toLowerCase()]}'`)
|
log.debug(`[DS-RequestReplace-Interceptor] remove '${key}': '${rOptions.headers[key.toLowerCase()]}'`)
|
||||||
delete rOptions.headers[key.toLowerCase()]
|
delete rOptions.headers[key.toLowerCase()]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,14 @@ module.exports = {
|
||||||
// 尝试修改rawHeaders中的cache-control、last-modified、expires
|
// 尝试修改rawHeaders中的cache-control、last-modified、expires
|
||||||
if (proxyRes.rawHeaders[i].toLowerCase() === 'cache-control') {
|
if (proxyRes.rawHeaders[i].toLowerCase() === 'cache-control') {
|
||||||
originalHeaders.cacheControl = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
originalHeaders.cacheControl = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
||||||
} else if (proxyRes.rawHeaders[i].toLowerCase() === 'last-modified') {
|
}
|
||||||
|
else if (proxyRes.rawHeaders[i].toLowerCase() === 'last-modified') {
|
||||||
originalHeaders.lastModified = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
originalHeaders.lastModified = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
||||||
} else if (proxyRes.rawHeaders[i].toLowerCase() === 'expires') {
|
}
|
||||||
|
else if (proxyRes.rawHeaders[i].toLowerCase() === 'expires') {
|
||||||
originalHeaders.expires = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
originalHeaders.expires = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
||||||
} else if (proxyRes.rawHeaders[i].toLowerCase() === 'etag') {
|
}
|
||||||
|
else if (proxyRes.rawHeaders[i].toLowerCase() === 'etag') {
|
||||||
originalHeaders.etag = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
originalHeaders.etag = { value: proxyRes.rawHeaders[i + 1], valueIndex: i + 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,7 +70,8 @@ module.exports = {
|
||||||
if (maxAgeMatch && maxAgeMatch[1] > maxAge) {
|
if (maxAgeMatch && maxAgeMatch[1] > maxAge) {
|
||||||
if (interceptOpt.cacheImmutable !== false && !originalHeaders.cacheControl.value.includes('immutable')) {
|
if (interceptOpt.cacheImmutable !== false && !originalHeaders.cacheControl.value.includes('immutable')) {
|
||||||
maxAge = maxAgeMatch[1]
|
maxAge = maxAgeMatch[1]
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const url = `${rOptions.method} ➜ ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${req.url}`
|
const url = `${rOptions.method} ➜ ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${req.url}`
|
||||||
res.setHeader('DS-Cache-Response-Interceptor', `skip: ${maxAgeMatch[1]} > ${maxAge}`)
|
res.setHeader('DS-Cache-Response-Interceptor', `skip: ${maxAgeMatch[1]} > ${maxAge}`)
|
||||||
log.info(`cache response intercept: skip: ${maxAgeMatch[1]} > ${maxAge}, url: ${url}`)
|
log.info(`cache response intercept: skip: ${maxAgeMatch[1]} > ${maxAge}, url: ${url}`)
|
||||||
|
|
@ -87,19 +91,22 @@ module.exports = {
|
||||||
// 替换cache-control
|
// 替换cache-control
|
||||||
if (originalHeaders.cacheControl) {
|
if (originalHeaders.cacheControl) {
|
||||||
proxyRes.rawHeaders[originalHeaders.cacheControl.valueIndex] = replaceHeaders.cacheControl
|
proxyRes.rawHeaders[originalHeaders.cacheControl.valueIndex] = replaceHeaders.cacheControl
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
res.setHeader('Cache-Control', replaceHeaders.cacheControl)
|
res.setHeader('Cache-Control', replaceHeaders.cacheControl)
|
||||||
}
|
}
|
||||||
// 替换last-modified
|
// 替换last-modified
|
||||||
if (originalHeaders.lastModified) {
|
if (originalHeaders.lastModified) {
|
||||||
proxyRes.rawHeaders[originalHeaders.lastModified.valueIndex] = replaceHeaders.lastModified
|
proxyRes.rawHeaders[originalHeaders.lastModified.valueIndex] = replaceHeaders.lastModified
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
res.setHeader('Last-Modified', replaceHeaders.lastModified)
|
res.setHeader('Last-Modified', replaceHeaders.lastModified)
|
||||||
}
|
}
|
||||||
// 替换expires
|
// 替换expires
|
||||||
if (originalHeaders.expires) {
|
if (originalHeaders.expires) {
|
||||||
proxyRes.rawHeaders[originalHeaders.expires.valueIndex] = replaceHeaders.expires
|
proxyRes.rawHeaders[originalHeaders.expires.valueIndex] = replaceHeaders.expires
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
res.setHeader('Expires', replaceHeaders.expires)
|
res.setHeader('Expires', replaceHeaders.expires)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ function replaceResponseHeaders (newHeaders, res, proxyRes) {
|
||||||
preHeaders[headerKey] = proxyRes.rawHeaders[i + 1] // 先保存原先响应头
|
preHeaders[headerKey] = proxyRes.rawHeaders[i + 1] // 先保存原先响应头
|
||||||
if (newHeaderValue === REMOVE) { // 由于拦截配置中不允许配置null,会被删,所以配置一个 "[remove]",当作删除响应头的意思
|
if (newHeaderValue === REMOVE) { // 由于拦截配置中不允许配置null,会被删,所以配置一个 "[remove]",当作删除响应头的意思
|
||||||
proxyRes.rawHeaders[i + 1] = ''
|
proxyRes.rawHeaders[i + 1] = ''
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
proxyRes.rawHeaders[i + 1] = newHeaderValue
|
proxyRes.rawHeaders[i + 1] = newHeaderValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,8 @@ module.exports = {
|
||||||
|
|
||||||
if (key.includes('/')) {
|
if (key.includes('/')) {
|
||||||
scriptTag = getScriptByUrlOrPath(key) // 1.绝对地址或相对地址(注意:当目标站点限制跨域脚本时,可使用相对地址,再结合proxy拦截器进行代理,可规避掉限制跨域脚本问题。)
|
scriptTag = getScriptByUrlOrPath(key) // 1.绝对地址或相对地址(注意:当目标站点限制跨域脚本时,可使用相对地址,再结合proxy拦截器进行代理,可规避掉限制跨域脚本问题。)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const script = scripts[key]
|
const script = scripts[key]
|
||||||
if (script == null) {
|
if (script == null) {
|
||||||
continue
|
continue
|
||||||
|
|
@ -71,7 +72,8 @@ module.exports = {
|
||||||
// 插入油猴脚本浏览器扩展
|
// 插入油猴脚本浏览器扩展
|
||||||
if (typeof interceptOpt.tampermonkeyScript === 'string') {
|
if (typeof interceptOpt.tampermonkeyScript === 'string') {
|
||||||
tags = `\r\n\t${getScriptByUrlOrPath(interceptOpt.tampermonkeyScript)}${tags}`
|
tags = `\r\n\t${getScriptByUrlOrPath(interceptOpt.tampermonkeyScript)}${tags}`
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
tags = `\r\n\t${getScript('tampermonkey', scripts.tampermonkey.script)}${tags}`
|
tags = `\r\n\t${getScript('tampermonkey', scripts.tampermonkey.script)}${tags}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,10 +82,12 @@ module.exports = {
|
||||||
return {
|
return {
|
||||||
head: `${tags}\r\n`,
|
head: `${tags}\r\n`,
|
||||||
}
|
}
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
try {
|
try {
|
||||||
res.setHeader('DS-Script-Interceptor', 'error')
|
res.setHeader('DS-Script-Interceptor', 'error')
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
log.error('load monkey script error', err)
|
log.error('load monkey script error', err)
|
||||||
|
|
@ -108,7 +112,8 @@ module.exports = {
|
||||||
if (typeof replaceScriptUrlFun === 'function') {
|
if (typeof replaceScriptUrlFun === 'function') {
|
||||||
replaceScriptUrlFun(scriptKey)
|
replaceScriptUrlFun(scriptKey)
|
||||||
}
|
}
|
||||||
} else if (scriptUrl.indexOf('/') === 0) {
|
}
|
||||||
|
else if (scriptUrl.indexOf('/') === 0) {
|
||||||
// 相对地址
|
// 相对地址
|
||||||
scriptProxy[scriptUrl] = scriptUrl
|
scriptProxy[scriptUrl] = scriptUrl
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +129,8 @@ module.exports = {
|
||||||
pathConfig.script[i] = scriptKey
|
pathConfig.script[i] = scriptKey
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (typeof pathConfig.script === 'string') {
|
}
|
||||||
|
else if (typeof pathConfig.script === 'string') {
|
||||||
handleScriptUrl(pathConfig.script, 'script', (scriptKey) => {
|
handleScriptUrl(pathConfig.script, 'script', (scriptKey) => {
|
||||||
pathConfig.script = scriptKey
|
pathConfig.script = scriptKey
|
||||||
})
|
})
|
||||||
|
|
@ -174,7 +180,8 @@ module.exports = {
|
||||||
const obj = {}
|
const obj = {}
|
||||||
obj[pathPattern] = hostnameConfig[pathPattern]
|
obj[pathPattern] = hostnameConfig[pathPattern]
|
||||||
log.debug(`域名 '${hostnamePattern}' 拦截配置中,新增伪脚本地址的代理配置:`, JSON.stringify(obj, null, '\t'))
|
log.debug(`域名 '${hostnamePattern}' 拦截配置中,新增伪脚本地址的代理配置:`, JSON.stringify(obj, null, '\t'))
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 相对地址:新增响应头Content-Type替换配置
|
// 相对地址:新增响应头Content-Type替换配置
|
||||||
if (hostnameConfig[scriptKey]) {
|
if (hostnameConfig[scriptKey]) {
|
||||||
continue // 配置已经存在,按自定义配置优先
|
continue // 配置已经存在,按自定义配置优先
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
// request interceptor impls
|
|
||||||
const OPTIONS = require('./impl/req/OPTIONS.js')
|
|
||||||
|
|
||||||
const success = require('./impl/req/success')
|
|
||||||
const redirect = require('./impl/req/redirect')
|
|
||||||
const abort = require('./impl/req/abort')
|
const abort = require('./impl/req/abort')
|
||||||
const cacheReq = require('./impl/req/cacheReq')
|
|
||||||
|
|
||||||
const requestReplace = require('./impl/req/requestReplace')
|
|
||||||
|
|
||||||
const proxy = require('./impl/req/proxy')
|
|
||||||
const sni = require('./impl/req/sni')
|
|
||||||
|
|
||||||
const baiduOcr = require('./impl/req/baiduOcr')
|
const baiduOcr = require('./impl/req/baiduOcr')
|
||||||
|
const cacheReq = require('./impl/req/cacheReq')
|
||||||
|
// request interceptor impls
|
||||||
|
const OPTIONS = require('./impl/req/OPTIONS.js')
|
||||||
|
const proxy = require('./impl/req/proxy')
|
||||||
|
|
||||||
|
const redirect = require('./impl/req/redirect')
|
||||||
|
|
||||||
|
const requestReplace = require('./impl/req/requestReplace')
|
||||||
|
const sni = require('./impl/req/sni')
|
||||||
|
|
||||||
|
const success = require('./impl/req/success')
|
||||||
|
|
||||||
// response interceptor impls
|
// response interceptor impls
|
||||||
const OPTIONSHeaders = require('./impl/res/AfterOPTIONSHeaders')
|
const OPTIONSHeaders = require('./impl/res/AfterOPTIONSHeaders')
|
||||||
|
|
@ -23,12 +23,18 @@ const script = require('./impl/res/script')
|
||||||
module.exports = [
|
module.exports = [
|
||||||
// request interceptor impls
|
// request interceptor impls
|
||||||
OPTIONS,
|
OPTIONS,
|
||||||
success, redirect, abort, cacheReq,
|
success,
|
||||||
|
redirect,
|
||||||
|
abort,
|
||||||
|
cacheReq,
|
||||||
requestReplace,
|
requestReplace,
|
||||||
proxy, sni,
|
proxy,
|
||||||
|
sni,
|
||||||
baiduOcr,
|
baiduOcr,
|
||||||
|
|
||||||
// response interceptor impls
|
// response interceptor impls
|
||||||
OPTIONSHeaders, cacheRes, responseReplace,
|
OPTIONSHeaders,
|
||||||
|
cacheRes,
|
||||||
|
responseReplace,
|
||||||
script,
|
script,
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const log = require('../../utils/util.log')
|
const log = require('../../utils/util.log')
|
||||||
|
|
||||||
let scripts
|
let scripts
|
||||||
|
|
@ -12,7 +12,8 @@ function buildScript (sc, content, scriptName) {
|
||||||
let eventStr
|
let eventStr
|
||||||
if (runAt === 'document-end') {
|
if (runAt === 'document-end') {
|
||||||
eventStr = 'document.addEventListener("DOMContentLoaded"'
|
eventStr = 'document.addEventListener("DOMContentLoaded"'
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
eventStr = 'window.addEventListener("load"'
|
eventStr = 'window.addEventListener("load"'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +48,8 @@ if (!((window.__ds_global__ || {}).GM_getValue || (() => true))("ds_enabled", tr
|
||||||
|
|
||||||
if (item.indexOf('.') > 0) {
|
if (item.indexOf('.') > 0) {
|
||||||
grantStr += `${item} = (window.__ds_global__ || {})['${item}'];`
|
grantStr += `${item} = (window.__ds_global__ || {})['${item}'];`
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
grantStr += `const ${item} = (window.__ds_global__ || {})['${item}'] || (() => {});`
|
grantStr += `const ${item} = (window.__ds_global__ || {})['${item}'] || (() => {});`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -57,10 +59,10 @@ if (!((window.__ds_global__ || {}).GM_getValue || (() => true))("ds_enabled", tr
|
||||||
initStr}\r\n${
|
initStr}\r\n${
|
||||||
checkEnabledStr}\r\n\r\n${
|
checkEnabledStr}\r\n\r\n${
|
||||||
grantStr ? (`${grantStr}\r\n\r\n`) : ''
|
grantStr ? (`${grantStr}\r\n\r\n`) : ''
|
||||||
}${content
|
}${content
|
||||||
}\r\nconsole.log("${scriptKey} completed")`
|
}\r\nconsole.log("${scriptKey} completed")`
|
||||||
+ `\r\n})`
|
+ `\r\n})`
|
||||||
+ `\r\nconsole.log("${scriptKey} loaded")`
|
+ `\r\nconsole.log("${scriptKey} loaded")`
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadScript (content, scriptName) {
|
function loadScript (content, scriptName) {
|
||||||
|
|
@ -89,9 +91,11 @@ function loadScript (content, scriptName) {
|
||||||
const value = ret[2].trim()
|
const value = ret[2].trim()
|
||||||
if (key === 'grant') {
|
if (key === 'grant') {
|
||||||
sc.grant.push(value)
|
sc.grant.push(value)
|
||||||
} else if (key === 'match') {
|
}
|
||||||
|
else if (key === 'match') {
|
||||||
sc.match.push(value)
|
sc.match.push(value)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
sc[key] = value
|
sc[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
|
|
||||||
const config = exports
|
const config = exports
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const url = require('url')
|
const url = require('node:url')
|
||||||
const tunnelAgent = require('tunnel-agent')
|
const tunnelAgent = require('tunnel-agent')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const matchUtil = require('../../../utils/util.match')
|
const matchUtil = require('../../../utils/util.match')
|
||||||
|
|
@ -83,7 +83,8 @@ util.parseHostnameAndPort = (host, defaultPort) => {
|
||||||
if (arr[1]) {
|
if (arr[1]) {
|
||||||
arr[1] = Number.parseInt(arr[1], 10)
|
arr[1] = Number.parseInt(arr[1], 10)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
arr = host.split(':')
|
arr = host.split(':')
|
||||||
if (arr.length > 1) {
|
if (arr.length > 1) {
|
||||||
arr[1] = Number.parseInt(arr[1], 10)
|
arr[1] = Number.parseInt(arr[1], 10)
|
||||||
|
|
@ -92,7 +93,8 @@ util.parseHostnameAndPort = (host, defaultPort) => {
|
||||||
|
|
||||||
if (defaultPort > 0 && (arr.length === 1 || arr[1] === undefined)) {
|
if (defaultPort > 0 && (arr.length === 1 || arr[1] === undefined)) {
|
||||||
arr[1] = defaultPort
|
arr[1] = defaultPort
|
||||||
} else if (arr.length === 2 && arr[1] === undefined) {
|
}
|
||||||
|
else if (arr.length === 2 && arr[1] === undefined) {
|
||||||
arr.pop()
|
arr.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,10 +112,12 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting, com
|
||||||
if (externalProxy) {
|
if (externalProxy) {
|
||||||
if (typeof externalProxy === 'string') {
|
if (typeof externalProxy === 'string') {
|
||||||
externalProxyUrl = externalProxy
|
externalProxyUrl = externalProxy
|
||||||
} else if (typeof externalProxy === 'function') {
|
}
|
||||||
|
else if (typeof externalProxy === 'function') {
|
||||||
try {
|
try {
|
||||||
externalProxyUrl = externalProxy(req, ssl)
|
externalProxyUrl = externalProxy(req, ssl)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('externalProxy error:', e)
|
log.error('externalProxy error:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -133,10 +137,12 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting, com
|
||||||
// log.info(`get timeoutConfig '${hostname}':`, timeoutConfig)
|
// log.info(`get timeoutConfig '${hostname}':`, timeoutConfig)
|
||||||
agent = createAgent(protocol, timeoutConfig, serverSetting.verifySsl)
|
agent = createAgent(protocol, timeoutConfig, serverSetting.verifySsl)
|
||||||
headers.connection = 'keep-alive'
|
headers.connection = 'keep-alive'
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
agent = false
|
agent = false
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
agent = util.getTunnelAgent(protocol === 'https:', externalProxyUrl)
|
agent = util.getTunnelAgent(protocol === 'https:', externalProxyUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,7 +172,8 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting, com
|
||||||
// mark a socketId for Agent to bind socket for NTLM
|
// mark a socketId for Agent to bind socket for NTLM
|
||||||
if (req.socket.customSocketId) {
|
if (req.socket.customSocketId) {
|
||||||
options.customSocketId = req.socket.customSocketId
|
options.customSocketId = req.socket.customSocketId
|
||||||
} else if (headers.authorization) {
|
}
|
||||||
|
else if (headers.authorization) {
|
||||||
options.customSocketId = req.socket.customSocketId = socketId++
|
options.customSocketId = req.socket.customSocketId = socketId++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,7 +201,8 @@ util.getTunnelAgent = (requestIsSSL, externalProxyUrl) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return httpsOverHttpAgent
|
return httpsOverHttpAgent
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (!httpsOverHttpsAgent) {
|
if (!httpsOverHttpsAgent) {
|
||||||
httpsOverHttpsAgent = tunnelAgent.httpsOverHttps({
|
httpsOverHttpsAgent = tunnelAgent.httpsOverHttps({
|
||||||
proxy: {
|
proxy: {
|
||||||
|
|
@ -205,7 +213,8 @@ util.getTunnelAgent = (requestIsSSL, externalProxyUrl) => {
|
||||||
}
|
}
|
||||||
return httpsOverHttpsAgent
|
return httpsOverHttpsAgent
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (protocol === 'http:') {
|
if (protocol === 'http:') {
|
||||||
// if (!httpOverHttpAgent) {
|
// if (!httpOverHttpAgent) {
|
||||||
// httpOverHttpAgent = tunnelAgent.httpOverHttp({
|
// httpOverHttpAgent = tunnelAgent.httpOverHttp({
|
||||||
|
|
@ -216,7 +225,8 @@ util.getTunnelAgent = (requestIsSSL, externalProxyUrl) => {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
return false
|
return false
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (!httpOverHttpsAgent) {
|
if (!httpOverHttpsAgent) {
|
||||||
httpOverHttpsAgent = tunnelAgent.httpOverHttps({
|
httpOverHttpsAgent = tunnelAgent.httpOverHttps({
|
||||||
proxy: {
|
proxy: {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
*
|
*
|
||||||
* @author WangLiang
|
* @author WangLiang
|
||||||
*/
|
*/
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const jsonApi = require('../../../json')
|
const jsonApi = require('../../../json')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const matchUtil = require('../../../utils/util.match')
|
const matchUtil = require('../../../utils/util.match')
|
||||||
|
|
@ -58,7 +58,8 @@ function _loadFromFile (defaultConfig) {
|
||||||
if (!fs.existsSync(configPath)) {
|
if (!fs.existsSync(configPath)) {
|
||||||
config = defaultConfig
|
config = defaultConfig
|
||||||
log.info(`本地未保存过 ${configPath} 文件,使用默认配置`)
|
log.info(`本地未保存过 ${configPath} 文件,使用默认配置`)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const file = fs.readFileSync(configPath)
|
const file = fs.readFileSync(configPath)
|
||||||
log.info('读取 automaticCompatibleConfig.json 成功:', configPath)
|
log.info('读取 automaticCompatibleConfig.json 成功:', configPath)
|
||||||
const fileStr = file.toString()
|
const fileStr = file.toString()
|
||||||
|
|
@ -79,7 +80,8 @@ function _saveConfigToFile () {
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(filePath, jsonApi.stringify(config))
|
fs.writeFileSync(filePath, jsonApi.stringify(config))
|
||||||
log.info('保存 automaticCompatibleConfig.json 成功:', filePath)
|
log.info('保存 automaticCompatibleConfig.json 成功:', filePath)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('保存 automaticCompatibleConfig.json 失败:', filePath, e)
|
log.error('保存 automaticCompatibleConfig.json 失败:', filePath, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +109,8 @@ module.exports = {
|
||||||
const connectCompatibleConfig = this.getConnectCompatibleConfig(hostname, port)
|
const connectCompatibleConfig = this.getConnectCompatibleConfig(hostname, port)
|
||||||
if (connectCompatibleConfig) {
|
if (connectCompatibleConfig) {
|
||||||
connectCompatibleConfig.ssl = ssl
|
connectCompatibleConfig.ssl = ssl
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
config.connect[`${hostname}:${port}`] = { ssl }
|
config.connect[`${hostname}:${port}`] = { ssl }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,7 +142,8 @@ module.exports = {
|
||||||
const requestCompatibleConfig = this.getRequestCompatibleConfig(rOptions.hostname, rOptions.port)
|
const requestCompatibleConfig = this.getRequestCompatibleConfig(rOptions.hostname, rOptions.port)
|
||||||
if (requestCompatibleConfig) {
|
if (requestCompatibleConfig) {
|
||||||
requestCompatibleConfig.rejectUnauthorized = rejectUnauthorized
|
requestCompatibleConfig.rejectUnauthorized = rejectUnauthorized
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
config.request[`${rOptions.hostname}:${rOptions.port}`] = { rejectUnauthorized }
|
config.request[`${rOptions.hostname}:${rOptions.port}`] = { rejectUnauthorized }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const zlib = require('zlib')
|
const zlib = require('node:zlib')
|
||||||
const through = require('through2')
|
const through = require('through2')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
|
|
||||||
|
|
@ -181,10 +181,12 @@ module.exports = {
|
||||||
}))
|
}))
|
||||||
.pipe(codec.createCompressor()) // 编码
|
.pipe(codec.createCompressor()) // 编码
|
||||||
.pipe(res)
|
.pipe(res)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.error(`InsertScriptMiddleware.responseInterceptor(): 暂不支持编码方式 ${encoding}, 目前支持:`, httpUtil.supportedEncodingsStr())
|
log.error(`InsertScriptMiddleware.responseInterceptor(): 暂不支持编码方式 ${encoding}, 目前支持:`, httpUtil.supportedEncodingsStr())
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
proxyRes
|
proxyRes
|
||||||
.pipe(through(function (chunk, enc, callback) {
|
.pipe(through(function (chunk, enc, callback) {
|
||||||
chunkByteReplace(this, chunk, enc, callback, append)
|
chunkByteReplace(this, chunk, enc, callback, append)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const { Buffer } = require('buffer')
|
const { Buffer } = require('node:buffer')
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const url = require('url')
|
const url = require('node:url')
|
||||||
const lodash = require('lodash')
|
const lodash = require('lodash')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
|
|
@ -15,7 +15,8 @@ function matched (hostname, overWallTargetMap) {
|
||||||
const ret1 = matchUtil.matchHostname(overWallTargetMap, hostname, 'matched overwall')
|
const ret1 = matchUtil.matchHostname(overWallTargetMap, hostname, 'matched overwall')
|
||||||
if (ret1) {
|
if (ret1) {
|
||||||
return 'in config'
|
return 'in config'
|
||||||
} else if (ret1 === false || ret1 === 'false') {
|
}
|
||||||
|
else if (ret1 === false || ret1 === 'false') {
|
||||||
log.debug(`域名 ${hostname} 的overwall配置为 false,跳过增强功能,即使它在 pac.txt 里`)
|
log.debug(`域名 ${hostname} 的overwall配置为 false,跳过增强功能,即使它在 pac.txt 里`)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +29,8 @@ function matched (hostname, overWallTargetMap) {
|
||||||
if (ret && ret.indexOf('PROXY ') === 0) {
|
if (ret && ret.indexOf('PROXY ') === 0) {
|
||||||
log.info(`matchHostname: matched overwall: '${hostname}' -> '${ret}' in pac.txt`)
|
log.info(`matchHostname: matched overwall: '${hostname}' -> '${ret}' in pac.txt`)
|
||||||
return 'in pac.txt'
|
return 'in pac.txt'
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.debug(`matchHostname: matched overwall: Not-Matched '${hostname}' -> '${ret}' in pac.txt`)
|
log.debug(`matchHostname: matched overwall: Not-Matched '${hostname}' -> '${ret}' in pac.txt`)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +51,8 @@ function loadPacLastModifiedTime (pacTxt) {
|
||||||
if (matched && matched.length > 0) {
|
if (matched && matched.length > 0) {
|
||||||
try {
|
try {
|
||||||
return new Date(matched[0])
|
return new Date(matched[0])
|
||||||
} catch (ignore) {
|
}
|
||||||
|
catch {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +77,7 @@ function savePacFile (pacTxt) {
|
||||||
// 尝试解析和修改 pac.txt 文件时间
|
// 尝试解析和修改 pac.txt 文件时间
|
||||||
const lastModifiedTime = loadPacLastModifiedTime(pacTxt)
|
const lastModifiedTime = loadPacLastModifiedTime(pacTxt)
|
||||||
if (lastModifiedTime) {
|
if (lastModifiedTime) {
|
||||||
fs.stat(pacFilePath, (err, stats) => {
|
fs.stat(pacFilePath, (err, _stats) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
log.error('修改 pac.txt 文件时间失败:', err)
|
log.error('修改 pac.txt 文件时间失败:', err)
|
||||||
return
|
return
|
||||||
|
|
@ -84,7 +87,8 @@ function savePacFile (pacTxt) {
|
||||||
fs.utimes(pacFilePath, lastModifiedTime, lastModifiedTime, (utimesErr) => {
|
fs.utimes(pacFilePath, lastModifiedTime, lastModifiedTime, (utimesErr) => {
|
||||||
if (utimesErr) {
|
if (utimesErr) {
|
||||||
log.error('修改 pac.txt 文件时间失败:', utimesErr)
|
log.error('修改 pac.txt 文件时间失败:', utimesErr)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`'${pacFilePath}' 文件的修改时间已更新为其最近更新时间 '${formatDate(lastModifiedTime)}'`)
|
log.info(`'${pacFilePath}' 文件的修改时间已更新为其最近更新时间 '${formatDate(lastModifiedTime)}'`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -107,7 +111,8 @@ async function downloadPacAsync (pacConfig) {
|
||||||
if (body == null || body.length < 100) {
|
if (body == null || body.length < 100) {
|
||||||
log.warn('下载远程 pac.txt 文件成功,但内容为空或内容太短,判断为无效的 pax.txt 文件:', remotePacFileUrl, ', body:', body)
|
log.warn('下载远程 pac.txt 文件成功,但内容为空或内容太短,判断为无效的 pax.txt 文件:', remotePacFileUrl, ', body:', body)
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info('下载远程 pac.txt 文件成功:', remotePacFileUrl)
|
log.info('下载远程 pac.txt 文件成功:', remotePacFileUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +123,8 @@ async function downloadPacAsync (pacConfig) {
|
||||||
pacTxt = Buffer.from(pacTxt, 'base64').toString('utf8')
|
pacTxt = Buffer.from(pacTxt, 'base64').toString('utf8')
|
||||||
// log.debug('解析 base64 后的 pax:', pacTxt)
|
// log.debug('解析 base64 后的 pax:', pacTxt)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch {
|
||||||
if (!pacTxt.includes('!---------------------EOF')) {
|
if (!pacTxt.includes('!---------------------EOF')) {
|
||||||
log.error(`远程 pac.txt 文件内容即不是base64格式,也不是要求的格式,url: ${remotePacFileUrl},body: ${body}`)
|
log.error(`远程 pac.txt 文件内容即不是base64格式,也不是要求的格式,url: ${remotePacFileUrl},body: ${body}`)
|
||||||
return
|
return
|
||||||
|
|
@ -127,7 +133,8 @@ async function downloadPacAsync (pacConfig) {
|
||||||
|
|
||||||
// 保存到本地
|
// 保存到本地
|
||||||
savePacFile(pacTxt)
|
savePacFile(pacTxt)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.error(`下载远程 pac.txt 文件失败: ${remotePacFileUrl}, response:`, response, ', body:', body)
|
log.error(`下载远程 pac.txt 文件失败: ${remotePacFileUrl}, response:`, response, ', body:', body)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -153,11 +160,11 @@ function createOverwallMiddleware (overWallConfig) {
|
||||||
}
|
}
|
||||||
const overWallTargetMap = matchUtil.domainMapRegexply(overWallConfig.targets)
|
const overWallTargetMap = matchUtil.domainMapRegexply(overWallConfig.targets)
|
||||||
return {
|
return {
|
||||||
sslConnectInterceptor: (req, cltSocket, head) => {
|
sslConnectInterceptor: (req, _cltSocket, _head) => {
|
||||||
const hostname = req.url.split(':')[0]
|
const hostname = req.url.split(':')[0]
|
||||||
return matched(hostname, overWallTargetMap)
|
return matched(hostname, overWallTargetMap)
|
||||||
},
|
},
|
||||||
requestIntercept (context, req, res, ssl, next) {
|
requestIntercept (context, req, res, _ssl, _next) {
|
||||||
const { rOptions, log, RequestCounter } = context
|
const { rOptions, log, RequestCounter } = context
|
||||||
if (rOptions.protocol === 'http:') {
|
if (rOptions.protocol === 'http:') {
|
||||||
return
|
return
|
||||||
|
|
@ -176,7 +183,8 @@ function createOverwallMiddleware (overWallConfig) {
|
||||||
}
|
}
|
||||||
if (count.value == null) {
|
if (count.value == null) {
|
||||||
log.error('`count.value` is null, the count:', count)
|
log.error('`count.value` is null, the count:', count)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
count.doCount(count.value)
|
count.doCount(count.value)
|
||||||
proxyServer = count.value
|
proxyServer = count.value
|
||||||
context.requestCount = {
|
context.requestCount = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const log = require('../../../../utils/util.log')
|
const log = require('../../../../utils/util.log')
|
||||||
|
|
||||||
function createPacClient (pacFilePath) {
|
function createPacClient (pacFilePath) {
|
||||||
|
|
@ -12,7 +12,8 @@ function createPacClient (pacFilePath) {
|
||||||
const filePath = path.resolve(location)
|
const filePath = path.resolve(location)
|
||||||
log.info('read pac path:', filePath)
|
log.info('read pac path:', filePath)
|
||||||
return fs.readFileSync(location).toString()
|
return fs.readFileSync(location).toString()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('读取pac失败:', e)
|
log.error('读取pac失败:', e)
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const net = require('net')
|
const net = require('node:net')
|
||||||
const url = require('url')
|
const url = require('node:url')
|
||||||
const jsonApi = require('../../../json')
|
const jsonApi = require('../../../json')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const DnsUtil = require('../../dns/index')
|
const DnsUtil = require('../../dns/index')
|
||||||
|
|
@ -45,7 +45,8 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
log.error(`----- fakeServer getServerPromise error: ${hostname}:${port}, error:`, e)
|
log.error(`----- fakeServer getServerPromise error: ${hostname}:${port}, error:`, e)
|
||||||
})
|
})
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`不拦截请求,直连目标服务器: ${hostname}:${port}, headers:`, jsonApi.stringify2(req.headers))
|
log.info(`不拦截请求,直连目标服务器: ${hostname}:${port}, headers:`, jsonApi.stringify2(req.headers))
|
||||||
connect(req, cltSocket, head, hostname, port, dnsConfig, true)
|
connect(req, cltSocket, head, hostname, port, dnsConfig, true)
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +118,8 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig = null, isDire
|
||||||
const proxySocket = net.connect(options, () => {
|
const proxySocket = net.connect(options, () => {
|
||||||
if (!isDirect) {
|
if (!isDirect) {
|
||||||
log.info('Proxy connect start:', hostport)
|
log.info('Proxy connect start:', hostport)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.debug('Direct connect start:', hostport)
|
log.debug('Direct connect start:', hostport)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,7 +192,8 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig = null, isDire
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxySocket
|
return proxySocket
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error(`${isDirect ? '直连' : '代理连接'}错误: ${hostport}, error:`, e)
|
log.error(`${isDirect ? '直连' : '代理连接'}错误: ${hostport}, error:`, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const forge = require('node-forge')
|
const forge = require('node-forge')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const FakeServersCenter = require('../tls/FakeServersCenter')
|
const FakeServersCenter = require('../tls/FakeServersCenter')
|
||||||
|
|
@ -20,7 +20,8 @@ module.exports = function createFakeServerCenter ({
|
||||||
const caKeyPem = fs.readFileSync(caKeyPath)
|
const caKeyPem = fs.readFileSync(caKeyPath)
|
||||||
caCert = forge.pki.certificateFromPem(caCertPem)
|
caCert = forge.pki.certificateFromPem(caCertPem)
|
||||||
caKey = forge.pki.privateKeyFromPem(caKeyPem)
|
caKey = forge.pki.privateKeyFromPem(caKeyPem)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('Can not find `CA certificate` or `CA key`:', e)
|
log.error('Can not find `CA certificate` or `CA key`:', e)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const http = require('http')
|
const http = require('node:http')
|
||||||
const https = require('https')
|
const https = require('node:https')
|
||||||
const jsonApi = require('../../../json')
|
const jsonApi = require('../../../json')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const RequestCounter = require('../../choice/RequestCounter')
|
const RequestCounter = require('../../choice/RequestCounter')
|
||||||
|
|
@ -23,9 +23,11 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
||||||
|
|
||||||
if (rOptions.headers.connection === 'close') {
|
if (rOptions.headers.connection === 'close') {
|
||||||
req.socket.setKeepAlive(false)
|
req.socket.setKeepAlive(false)
|
||||||
} else if (rOptions.customSocketId != null) { // for NTLM
|
}
|
||||||
|
else if (rOptions.customSocketId != null) { // for NTLM
|
||||||
req.socket.setKeepAlive(true, 60 * 60 * 1000)
|
req.socket.setKeepAlive(true, 60 * 60 * 1000)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
req.socket.setKeepAlive(true, 30000)
|
req.socket.setKeepAlive(true, 30000)
|
||||||
}
|
}
|
||||||
const context = {
|
const context = {
|
||||||
|
|
@ -71,10 +73,12 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -125,10 +129,12 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
||||||
rOptions.lookup = dnsLookup.createLookupFunc(res, dns, 'request url', url, isDnsIntercept)
|
rOptions.lookup = dnsLookup.createLookupFunc(res, dns, 'request url', url, isDnsIntercept)
|
||||||
log.debug(`域名 ${rOptions.hostname} DNS: ${dns.name}`)
|
log.debug(`域名 ${rOptions.hostname} DNS: ${dns.name}`)
|
||||||
res.setHeader('DS-DNS', dns.name)
|
res.setHeader('DS-DNS', dns.name)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`域名 ${rOptions.hostname} 在DNS中未配置`)
|
log.info(`域名 ${rOptions.hostname} 在DNS中未配置`)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`域名 ${rOptions.hostname} DNS配置不存在`)
|
log.info(`域名 ${rOptions.hostname} DNS配置不存在`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +163,8 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
||||||
const cost = new Date() - start
|
const cost = new Date() - start
|
||||||
if (rOptions.protocol === 'https:') {
|
if (rOptions.protocol === 'https:') {
|
||||||
log.info(`代理请求返回: 【${proxyRes.statusCode}】${url}, cost: ${cost} ms`)
|
log.info(`代理请求返回: 【${proxyRes.statusCode}】${url}, cost: ${cost} ms`)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`请求返回: 【${proxyRes.statusCode}】${url}, cost: ${cost} ms`)
|
log.info(`请求返回: 【${proxyRes.statusCode}】${url}, cost: ${cost} ms`)
|
||||||
}
|
}
|
||||||
// console.log('request:', proxyReq, proxyReq.socket)
|
// console.log('request:', proxyReq, proxyReq.socket)
|
||||||
|
|
@ -284,7 +291,8 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
||||||
if (append.body) {
|
if (append.body) {
|
||||||
body += append.body
|
body += append.body
|
||||||
}
|
}
|
||||||
} else if (append === false) {
|
}
|
||||||
|
else if (append === false) {
|
||||||
break // 返回false表示终止拦截器,跳出循环
|
break // 返回false表示终止拦截器,跳出循环
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -292,10 +300,12 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
||||||
head,
|
head,
|
||||||
body,
|
body,
|
||||||
})
|
})
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -331,13 +341,15 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
|
||||||
目标网站请求错误:【${e.code}】 ${e.message}<br/>
|
目标网站请求错误:【${e.code}】 ${e.message}<br/>
|
||||||
目标地址:${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`,
|
目标地址:${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}`,
|
||||||
)
|
)
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
res.end()
|
res.end()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const http = require('http')
|
const http = require('node:http')
|
||||||
const https = require('https')
|
const https = require('node:https')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const util = require('../common/util')
|
const util = require('../common/util')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const defaultDns = require('dns')
|
const defaultDns = require('node:dns')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const speedTest = require('../../speed')
|
const speedTest = require('../../speed')
|
||||||
|
|
||||||
|
|
@ -17,7 +17,8 @@ module.exports = {
|
||||||
}
|
}
|
||||||
callback(null, aliveIpObj.host, 4)
|
callback(null, aliveIpObj.host, 4)
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`----- ${action}: ${hostname}, no alive ip${target}, tester: { "ready": ${tester.ready}, "backupList": ${JSON.stringify(tester.backupList)} }`)
|
log.info(`----- ${action}: ${hostname}, no alive ip${target}, tester: { "ready": ${tester.ready}, "backupList": ${JSON.stringify(tester.backupList)} }`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,11 +50,13 @@ module.exports = {
|
||||||
}
|
}
|
||||||
callback(null, ip, 4)
|
callback(null, ip, 4)
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 使用默认dns
|
// 使用默认dns
|
||||||
log.info(`----- ${action}: ${hostname}, use hostname by default DNS: ${hostname}, skip test failed ip from dns '${dns.name}: ${ip}'${target}, options:`, options)
|
log.info(`----- ${action}: ${hostname}, use hostname by default DNS: ${hostname}, skip test failed ip from dns '${dns.name}: ${ip}'${target}, options:`, options)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 使用默认dns
|
// 使用默认dns
|
||||||
log.info(`----- ${action}: ${hostname}, use hostname by default DNS: ${hostname}${target}, options:`, options, ', dns:', dns)
|
log.info(`----- ${action}: ${hostname}, use hostname by default DNS: ${hostname}${target}, options:`, options, ', dns:', dns)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const http = require('http')
|
const http = require('node:http')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const speedTest = require('../../speed/index.js')
|
const speedTest = require('../../speed/index.js')
|
||||||
const config = require('../common/config')
|
const config = require('../common/config')
|
||||||
|
|
@ -104,7 +104,8 @@ module.exports = {
|
||||||
server.on('upgrade', (req, cltSocket, head) => {
|
server.on('upgrade', (req, cltSocket, head) => {
|
||||||
if (printDebugLog) {
|
if (printDebugLog) {
|
||||||
log.debug(`【server upgrade, ssl: ${ssl}】\r\n----- req -----\r\n`, req)
|
log.debug(`【server upgrade, ssl: ${ssl}】\r\n----- req -----\r\n`, req)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`【server upgrade, ssl: ${ssl}】`, req.url)
|
log.info(`【server upgrade, ssl: ${ssl}】`, req.url)
|
||||||
}
|
}
|
||||||
upgradeHandler(req, cltSocket, head, ssl)
|
upgradeHandler(req, cltSocket, head, ssl)
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,8 @@ module.exports = class CertAndKeyContainer {
|
||||||
if (fast) {
|
if (fast) {
|
||||||
certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
certObj = tlsUtils.createFakeCertificateByDomain(this.caKey, this.caCert, hostname)
|
||||||
_resolve(certObj)
|
_resolve(certObj)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// 这个太慢了
|
// 这个太慢了
|
||||||
// const preReq = https.request({
|
// const preReq = https.request({
|
||||||
// port: port,
|
// port: port,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
const http = require('http')
|
const http = require('node:http')
|
||||||
const https = require('https')
|
const https = require('node:https')
|
||||||
const forge = require('node-forge')
|
const forge = require('node-forge')
|
||||||
const CertAndKeyContainer = require('./CertAndKeyContainer')
|
const CertAndKeyContainer = require('./CertAndKeyContainer')
|
||||||
const tlsUtils = require('./tlsUtils')
|
const tlsUtils = require('./tlsUtils')
|
||||||
|
|
||||||
const pki = forge.pki
|
const pki = forge.pki
|
||||||
// const colors = require('colors')
|
// const colors = require('colors')
|
||||||
const tls = require('tls')
|
const tls = require('node:tls')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
const compatible = require('../compatible/compatible')
|
const compatible = require('../compatible/compatible')
|
||||||
|
|
||||||
|
|
@ -38,7 +38,8 @@ module.exports = class FakeServersCenter {
|
||||||
try {
|
try {
|
||||||
log.info('超过最大服务数量,删除旧服务。delServerObj:', delServerObj)
|
log.info('超过最大服务数量,删除旧服务。delServerObj:', delServerObj)
|
||||||
delServerObj.serverObj.server.close()
|
delServerObj.serverObj.server.close()
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
log.error('`delServerObj.serverObj.server.close()` error:', e)
|
log.error('`delServerObj.serverObj.server.close()` error:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +50,8 @@ module.exports = class FakeServersCenter {
|
||||||
getServerPromise (hostname, port, ssl, manualCompatibleConfig) {
|
getServerPromise (hostname, port, ssl, manualCompatibleConfig) {
|
||||||
if (port === 443 || port === 80) {
|
if (port === 443 || port === 80) {
|
||||||
ssl = port === 443
|
ssl = port === 443
|
||||||
} else if (ssl) {
|
}
|
||||||
|
else if (ssl) {
|
||||||
// 自动兼容程序:1
|
// 自动兼容程序:1
|
||||||
const compatibleConfig = compatible.getConnectCompatibleConfig(hostname, port, manualCompatibleConfig)
|
const compatibleConfig = compatible.getConnectCompatibleConfig(hostname, port, manualCompatibleConfig)
|
||||||
if (compatibleConfig && compatibleConfig.ssl != null) {
|
if (compatibleConfig && compatibleConfig.ssl != null) {
|
||||||
|
|
@ -105,7 +107,8 @@ module.exports = class FakeServersCenter {
|
||||||
})()
|
})()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
fakeServer = new http.Server()
|
fakeServer = new http.Server()
|
||||||
}
|
}
|
||||||
const serverObj = {
|
const serverObj = {
|
||||||
|
|
@ -146,7 +149,8 @@ module.exports = class FakeServersCenter {
|
||||||
fakeServer.on('upgrade', (req, socket, head) => {
|
fakeServer.on('upgrade', (req, socket, head) => {
|
||||||
if (printDebugLog) {
|
if (printDebugLog) {
|
||||||
log.debug(`【fakeServer upgrade - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- socket -----\r\n', socket, '\r\n----- head -----\r\n', head)
|
log.debug(`【fakeServer upgrade - ${hostname}:${port}】\r\n----- req -----\r\n`, req, '\r\n----- socket -----\r\n', socket, '\r\n----- head -----\r\n', head)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.info(`【fakeServer upgrade - ${hostname}:${port}】`, req.url)
|
log.info(`【fakeServer upgrade - ${hostname}:${port}】`, req.url)
|
||||||
}
|
}
|
||||||
this.upgradeHandler(req, socket, head, ssl)
|
this.upgradeHandler(req, socket, head, ssl)
|
||||||
|
|
@ -165,7 +169,8 @@ module.exports = class FakeServersCenter {
|
||||||
if (ssl === true && err.code.indexOf('ERR_SSL_') === 0) {
|
if (ssl === true && err.code.indexOf('ERR_SSL_') === 0) {
|
||||||
compatible.setConnectSsl(hostname, port, false)
|
compatible.setConnectSsl(hostname, port, false)
|
||||||
log.error(`自动兼容程序:SSL异常,现设置为禁用ssl: ${hostname}:${port}, ssl = false`)
|
log.error(`自动兼容程序:SSL异常,现设置为禁用ssl: ${hostname}:${port}, ssl = false`)
|
||||||
} else if (ssl === false && err.code === 'HPE_INVALID_METHOD') {
|
}
|
||||||
|
else if (ssl === false && err.code === 'HPE_INVALID_METHOD') {
|
||||||
compatible.setConnectSsl(hostname, port, true)
|
compatible.setConnectSsl(hostname, port, true)
|
||||||
log.error(`自动兼容程序:${err.code},现设置为启用ssl: ${hostname}:${port}, ssl = true`)
|
log.error(`自动兼容程序:${err.code},现设置为启用ssl: ${hostname}:${port}, ssl = true`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,11 +172,13 @@ module.exports = function extractSNI (data) {
|
||||||
end: n + nameLength,
|
end: n + nameLength,
|
||||||
length: nameLength,
|
length: nameLength,
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
n += nameLength
|
n += nameLength
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // ExtensionType was something we are not interested in
|
}
|
||||||
|
else { // ExtensionType was something we are not interested in
|
||||||
pos += extensionSize
|
pos += extensionSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const fs = require('fs')
|
const fs = require('node:fs')
|
||||||
const path = require('path')
|
const path = require('node:path')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const forge = require('node-forge')
|
const forge = require('node-forge')
|
||||||
const log = require('../../../utils/util.log')
|
const log = require('../../../utils/util.log')
|
||||||
|
|
@ -244,7 +244,8 @@ utils.initCA = function ({ caCertPath, caKeyPath }) {
|
||||||
caKeyPath,
|
caKeyPath,
|
||||||
create: false,
|
create: false,
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
const caObj = utils.createCA(config.caName)
|
const caObj = utils.createCA(config.caName)
|
||||||
|
|
||||||
const caCert = caObj.cert
|
const caCert = caObj.cert
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue