From b3d66d42ffb2adc94f569ed9951b4cbb824d24fb Mon Sep 17 00:00:00 2001 From: xream Date: Sat, 19 Jul 2025 06:47:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=84=E7=90=86=20clash=20=E7=B3=BB?= =?UTF-8?q?=E5=92=8C=20sing-box=20=E7=9A=84=20Early=20Data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 2 +- backend/src/core/proxy-utils/producers/clash.js | 12 ++++++++++++ backend/src/core/proxy-utils/producers/clashmeta.js | 12 ++++++++++++ .../src/core/proxy-utils/producers/shadowrocket.js | 12 ++++++++++++ backend/src/core/proxy-utils/producers/sing-box.js | 9 ++++++++- backend/src/core/proxy-utils/producers/stash.js | 12 ++++++++++++ 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/backend/package.json b/backend/package.json index 8443377..40852c7 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.19.86", + "version": "2.19.87", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/core/proxy-utils/producers/clash.js b/backend/src/core/proxy-utils/producers/clash.js index b117f12..e31d932 100644 --- a/backend/src/core/proxy-utils/producers/clash.js +++ b/backend/src/core/proxy-utils/producers/clash.js @@ -134,6 +134,18 @@ export default function Clash_Producer() { proxy['h2-opts'].headers.host = [host]; } } + if (proxy.network === 'ws') { + const wsPath = proxy['ws-opts']?.path; + const reg = /^(.*?)(?:\?ed=(\d+))?$/; + // eslint-disable-next-line no-unused-vars + const [_, path = '', ed = ''] = reg.exec(wsPath); + proxy['ws-opts'].path = path; + if (ed !== '') { + proxy['ws-opts']['early-data-header-name'] = + 'Sec-WebSocket-Protocol'; + proxy['ws-opts']['max-early-data'] = parseInt(ed, 10); + } + } if (proxy['plugin-opts']?.tls) { if (isPresent(proxy, 'skip-cert-verify')) { proxy['plugin-opts']['skip-cert-verify'] = diff --git a/backend/src/core/proxy-utils/producers/clashmeta.js b/backend/src/core/proxy-utils/producers/clashmeta.js index a76d299..a04ebfe 100644 --- a/backend/src/core/proxy-utils/producers/clashmeta.js +++ b/backend/src/core/proxy-utils/producers/clashmeta.js @@ -198,6 +198,18 @@ export default function ClashMeta_Producer() { proxy['h2-opts'].headers.host = [host]; } } + if (proxy.network === 'ws') { + const wsPath = proxy['ws-opts']?.path; + const reg = /^(.*?)(?:\?ed=(\d+))?$/; + // eslint-disable-next-line no-unused-vars + const [_, path = '', ed = ''] = reg.exec(wsPath); + proxy['ws-opts'].path = path; + if (ed !== '') { + proxy['ws-opts']['early-data-header-name'] = + 'Sec-WebSocket-Protocol'; + proxy['ws-opts']['max-early-data'] = parseInt(ed, 10); + } + } if (proxy['plugin-opts']?.tls) { if (isPresent(proxy, 'skip-cert-verify')) { diff --git a/backend/src/core/proxy-utils/producers/shadowrocket.js b/backend/src/core/proxy-utils/producers/shadowrocket.js index 788276b..291d882 100644 --- a/backend/src/core/proxy-utils/producers/shadowrocket.js +++ b/backend/src/core/proxy-utils/producers/shadowrocket.js @@ -166,6 +166,18 @@ export default function Shadowrocket_Producer() { proxy['h2-opts'].headers.host = [host]; } } + if (proxy.network === 'ws') { + const wsPath = proxy['ws-opts']?.path; + const reg = /^(.*?)(?:\?ed=(\d+))?$/; + // eslint-disable-next-line no-unused-vars + const [_, path = '', ed = ''] = reg.exec(wsPath); + proxy['ws-opts'].path = path; + if (ed !== '') { + proxy['ws-opts']['early-data-header-name'] = + 'Sec-WebSocket-Protocol'; + proxy['ws-opts']['max-early-data'] = parseInt(ed, 10); + } + } if (proxy['plugin-opts']?.tls) { if (isPresent(proxy, 'skip-cert-verify')) { proxy['plugin-opts']['skip-cert-verify'] = diff --git a/backend/src/core/proxy-utils/producers/sing-box.js b/backend/src/core/proxy-utils/producers/sing-box.js index a694de9..36e45b7 100644 --- a/backend/src/core/proxy-utils/producers/sing-box.js +++ b/backend/src/core/proxy-utils/producers/sing-box.js @@ -71,7 +71,14 @@ const smuxParser = (smux, proxy) => { const wsParser = (proxy, parsedProxy) => { const transport = { type: 'ws', headers: {} }; if (proxy['ws-opts']) { - const { path: wsPath = '', headers: wsHeaders = {} } = proxy['ws-opts']; + const { + path: wsPath = '', + headers: wsHeaders = {}, + 'max-early-data': max_early_data, + 'early-data-header-name': early_data_header_name, + } = proxy['ws-opts']; + transport.early_data_header_name = early_data_header_name; + transport.max_early_data = parseInt(max_early_data, 10); if (wsPath !== '') transport.path = `${wsPath}`; if (Object.keys(wsHeaders).length > 0) { const headers = {}; diff --git a/backend/src/core/proxy-utils/producers/stash.js b/backend/src/core/proxy-utils/producers/stash.js index a87c8c0..b4f8201 100644 --- a/backend/src/core/proxy-utils/producers/stash.js +++ b/backend/src/core/proxy-utils/producers/stash.js @@ -238,6 +238,18 @@ export default function Stash_Producer() { proxy['h2-opts'].headers.host = [host]; } } + if (proxy.network === 'ws') { + const wsPath = proxy['ws-opts']?.path; + const reg = /^(.*?)(?:\?ed=(\d+))?$/; + // eslint-disable-next-line no-unused-vars + const [_, path = '', ed = ''] = reg.exec(wsPath); + proxy['ws-opts'].path = path; + if (ed !== '') { + proxy['ws-opts']['early-data-header-name'] = + 'Sec-WebSocket-Protocol'; + proxy['ws-opts']['max-early-data'] = parseInt(ed, 10); + } + } if (proxy['plugin-opts']?.tls) { if (isPresent(proxy, 'skip-cert-verify')) { proxy['plugin-opts']['skip-cert-verify'] =