Skip to content

Commit f89921a

Browse files
committed
feat: Surge 支持 Snell v6(v6 不支持 obfs, 将自动过滤)
1 parent 43225c0 commit f89921a

3 files changed

Lines changed: 67 additions & 19 deletions

File tree

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sub-store",
3-
"version": "2.24.17",
3+
"version": "2.24.19",
44
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
55
"main": "src/main.js",
66
"packageManager": "pnpm@11.0.9",

backend/src/core/proxy-utils/producers/surge.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ function warnMaxStreamsIfNeeded(proxy) {
9696
);
9797
}
9898

99+
function hasSnellObfs(proxy) {
100+
return (
101+
isPresent(proxy, 'obfs-opts.mode') ||
102+
isPresent(proxy, 'obfs-opts.host') ||
103+
isPresent(proxy, 'obfs-opts.path')
104+
);
105+
}
106+
107+
function isUnsupportedSnellV6Obfs(proxy) {
108+
return Number(proxy.version) === 6 && hasSnellObfs(proxy);
109+
}
110+
99111
export default function Surge_Producer() {
100112
const produce = (proxy, type, opts = {}) => {
101113
if (
@@ -923,6 +935,13 @@ function formatHeaderMap(headers, separator) {
923935
}
924936

925937
function snell(proxy) {
938+
if (isUnsupportedSnellV6Obfs(proxy)) {
939+
$.error(
940+
`Platform ${targetPlatform} does not support Snell version ${proxy.version} with obfs`,
941+
);
942+
return '';
943+
}
944+
926945
const result = new Result(proxy);
927946
result.append(`${proxy.name}=${proxy.type},${proxy.server},${proxy.port}`);
928947
result.appendIfPresent(`,version=${proxy.version}`, 'version');

backend/src/test/proxy-producers/text.spec.js

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,47 @@ describe('Proxy text producers', function () {
807807
);
808808
});
809809

810+
it('produces Surge Snell v6 and filters v6 obfs', function () {
811+
const { result: output, errors } = captureErrors(() =>
812+
ProxyUtils.produce(
813+
[
814+
{
815+
type: 'snell',
816+
name: 'Surge Snell v6',
817+
server: 'snell.example.com',
818+
port: 443,
819+
psk: 'secret',
820+
version: 6,
821+
udp: true,
822+
},
823+
{
824+
type: 'snell',
825+
name: 'Surge Snell v6 Obfs',
826+
server: 'snell.example.com',
827+
port: 443,
828+
psk: 'secret',
829+
version: 6,
830+
udp: true,
831+
'obfs-opts': {
832+
mode: 'tls',
833+
host: 'obfs.example.com',
834+
path: '/snell',
835+
},
836+
},
837+
],
838+
'Surge',
839+
'external',
840+
),
841+
);
842+
843+
expect(output).to.equal(
844+
'Surge Snell v6=snell,snell.example.com,443,version=6,psk="secret",udp-relay=true',
845+
);
846+
expect(errors).to.deep.equal([
847+
'Platform Surge does not support Snell version 6 with obfs',
848+
]);
849+
});
850+
810851
it('omits Surge TLS-only params for plain HTTP, SOCKS5, and VMess nodes', function () {
811852
const cases = [
812853
{
@@ -2791,16 +2832,10 @@ describe('Proxy text producers', function () {
27912832
expect(
27922833
reparsed[0]['xhttp-opts']?.['download-settings']?.server,
27932834
).to.equal('download.example.com');
2794-
expect(reparsed[0]['xhttp-opts']?.['session-table']).to.equal(
2795-
'Base62',
2796-
);
2797-
expect(reparsed[0]['xhttp-opts']?.['session-length']).to.equal(
2798-
'16-32',
2799-
);
2835+
expect(reparsed[0]['xhttp-opts']?.['session-table']).to.equal('Base62');
2836+
expect(reparsed[0]['xhttp-opts']?.['session-length']).to.equal('16-32');
28002837
expect(
2801-
reparsed[0]['xhttp-opts']?.['download-settings']?.[
2802-
'session-table'
2803-
],
2838+
reparsed[0]['xhttp-opts']?.['download-settings']?.['session-table'],
28042839
).to.equal('abcXYZ012');
28052840
expect(
28062841
reparsed[0]['xhttp-opts']?.['download-settings']?.[
@@ -4407,12 +4442,8 @@ describe('Proxy text producers', function () {
44074442
expect(
44084443
reparsed[0]['xhttp-opts']?.['sc-min-posts-interval-ms'],
44094444
).to.equal('0-300');
4410-
expect(reparsed[0]['xhttp-opts']?.['session-table']).to.equal(
4411-
'Base62',
4412-
);
4413-
expect(reparsed[0]['xhttp-opts']?.['session-length']).to.equal(
4414-
'16-32',
4415-
);
4445+
expect(reparsed[0]['xhttp-opts']?.['session-table']).to.equal('Base62');
4446+
expect(reparsed[0]['xhttp-opts']?.['session-length']).to.equal('16-32');
44164447
expect(
44174448
reparsed[0]['xhttp-opts']?.['download-settings']?.[
44184449
'sc-max-each-post-bytes'
@@ -4424,9 +4455,7 @@ describe('Proxy text producers', function () {
44244455
],
44254456
).to.equal('0-300');
44264457
expect(
4427-
reparsed[0]['xhttp-opts']?.['download-settings']?.[
4428-
'session-table'
4429-
],
4458+
reparsed[0]['xhttp-opts']?.['download-settings']?.['session-table'],
44304459
).to.equal('abcXYZ012');
44314460
expect(
44324461
reparsed[0]['xhttp-opts']?.['download-settings']?.[

0 commit comments

Comments
 (0)