hiddifypanel 9.0.0.dev92__py3-none-any.whl → 10.5.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hiddifypanel/VERSION +1 -1
- hiddifypanel/VERSION.py +2 -2
- hiddifypanel/auth.py +30 -9
- hiddifypanel/base.py +58 -50
- hiddifypanel/cache.py +43 -25
- hiddifypanel/database.py +9 -0
- hiddifypanel/drivers/abstract_driver.py +2 -0
- hiddifypanel/drivers/singbox_api.py +17 -15
- hiddifypanel/drivers/ssh_liberty_bridge_api.py +3 -1
- hiddifypanel/drivers/user_driver.py +12 -6
- hiddifypanel/drivers/wireguard_api.py +7 -2
- hiddifypanel/drivers/xray_api.py +14 -9
- hiddifypanel/hutils/__init__.py +4 -0
- hiddifypanel/hutils/convert.py +13 -2
- hiddifypanel/hutils/crypto.py +48 -0
- hiddifypanel/hutils/encode.py +4 -1
- hiddifypanel/hutils/flask.py +38 -5
- hiddifypanel/hutils/github_issue.py +1 -1
- hiddifypanel/hutils/importer/xui.py +5 -2
- hiddifypanel/{models/utils.py → hutils/model.py} +14 -4
- hiddifypanel/hutils/network/auto_ip_selector.py +2 -0
- hiddifypanel/hutils/network/net.py +46 -2
- hiddifypanel/hutils/node/__init__.py +3 -0
- hiddifypanel/hutils/node/api_client.py +76 -0
- hiddifypanel/hutils/node/child.py +147 -0
- hiddifypanel/hutils/node/parent.py +100 -0
- hiddifypanel/hutils/node/shared.py +65 -0
- hiddifypanel/hutils/proxy/__init__.py +5 -0
- hiddifypanel/hutils/proxy/clash.py +161 -0
- hiddifypanel/hutils/proxy/shared.py +434 -0
- hiddifypanel/hutils/proxy/singbox.py +339 -0
- hiddifypanel/hutils/proxy/xray.py +235 -0
- hiddifypanel/hutils/proxy/xrayjson.py +391 -0
- hiddifypanel/hutils/random.py +4 -0
- hiddifypanel/hutils/utils.py +4 -1
- hiddifypanel/models/__init__.py +2 -2
- hiddifypanel/models/admin.py +31 -17
- hiddifypanel/models/base_account.py +7 -7
- hiddifypanel/models/child.py +30 -16
- hiddifypanel/models/config.py +45 -16
- hiddifypanel/models/config_enum.py +68 -17
- hiddifypanel/models/domain.py +28 -20
- hiddifypanel/models/parent_domain.py +2 -2
- hiddifypanel/models/proxy.py +29 -20
- hiddifypanel/models/report.py +2 -3
- hiddifypanel/models/usage.py +2 -2
- hiddifypanel/models/user.py +33 -22
- hiddifypanel/panel/admin/Actions.py +13 -19
- hiddifypanel/panel/admin/AdminstratorAdmin.py +14 -3
- hiddifypanel/panel/admin/Dashboard.py +5 -10
- hiddifypanel/panel/admin/DomainAdmin.py +35 -48
- hiddifypanel/panel/admin/NodeAdmin.py +6 -2
- hiddifypanel/panel/admin/ProxyAdmin.py +6 -5
- hiddifypanel/panel/admin/QuickSetup.py +21 -20
- hiddifypanel/panel/admin/SettingAdmin.py +107 -62
- hiddifypanel/panel/admin/UserAdmin.py +22 -21
- hiddifypanel/panel/admin/templates/index.html +1 -1
- hiddifypanel/panel/admin/templates/model/user_list.html +44 -20
- hiddifypanel/panel/admin/templates/parent_dash.html +2 -4
- hiddifypanel/panel/admin/templates/result.html +2 -3
- hiddifypanel/panel/cf_api.py +1 -2
- hiddifypanel/panel/cli.py +16 -16
- hiddifypanel/panel/commercial/ProxyDetailsAdmin.py +16 -12
- hiddifypanel/panel/commercial/__init__.py +7 -5
- hiddifypanel/panel/commercial/restapi/v1/__init__.py +1 -1
- hiddifypanel/panel/commercial/restapi/v1/tgbot.py +1 -1
- hiddifypanel/panel/commercial/restapi/v1/tgmsg.py +14 -10
- hiddifypanel/panel/commercial/restapi/v2/admin/__init__.py +0 -5
- hiddifypanel/panel/commercial/restapi/v2/admin/admin_info_api.py +2 -2
- hiddifypanel/panel/commercial/restapi/v2/admin/admin_log_api.py +4 -5
- hiddifypanel/panel/commercial/restapi/v2/admin/admin_user_api.py +8 -25
- hiddifypanel/panel/commercial/restapi/v2/admin/admin_users_api.py +4 -4
- hiddifypanel/panel/commercial/restapi/v2/admin/schema.py +157 -0
- hiddifypanel/panel/commercial/restapi/v2/admin/server_status_api.py +3 -3
- hiddifypanel/panel/commercial/restapi/v2/admin/user_api.py +9 -66
- hiddifypanel/panel/commercial/restapi/v2/admin/users_api.py +1 -1
- hiddifypanel/panel/commercial/restapi/v2/child/__init__.py +18 -0
- hiddifypanel/panel/commercial/restapi/v2/child/actions.py +63 -0
- hiddifypanel/panel/commercial/restapi/v2/child/register_parent_api.py +34 -0
- hiddifypanel/panel/commercial/restapi/v2/child/schema.py +7 -0
- hiddifypanel/panel/commercial/restapi/v2/child/sync_parent_api.py +21 -0
- hiddifypanel/panel/commercial/restapi/v2/panel/__init__.py +13 -0
- hiddifypanel/panel/commercial/restapi/v2/panel/info.py +18 -0
- hiddifypanel/panel/commercial/restapi/v2/panel/ping_pong.py +23 -0
- hiddifypanel/panel/commercial/restapi/v2/panel/schema.py +7 -0
- hiddifypanel/panel/commercial/restapi/v2/parent/__init__.py +16 -0
- hiddifypanel/panel/commercial/restapi/v2/parent/register_api.py +65 -0
- hiddifypanel/panel/commercial/restapi/v2/parent/schema.py +115 -0
- hiddifypanel/panel/commercial/restapi/v2/parent/status_api.py +26 -0
- hiddifypanel/panel/commercial/restapi/v2/parent/sync_api.py +53 -0
- hiddifypanel/panel/commercial/restapi/v2/parent/usage_api.py +57 -0
- hiddifypanel/panel/commercial/restapi/v2/user/apps_api.py +17 -23
- hiddifypanel/panel/commercial/restapi/v2/user/configs_api.py +23 -26
- hiddifypanel/panel/commercial/telegrambot/admin.py +1 -2
- hiddifypanel/panel/common.py +25 -8
- hiddifypanel/panel/common_bp/login.py +2 -2
- hiddifypanel/panel/hiddify.py +22 -185
- hiddifypanel/panel/init_db.py +102 -55
- hiddifypanel/panel/usage.py +33 -18
- hiddifypanel/panel/user/__init__.py +0 -1
- hiddifypanel/panel/user/templates/all_configs copy.txt +2 -2
- hiddifypanel/panel/user/templates/all_configs.txt +2 -2
- hiddifypanel/panel/user/templates/base_singbox_config.json.j2 +2 -1
- hiddifypanel/panel/user/templates/base_xray_config.json.j2 +125 -0
- hiddifypanel/panel/user/templates/clash_config copy.yml +1 -1
- hiddifypanel/panel/user/templates/clash_config.yml +4 -4
- hiddifypanel/panel/user/templates/clash_proxies.yml +1 -1
- hiddifypanel/panel/user/templates/home/all-configs.html +2 -2
- hiddifypanel/panel/user/templates/home/all-configs_old.html +1 -1
- hiddifypanel/panel/user/templates/home/ios copy.html +2 -2
- hiddifypanel/panel/user/templates/home/usage.html +1 -1
- hiddifypanel/panel/user/templates/new.html +2 -2
- hiddifypanel/panel/user/user.py +56 -50
- hiddifypanel/static/css/custom.css +31 -0
- hiddifypanel/static/images/favicon.ico +0 -0
- hiddifypanel/static/images/hiddify-old.png +0 -0
- hiddifypanel/static/images/hiddify.png +0 -0
- hiddifypanel/static/images/hiddify2.png +0 -0
- hiddifypanel/static/new/assets/{index-1b891a7c.js → index-ccb9873c.js} +56 -56
- hiddifypanel/static/new/assets/index-fa00de9a.css +1 -0
- hiddifypanel/static/new/i18n/en.json +6 -6
- hiddifypanel/static/new/i18n/fa.json +2 -2
- hiddifypanel/templates/admin-layout.html +30 -43
- hiddifypanel/templates/fake.html +0 -4
- hiddifypanel/templates/flaskadmin-layout.html +7 -3
- hiddifypanel/templates/master.html +11 -6
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +2082 -1977
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +2035 -1924
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +1911 -1848
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +2019 -1874
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +1873 -1742
- hiddifypanel/translations.i18n/en.json +992 -933
- hiddifypanel/translations.i18n/fa.json +994 -935
- hiddifypanel/translations.i18n/pt.json +1031 -972
- hiddifypanel/translations.i18n/ru.json +994 -935
- hiddifypanel/translations.i18n/zh.json +971 -912
- {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.5.0.dev0.dist-info}/METADATA +47 -47
- {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.5.0.dev0.dist-info}/RECORD +147 -120
- {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.5.0.dev0.dist-info}/WHEEL +1 -1
- hiddifypanel/panel/commercial/restapi/v2/DTO.py +0 -9
- hiddifypanel/panel/commercial/restapi/v2/hello/__init__.py +0 -16
- hiddifypanel/panel/commercial/restapi/v2/hello/hello.py +0 -32
- hiddifypanel/panel/user/link_maker.py +0 -1083
- hiddifypanel/static/new/assets/index-669b32c8.css +0 -1
- {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.5.0.dev0.dist-info}/LICENSE.md +0 -0
- {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.5.0.dev0.dist-info}/entry_points.txt +0 -0
- {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.5.0.dev0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,161 @@
|
|
1
|
+
import yaml
|
2
|
+
from hiddifypanel.models import Proxy, ProxyCDN, ProxyL3, ProxyProto, ProxyTransport, Domain
|
3
|
+
from hiddifypanel import hutils
|
4
|
+
|
5
|
+
|
6
|
+
def get_clash_config_names(meta_or_normal, domains: list[Domain]):
|
7
|
+
allp = []
|
8
|
+
for pinfo in hutils.proxy.get_valid_proxies(domains):
|
9
|
+
clash = to_clash(pinfo, meta_or_normal)
|
10
|
+
if 'msg' not in clash:
|
11
|
+
allp.append(clash['name'])
|
12
|
+
|
13
|
+
return yaml.dump(allp, sort_keys=False)
|
14
|
+
|
15
|
+
|
16
|
+
def get_all_clash_configs(meta_or_normal, domains: list[Domain]):
|
17
|
+
allp = []
|
18
|
+
for pinfo in hutils.proxy.get_valid_proxies(domains):
|
19
|
+
clash = to_clash(pinfo, meta_or_normal)
|
20
|
+
if 'msg' not in clash:
|
21
|
+
allp.append(clash)
|
22
|
+
|
23
|
+
return yaml.dump({"proxies": allp}, sort_keys=False)
|
24
|
+
|
25
|
+
# def to_clash_yml(proxy):
|
26
|
+
# return yaml.dump(to_clash(proxy,'normal'))
|
27
|
+
|
28
|
+
|
29
|
+
def to_clash(proxy, meta_or_normal):
|
30
|
+
|
31
|
+
name = proxy['name']
|
32
|
+
if proxy['l3'] == "kcp":
|
33
|
+
return {'name': name, 'msg': "clash does not support kcp", 'type': 'debug'}
|
34
|
+
if proxy['proto'] == "ssh":
|
35
|
+
return {'name': name, 'msg': "clash does not support ssh", 'type': 'debug'}
|
36
|
+
if meta_or_normal == "normal":
|
37
|
+
if proxy['proto'] in ["vless", 'tuic', 'hysteria2']:
|
38
|
+
return {'name': name, 'msg': f"{proxy['proto']} not supported in clash", 'type': 'debug'}
|
39
|
+
if proxy.get('flow'):
|
40
|
+
return {'name': name, 'msg': "xtls not supported in clash", 'type': 'debug'}
|
41
|
+
if proxy['transport'] == "shadowtls":
|
42
|
+
return {'name': name, 'msg': "shadowtls not supported in clash", 'type': 'debug'}
|
43
|
+
if proxy['l3'] == ProxyL3.tls_h2 and proxy['proto'] in [ProxyProto.vmess, ProxyProto.vless] and proxy['dbe'].cdn == ProxyCDN.direct:
|
44
|
+
return {'name': name, 'msg': "bug tls_h2 vmess and vless in clash meta", 'type': 'warning'}
|
45
|
+
base = {}
|
46
|
+
# vmess ws
|
47
|
+
base["name"] = f"""{proxy['extra_info']} {proxy["name"]} § {proxy['port']} {proxy["dbdomain"].id}"""
|
48
|
+
base["type"] = str(proxy["proto"])
|
49
|
+
base["server"] = proxy["server"]
|
50
|
+
base["port"] = proxy["port"]
|
51
|
+
base['alpn'] = proxy['alpn'].split(',')
|
52
|
+
if proxy["proto"] == "ssr":
|
53
|
+
base["cipher"] = proxy["cipher"]
|
54
|
+
base["password"] = proxy["uuid"]
|
55
|
+
base["udp"] = True
|
56
|
+
base["obfs"] = proxy["ssr-obfs"]
|
57
|
+
base["protocol"] = proxy["ssr-protocol"]
|
58
|
+
base["obfs-param"] = proxy["fakedomain"]
|
59
|
+
return base
|
60
|
+
elif proxy["proto"] == "tuic":
|
61
|
+
base["uuid"] = proxy["uuid"]
|
62
|
+
base["password"] = proxy["uuid"]
|
63
|
+
base["disable-sni"] = proxy['allow_insecure']
|
64
|
+
base["reduce-rtt"] = True
|
65
|
+
base["request-timeout"] = 8000
|
66
|
+
base["udp-relay-mode"] = 'native'
|
67
|
+
base["congestion-controller"] = 'cubic'
|
68
|
+
base['sni'] = proxy['sni']
|
69
|
+
return base
|
70
|
+
elif proxy["proto"] in ["ss", "v2ray"]:
|
71
|
+
base["cipher"] = proxy["cipher"]
|
72
|
+
base["password"] = proxy["password"]
|
73
|
+
base["udp_over_tcp"] = True
|
74
|
+
if proxy["transport"] == "faketls":
|
75
|
+
base["plugin"] = "obfs"
|
76
|
+
base["plugin-opts"] = {
|
77
|
+
"mode": 'tls',
|
78
|
+
"host": proxy["fakedomain"]
|
79
|
+
}
|
80
|
+
elif proxy["transport"] == "shadowtls":
|
81
|
+
base["plugin"] = "shadow-tls"
|
82
|
+
base["plugin-opts"] = {
|
83
|
+
"host": proxy["fakedomain"],
|
84
|
+
"password": proxy["proxy_path"],
|
85
|
+
"version": 3 # support 1/2/3
|
86
|
+
|
87
|
+
}
|
88
|
+
|
89
|
+
elif proxy["proto"] == "v2ray":
|
90
|
+
base["plugin"] = "v2ray-plugin"
|
91
|
+
base["type"] = "ss"
|
92
|
+
base["plugin-opts"] = {
|
93
|
+
"mode": "websocket",
|
94
|
+
"tls": "tls" in proxy["l3"],
|
95
|
+
"skip-cert-verify": proxy["mode"] == "Fake" or proxy['allow_insecure'],
|
96
|
+
"host": proxy['sni'],
|
97
|
+
"path": proxy["path"]
|
98
|
+
}
|
99
|
+
return base
|
100
|
+
elif proxy["proto"] == "trojan":
|
101
|
+
base["password"] = proxy["uuid"]
|
102
|
+
base["sni"] = proxy["sni"]
|
103
|
+
|
104
|
+
else:
|
105
|
+
base["uuid"] = proxy["uuid"]
|
106
|
+
base["servername"] = proxy["sni"]
|
107
|
+
base["tls"] = "tls" in proxy["l3"] or "reality" in proxy["l3"]
|
108
|
+
if meta_or_normal == "meta":
|
109
|
+
base['client-fingerprint'] = proxy['fingerprint']
|
110
|
+
if proxy.get('flow'):
|
111
|
+
base["flow"] = proxy['flow']
|
112
|
+
# base["flow-show"] = True
|
113
|
+
|
114
|
+
if proxy["proto"] == "vmess":
|
115
|
+
base["alterId"] = 0
|
116
|
+
base["cipher"] = proxy["cipher"]
|
117
|
+
base["udp"] = True
|
118
|
+
|
119
|
+
base["skip-cert-verify"] = proxy["mode"] == "Fake"
|
120
|
+
|
121
|
+
base["network"] = proxy["transport"]
|
122
|
+
|
123
|
+
if base["network"] == "ws":
|
124
|
+
base["ws-opts"] = {
|
125
|
+
"path": proxy["path"]
|
126
|
+
}
|
127
|
+
if "host" in proxy:
|
128
|
+
base["ws-opts"]["headers"] = {"Host": proxy["host"]}
|
129
|
+
|
130
|
+
if base["network"] == "tcp" and proxy['alpn'] != 'h2':
|
131
|
+
if proxy['transport'] != ProxyTransport.XTLS:
|
132
|
+
base["network"] = "http"
|
133
|
+
|
134
|
+
if "path" in proxy:
|
135
|
+
base["http-opts"] = {
|
136
|
+
"path": [proxy["path"]]
|
137
|
+
}
|
138
|
+
if 'host' in proxy:
|
139
|
+
base["http-opts"]["host"] = [proxy["host"]]
|
140
|
+
if base["network"] == "tcp" and proxy['alpn'] == 'h2':
|
141
|
+
base["network"] = "h2"
|
142
|
+
|
143
|
+
if "path" in proxy:
|
144
|
+
base["h2-opts"] = {
|
145
|
+
"path": proxy["path"]
|
146
|
+
}
|
147
|
+
if 'host' in proxy:
|
148
|
+
base["h2-opts"]["host"] = [proxy["host"]]
|
149
|
+
if base["network"] == "grpc":
|
150
|
+
base["grpc-opts"] = {
|
151
|
+
"grpc-service-name": proxy["grpc_service_name"]
|
152
|
+
}
|
153
|
+
if proxy['l3'] == ProxyL3.reality:
|
154
|
+
base["reality-opts"] = {
|
155
|
+
"public-key": proxy['reality_pbk'],
|
156
|
+
"short-id": proxy['reality_short_id'],
|
157
|
+
}
|
158
|
+
if proxy["transport"] != 'grpc':
|
159
|
+
base["network"] = 'tcp'
|
160
|
+
|
161
|
+
return base
|
@@ -0,0 +1,434 @@
|
|
1
|
+
from flask import current_app, request, g
|
2
|
+
import glob
|
3
|
+
import random
|
4
|
+
import re
|
5
|
+
import json
|
6
|
+
from ipaddress import IPv4Address, IPv6Address
|
7
|
+
from hiddifypanel.cache import cache
|
8
|
+
from hiddifypanel.models import Proxy, ProxyProto, ProxyL3, ProxyTransport, ProxyCDN, Domain, DomainType, ConfigEnum, hconfig, get_hconfigs
|
9
|
+
from hiddifypanel import hutils
|
10
|
+
|
11
|
+
|
12
|
+
def get_ssh_hostkeys(dojson=False) -> list[str] | str:
|
13
|
+
key_files = glob.glob(current_app.config['HIDDIFY_CONFIG_PATH'] + "/other/ssh/host_key/*_key.pub")
|
14
|
+
host_keys = []
|
15
|
+
for file_name in key_files:
|
16
|
+
with open(file_name, "r") as f:
|
17
|
+
host_key = f.read().strip()
|
18
|
+
host_key = host_key.split()
|
19
|
+
if len(host_key) > 2:
|
20
|
+
host_key = host_key[:2] # strip the hostname part
|
21
|
+
host_key = " ".join(host_key)
|
22
|
+
host_keys.append(host_key)
|
23
|
+
if dojson:
|
24
|
+
return json.dumps(host_keys)
|
25
|
+
return host_keys
|
26
|
+
|
27
|
+
|
28
|
+
def is_proxy_valid(proxy: Proxy, domain_db: Domain, port: int) -> dict | None:
|
29
|
+
name = proxy.name
|
30
|
+
l3 = proxy.l3
|
31
|
+
if not port:
|
32
|
+
return {'name': name, 'msg': "port not defined", 'type': 'error', 'proto': proxy.proto}
|
33
|
+
if "reality" not in l3 and domain_db.mode == DomainType.reality:
|
34
|
+
return {'name': name, 'msg': "reality proxy not in reality domain", 'type': 'debug', 'proto': proxy.proto}
|
35
|
+
|
36
|
+
if "reality" in l3 and domain_db.mode != DomainType.reality:
|
37
|
+
return {'name': name, 'msg': "reality proxy not in reality domain", 'type': 'debug', 'proto': proxy.proto}
|
38
|
+
|
39
|
+
if "reality" in l3 and domain_db.grpc and ProxyTransport.grpc != proxy.transport:
|
40
|
+
return {'name': name, 'msg': "reality proxy not in reality domain", 'type': 'debug', 'proto': proxy.proto}
|
41
|
+
|
42
|
+
if "reality" in l3 and (not domain_db.grpc) and ProxyTransport.grpc == proxy.transport:
|
43
|
+
return {'name': name, 'msg': "reality proxy not in reality domain", 'type': 'debug', 'proto': proxy.proto}
|
44
|
+
|
45
|
+
is_cdn = ProxyCDN.CDN == proxy.cdn or ProxyCDN.Fake == proxy.cdn
|
46
|
+
if is_cdn and domain_db.mode not in [DomainType.cdn, DomainType.auto_cdn_ip, DomainType.worker]:
|
47
|
+
# print("cdn proxy not in cdn domain", domain, name)
|
48
|
+
return {'name': name, 'msg': "cdn proxy not in cdn domain", 'type': 'debug', 'proto': proxy.proto}
|
49
|
+
|
50
|
+
if not is_cdn and domain_db.mode in [DomainType.cdn, DomainType.auto_cdn_ip, DomainType.worker]:
|
51
|
+
# print("not cdn proxy in cdn domain", domain, name, proxy.cdn)
|
52
|
+
return {'name': name, 'msg': "not cdn proxy in cdn domain", 'type': 'debug', 'proto': proxy.proto}
|
53
|
+
|
54
|
+
if proxy.cdn == ProxyCDN.relay and domain_db.mode not in [DomainType.relay]:
|
55
|
+
return {'name': name, 'msg': "relay proxy not in relay domain", 'type': 'debug', 'proto': proxy.proto}
|
56
|
+
|
57
|
+
if proxy.cdn != ProxyCDN.relay and domain_db.mode in [DomainType.relay]:
|
58
|
+
return {'name': name, 'msg': "relay proxy not in relay domain", 'type': 'debug', 'proto': proxy.proto}
|
59
|
+
|
60
|
+
if domain_db.mode == DomainType.worker and proxy.transport == ProxyTransport.grpc:
|
61
|
+
return {'name': name, 'msg': "worker does not support grpc", 'type': 'debug', 'proto': proxy.proto}
|
62
|
+
|
63
|
+
if domain_db.mode != DomainType.old_xtls_direct and "tls" in proxy.l3 and proxy.cdn == ProxyCDN.direct and proxy.transport in [ProxyTransport.tcp, ProxyTransport.XTLS]:
|
64
|
+
return {'name': name, 'msg': "only old_xtls_direct support this", 'type': 'debug', 'proto': proxy.proto}
|
65
|
+
|
66
|
+
if proxy.proto == "trojan" and not is_tls(l3):
|
67
|
+
return {'name': name, 'msg': "trojan but not tls", 'type': 'warning', 'proto': proxy.proto}
|
68
|
+
|
69
|
+
if l3 == "http" and ProxyTransport.XTLS in proxy.transport:
|
70
|
+
return {'name': name, 'msg': "http and xtls???", 'type': 'warning', 'proto': proxy.proto}
|
71
|
+
|
72
|
+
if l3 == "http" and proxy.proto in [ProxyProto.ss, ProxyProto.ssr]:
|
73
|
+
return {'name': name, 'msg': "http and ss or ssr???", 'type': 'warning', 'proto': proxy.proto}
|
74
|
+
|
75
|
+
|
76
|
+
def get_port(proxy: Proxy, hconfigs: dict, domain_db: Domain, ptls: int, phttp: int, pport: int | None) -> int:
|
77
|
+
l3 = proxy.l3
|
78
|
+
port = 443
|
79
|
+
if isinstance(phttp, str):
|
80
|
+
phttp = int(phttp) if phttp != "None" else None # type: ignore
|
81
|
+
if isinstance(ptls, str):
|
82
|
+
ptls = int(ptls) if ptls != "None" else None # type: ignore
|
83
|
+
if l3 == "kcp":
|
84
|
+
port = hconfigs[ConfigEnum.kcp_ports].split(",")[0]
|
85
|
+
elif proxy.proto == ProxyProto.wireguard:
|
86
|
+
port = hconfigs[ConfigEnum.wireguard_port]
|
87
|
+
elif proxy.proto == "tuic":
|
88
|
+
port = domain_db.internal_port_tuic
|
89
|
+
elif proxy.proto == "hysteria2":
|
90
|
+
port = domain_db.internal_port_hysteria2
|
91
|
+
elif l3 == 'ssh':
|
92
|
+
port = hconfigs[ConfigEnum.ssh_server_port]
|
93
|
+
elif is_tls(l3):
|
94
|
+
port = ptls
|
95
|
+
elif l3 == "http":
|
96
|
+
port = phttp
|
97
|
+
else:
|
98
|
+
port = int(pport) # type: ignore
|
99
|
+
return port
|
100
|
+
|
101
|
+
|
102
|
+
def is_tls(l3) -> bool:
|
103
|
+
return 'tls' in l3 or "reality" in l3
|
104
|
+
|
105
|
+
|
106
|
+
@cache.cache(ttl=300)
|
107
|
+
def get_proxies(child_id: int = 0, only_enabled=False) -> list['Proxy']:
|
108
|
+
proxies = Proxy.query.filter(Proxy.child_id == child_id).all()
|
109
|
+
proxies = [c for c in proxies if 'restls' not in c.transport]
|
110
|
+
# if not hconfig(ConfigEnum.tuic_enable, child_id):
|
111
|
+
# proxies = [c for c in proxies if c.proto != ProxyProto.tuic]
|
112
|
+
# if not hconfig(ConfigEnum.hysteria_enable, child_id):
|
113
|
+
# proxies = [c for c in proxies if c.proto != ProxyProto.hysteria2]
|
114
|
+
if not hconfig(ConfigEnum.shadowsocks2022_enable, child_id):
|
115
|
+
proxies = [c for c in proxies if 'shadowsocks' != c.transport]
|
116
|
+
|
117
|
+
if not hconfig(ConfigEnum.ssfaketls_enable, child_id):
|
118
|
+
proxies = [c for c in proxies if 'faketls' != c.transport]
|
119
|
+
if not hconfig(ConfigEnum.v2ray_enable, child_id):
|
120
|
+
proxies = [c for c in proxies if 'v2ray' != c.proto]
|
121
|
+
if not hconfig(ConfigEnum.shadowtls_enable, child_id):
|
122
|
+
proxies = [c for c in proxies if c.transport != 'shadowtls']
|
123
|
+
if not hconfig(ConfigEnum.ssr_enable, child_id):
|
124
|
+
proxies = [c for c in proxies if 'ssr' != c.proto]
|
125
|
+
if not hconfig(ConfigEnum.vmess_enable, child_id):
|
126
|
+
proxies = [c for c in proxies if 'vmess' not in c.proto]
|
127
|
+
if not hconfig(ConfigEnum.vless_enable, child_id):
|
128
|
+
proxies = [c for c in proxies if 'vless' not in c.proto]
|
129
|
+
if not hconfig(ConfigEnum.trojan_enable, child_id):
|
130
|
+
proxies = [c for c in proxies if 'trojan' not in c.proto]
|
131
|
+
if not hconfig(ConfigEnum.httpupgrade_enable, child_id):
|
132
|
+
proxies = [c for c in proxies if ProxyTransport.httpupgrade not in c.transport]
|
133
|
+
if not hconfig(ConfigEnum.ws_enable, child_id):
|
134
|
+
proxies = [c for c in proxies if ProxyTransport.WS not in c.transport]
|
135
|
+
if not hconfig(ConfigEnum.xtls_enable, child_id):
|
136
|
+
proxies = [c for c in proxies if ProxyTransport.XTLS not in c.transport]
|
137
|
+
if not hconfig(ConfigEnum.grpc_enable, child_id):
|
138
|
+
proxies = [c for c in proxies if ProxyTransport.grpc not in c.transport]
|
139
|
+
if not hconfig(ConfigEnum.tcp_enable, child_id):
|
140
|
+
proxies = [c for c in proxies if 'tcp' not in c.transport]
|
141
|
+
if not hconfig(ConfigEnum.h2_enable, child_id):
|
142
|
+
proxies = [c for c in proxies if 'h2' not in c.transport and c.l3 not in [ProxyL3.tls_h2_h1, ProxyL3.tls_h2]]
|
143
|
+
if not hconfig(ConfigEnum.kcp_enable, child_id):
|
144
|
+
proxies = [c for c in proxies if 'kcp' not in c.l3]
|
145
|
+
if not hconfig(ConfigEnum.reality_enable, child_id):
|
146
|
+
proxies = [c for c in proxies if 'reality' not in c.l3]
|
147
|
+
if not hconfig(ConfigEnum.quic_enable, child_id):
|
148
|
+
proxies = [c for c in proxies if 'h3_quic' not in c.l3]
|
149
|
+
if not hconfig(ConfigEnum.http_proxy_enable, child_id):
|
150
|
+
proxies = [c for c in proxies if 'http' != c.l3]
|
151
|
+
|
152
|
+
if not Domain.query.filter(Domain.mode.in_([DomainType.cdn, DomainType.auto_cdn_ip])).first():
|
153
|
+
proxies = [c for c in proxies if c.cdn != "CDN"]
|
154
|
+
|
155
|
+
if not Domain.query.filter(Domain.mode.in_([DomainType.relay])).first():
|
156
|
+
proxies = [c for c in proxies if c.cdn != ProxyCDN.relay]
|
157
|
+
|
158
|
+
if not Domain.query.filter(Domain.mode.in_([DomainType.cdn, DomainType.auto_cdn_ip]), Domain.servernames != "", Domain.servernames != Domain.domain).first():
|
159
|
+
proxies = [c for c in proxies if 'Fake' not in c.cdn]
|
160
|
+
proxies = [c for c in proxies if not ('vless' == c.proto and ProxyTransport.tcp == c.transport and c.cdn == ProxyCDN.direct)]
|
161
|
+
|
162
|
+
if only_enabled:
|
163
|
+
proxies = [p for p in proxies if p.enable]
|
164
|
+
return proxies
|
165
|
+
|
166
|
+
|
167
|
+
def get_valid_proxies(domains: list[Domain]) -> list[dict]:
|
168
|
+
allp = []
|
169
|
+
allphttp = [p for p in request.args.get("phttp", "").split(',') if p]
|
170
|
+
allptls = [p for p in request.args.get("ptls", "").split(',') if p]
|
171
|
+
added_ip = {}
|
172
|
+
configsmap = {}
|
173
|
+
proxeismap = {}
|
174
|
+
for domain in domains:
|
175
|
+
if domain.child_id not in configsmap:
|
176
|
+
configsmap[domain.child_id] = get_hconfigs(domain.child_id)
|
177
|
+
proxeismap[domain.child_id] = get_proxies(domain.child_id, only_enabled=True)
|
178
|
+
hconfigs = configsmap[domain.child_id]
|
179
|
+
|
180
|
+
ip = hutils.network.get_domain_ip(domain.domain, version=4)
|
181
|
+
ip6 = hutils.network.get_domain_ip(domain.domain, version=6)
|
182
|
+
ips = [x for x in [ip, ip6] if x is not None]
|
183
|
+
for proxy in proxeismap[domain.child_id]:
|
184
|
+
noDomainProxies = False
|
185
|
+
if proxy.proto in [ProxyProto.ssh, ProxyProto.wireguard]:
|
186
|
+
noDomainProxies = True
|
187
|
+
if proxy.proto in [ProxyProto.ss] and proxy.transport not in [ProxyTransport.grpc, ProxyTransport.h2, ProxyTransport.WS, ProxyTransport.httpupgrade]:
|
188
|
+
noDomainProxies = True
|
189
|
+
options = []
|
190
|
+
key = f'{proxy.proto}{proxy.transport}{proxy.cdn}{proxy.l3}'
|
191
|
+
if key not in added_ip:
|
192
|
+
added_ip[key] = {}
|
193
|
+
if proxy.proto in [ProxyProto.ssh, ProxyProto.tuic, ProxyProto.hysteria2, ProxyProto.wireguard, ProxyProto.ss]:
|
194
|
+
if noDomainProxies and all([x in added_ip[key] for x in ips]):
|
195
|
+
continue
|
196
|
+
|
197
|
+
for x in ips:
|
198
|
+
added_ip[key][x] = 1
|
199
|
+
|
200
|
+
if proxy.proto in [ProxyProto.ssh, ProxyProto.wireguard, ProxyProto.ss]:
|
201
|
+
if domain.mode == 'fake':
|
202
|
+
continue
|
203
|
+
if proxy.proto in [ProxyProto.ssh]:
|
204
|
+
options = [{'pport': hconfigs[ConfigEnum.ssh_server_port]}]
|
205
|
+
elif proxy.proto in [ProxyProto.wireguard]:
|
206
|
+
options = [{'pport': hconfigs[ConfigEnum.wireguard_port]}]
|
207
|
+
elif proxy.transport in [ProxyTransport.shadowsocks]:
|
208
|
+
options = [{'pport': hconfigs[ConfigEnum.shadowsocks2022_port]}]
|
209
|
+
elif proxy.proto in [ProxyProto.ss]:
|
210
|
+
options = [{'pport': 443}]
|
211
|
+
elif proxy.proto == ProxyProto.tuic:
|
212
|
+
options = [{'pport': hconfigs[ConfigEnum.tuic_port]}]
|
213
|
+
elif proxy.proto == ProxyProto.hysteria2:
|
214
|
+
options = [{'pport': hconfigs[ConfigEnum.hysteria_port]}]
|
215
|
+
else:
|
216
|
+
protos = ['http', 'tls'] if hconfigs.get(ConfigEnum.http_proxy_enable) else ['tls']
|
217
|
+
for t in protos:
|
218
|
+
for port in hconfigs[ConfigEnum.http_ports if t == 'http' else ConfigEnum.tls_ports].split(','):
|
219
|
+
phttp = port if t == 'http' else None
|
220
|
+
ptls = port if t == 'tls' else None
|
221
|
+
if phttp and len(allphttp) and phttp not in allphttp:
|
222
|
+
continue
|
223
|
+
if ptls and len(allptls) and ptls not in allptls:
|
224
|
+
continue
|
225
|
+
options.append({'phttp': phttp, 'ptls': ptls})
|
226
|
+
|
227
|
+
for opt in options:
|
228
|
+
pinfo = make_proxy(hconfigs, proxy, domain, **opt)
|
229
|
+
if 'msg' not in pinfo:
|
230
|
+
allp.append(pinfo)
|
231
|
+
return allp
|
232
|
+
|
233
|
+
|
234
|
+
def make_proxy(hconfigs: dict, proxy: Proxy, domain_db: Domain, phttp=80, ptls=443, pport: int | None = None) -> dict:
|
235
|
+
|
236
|
+
l3 = proxy.l3
|
237
|
+
domain = domain_db.domain
|
238
|
+
child_id = domain_db.child_id
|
239
|
+
name = proxy.name
|
240
|
+
port = hutils.proxy.get_port(proxy, hconfigs, domain_db, ptls, phttp, pport)
|
241
|
+
|
242
|
+
if val_res := hutils.proxy.is_proxy_valid(proxy, domain_db, port):
|
243
|
+
# print(val_res)
|
244
|
+
return val_res
|
245
|
+
|
246
|
+
if 'reality' in proxy.l3:
|
247
|
+
alpn = "h2" if proxy.transport in ['h2', "grpc"] else 'http/1.1'
|
248
|
+
else:
|
249
|
+
alpn = "h2" if proxy.l3 in ['tls_h2'] or proxy.transport in ["grpc", 'h2'] else 'h2,http/1.1' if proxy.l3 == 'tls_h2_h1' else "http/1.1"
|
250
|
+
cdn_forced_host = domain_db.cdn_ip or (domain_db.domain if domain_db.mode != DomainType.reality else hutils.network.get_direct_host_or_ip(4))
|
251
|
+
is_cdn = ProxyCDN.CDN == proxy.cdn or ProxyCDN.Fake == proxy.cdn
|
252
|
+
base = {
|
253
|
+
'name': name,
|
254
|
+
'cdn': is_cdn,
|
255
|
+
'mode': "CDN" if is_cdn else "direct",
|
256
|
+
'l3': l3,
|
257
|
+
'host': domain,
|
258
|
+
'port': port,
|
259
|
+
'server': cdn_forced_host,
|
260
|
+
'sni': domain_db.servernames if is_cdn and domain_db.servernames else domain,
|
261
|
+
'uuid': str(g.account.uuid),
|
262
|
+
'proto': proxy.proto,
|
263
|
+
'transport': proxy.transport,
|
264
|
+
'proxy_path': hconfigs[ConfigEnum.proxy_path],
|
265
|
+
'alpn': alpn,
|
266
|
+
'extra_info': f'{domain_db.alias or domain}',
|
267
|
+
'fingerprint': hconfigs[ConfigEnum.utls],
|
268
|
+
'allow_insecure': domain_db.mode == DomainType.fake or "Fake" in proxy.cdn,
|
269
|
+
'dbe': proxy,
|
270
|
+
'dbdomain': domain_db
|
271
|
+
}
|
272
|
+
if proxy.proto in ['tuic', 'hysteria2']:
|
273
|
+
base['alpn'] = "h3"
|
274
|
+
if proxy.proto == 'hysteria2':
|
275
|
+
base['hysteria_up_mbps'] = hconfigs.get(ConfigEnum.hysteria_up_mbps)
|
276
|
+
base['hysteria_down_mbps'] = hconfigs.get(ConfigEnum.hysteria_down_mbps)
|
277
|
+
base['hysteria_obfs_enable'] = hconfigs.get(ConfigEnum.hysteria_obfs_enable)
|
278
|
+
base['hysteria_obfs_password'] = hconfigs.get(ConfigEnum.proxy_path) # TODO: it should not be correct
|
279
|
+
return base
|
280
|
+
if proxy.proto in ['wireguard']:
|
281
|
+
base['wg_pub'] = g.account.wg_pub
|
282
|
+
base['wg_pk'] = g.account.wg_pk
|
283
|
+
base['wg_psk'] = g.account.wg_psk
|
284
|
+
base['wg_ipv4'] = hutils.network.add_number_to_ipv4(hconfigs[ConfigEnum.wireguard_ipv4], g.account.id)
|
285
|
+
base['wg_ipv6'] = hutils.network.add_number_to_ipv6(hconfigs[ConfigEnum.wireguard_ipv6], g.account.id)
|
286
|
+
base['wg_server_pub'] = hconfigs[ConfigEnum.wireguard_public_key]
|
287
|
+
base['wg_noise_trick'] = hconfigs[ConfigEnum.wireguard_noise_trick]
|
288
|
+
return base
|
289
|
+
|
290
|
+
if proxy.proto in [ProxyProto.vmess]:
|
291
|
+
base['cipher'] = "chacha20-poly1305"
|
292
|
+
|
293
|
+
if l3 in ['reality']:
|
294
|
+
base['reality_short_id'] = random.sample(hconfigs[ConfigEnum.reality_short_ids].split(','), 1)[0]
|
295
|
+
# base['flow']="xtls-rprx-vision"
|
296
|
+
base['reality_pbk'] = hconfigs[ConfigEnum.reality_public_key]
|
297
|
+
if (domain_db.servernames):
|
298
|
+
all_servernames = re.split('[ \t\r\n;,]+', domain_db.servernames)
|
299
|
+
base['sni'] = random.sample(all_servernames, 1)[0]
|
300
|
+
if hconfigs[ConfigEnum.core_type] == "singbox":
|
301
|
+
base['sni'] = all_servernames[0]
|
302
|
+
else:
|
303
|
+
base['sni'] = domain_db.domain
|
304
|
+
|
305
|
+
del base['host']
|
306
|
+
if base.get('fingerprint'):
|
307
|
+
base['fingerprint'] = hconfigs[ConfigEnum.utls]
|
308
|
+
# if not domain_db.cdn_ip:
|
309
|
+
# base['server']=hiddify.get_domain_ip(base['server'])
|
310
|
+
|
311
|
+
if "Fake" in proxy.cdn:
|
312
|
+
if not hconfigs[ConfigEnum.domain_fronting_domain]:
|
313
|
+
return {'name': name, 'msg': "no domain_fronting_domain", 'type': 'debug', 'proto': proxy.proto}
|
314
|
+
if l3 == "http" and not hconfigs[ConfigEnum.domain_fronting_http_enable]:
|
315
|
+
return {'name': name, 'msg': "no http in domain_fronting_domain", 'type': 'debug', 'proto': proxy.proto}
|
316
|
+
if l3 == "tls" and not hconfigs[ConfigEnum.domain_fronting_tls_enable]:
|
317
|
+
return {'name': name, 'msg': "no tls in domain_fronting_domain", 'type': 'debug', 'proto': proxy.proto}
|
318
|
+
base['server'] = hconfigs[ConfigEnum.domain_fronting_domain]
|
319
|
+
base['sni'] = hconfigs[ConfigEnum.domain_fronting_domain]
|
320
|
+
# base["host"]=domain
|
321
|
+
base['mode'] = 'Fake'
|
322
|
+
elif l3 == "http" and not hconfigs[ConfigEnum.http_proxy_enable]:
|
323
|
+
return {'name': name, 'msg': "http but http is disabled ", 'type': 'debug', 'proto': proxy.proto}
|
324
|
+
|
325
|
+
path = {
|
326
|
+
'vless': f'{hconfigs[ConfigEnum.path_vless]}',
|
327
|
+
'trojan': f'{hconfigs[ConfigEnum.path_trojan]}',
|
328
|
+
'vmess': f'{hconfigs[ConfigEnum.path_vmess]}',
|
329
|
+
'ss': f'{hconfigs[ConfigEnum.path_ss]}',
|
330
|
+
'v2ray': f'{hconfigs[ConfigEnum.path_ss]}'
|
331
|
+
}
|
332
|
+
|
333
|
+
if base["proto"] in ['v2ray', 'ss', 'ssr']:
|
334
|
+
base['cipher'] = hconfigs[ConfigEnum.shadowsocks2022_method]
|
335
|
+
base['password'] = f'{hutils.encode.do_base_64(hconfigs[ConfigEnum.shared_secret].replace("-",""))}:{hutils.encode.do_base_64(g.account.uuid.replace("-",""))}'
|
336
|
+
|
337
|
+
if base['proto'] == 'trojan':
|
338
|
+
base['password'] = base['uuid']
|
339
|
+
if base["proto"] == "ssr":
|
340
|
+
base["ssr-obfs"] = "tls1.2_ticket_auth"
|
341
|
+
base["ssr-protocol"] = "auth_sha1_v4"
|
342
|
+
base["fakedomain"] = hconfigs[ConfigEnum.ssr_fakedomain]
|
343
|
+
base["mode"] = "FakeTLS"
|
344
|
+
return base
|
345
|
+
elif "faketls" in proxy.transport:
|
346
|
+
base['fakedomain'] = hconfigs[ConfigEnum.ssfaketls_fakedomain]
|
347
|
+
base['mode'] = 'FakeTLS'
|
348
|
+
return base
|
349
|
+
elif "shadowtls" in proxy.transport:
|
350
|
+
base['fakedomain'] = hconfigs[ConfigEnum.shadowtls_fakedomain]
|
351
|
+
# base['sni'] = hconfigs[ConfigEnum.shadowtls_fakedomain]
|
352
|
+
base['shared_secret'] = hconfigs[ConfigEnum.shared_secret]
|
353
|
+
base['mode'] = 'ShadowTLS'
|
354
|
+
return base
|
355
|
+
elif "shadowsocks" in proxy.transport:
|
356
|
+
return base
|
357
|
+
if ProxyTransport.XTLS in proxy.transport:
|
358
|
+
base['flow'] = 'xtls-rprx-vision'
|
359
|
+
return {**base, 'transport': 'tcp'}
|
360
|
+
|
361
|
+
if proxy.proto in {'vless', 'trojan', 'vmess'} and hconfigs.get(ConfigEnum.mux_enable):
|
362
|
+
if hconfigs[ConfigEnum.mux_enable]:
|
363
|
+
base['mux_enable'] = hconfigs[ConfigEnum.core_type]
|
364
|
+
|
365
|
+
base['mux_protocol'] = hconfigs.get(ConfigEnum.mux_protocol, "h2mux")
|
366
|
+
base['mux_max_connections'] = hconfigs.get(ConfigEnum.mux_max_connections, 0)
|
367
|
+
base['mux_min_streams'] = hconfigs.get(ConfigEnum.mux_min_streams, 0)
|
368
|
+
base['mux_max_streams'] = hconfigs.get(ConfigEnum.mux_max_streams, 0)
|
369
|
+
base['mux_padding_enable'] = hconfigs.get(ConfigEnum.mux_padding_enable)
|
370
|
+
|
371
|
+
if hconfigs[ConfigEnum.mux_brutal_enable]:
|
372
|
+
base['mux_brutal_enable'] = True
|
373
|
+
base['mux_brutal_up_mbps'] = hconfigs.get(ConfigEnum.mux_brutal_up_mbps, 10)
|
374
|
+
base['mux_brutal_down_mbps'] = hconfigs.get(ConfigEnum.mux_brutal_down_mbps, 10)
|
375
|
+
|
376
|
+
if is_cdn and proxy.proto in {'vless', 'trojan', "vmess"}:
|
377
|
+
if hconfigs[ConfigEnum.tls_fragment_enable]:
|
378
|
+
base["tls_fragment_enable"] = True
|
379
|
+
base["tls_fragment_size"] = hconfigs[ConfigEnum.tls_fragment_size]
|
380
|
+
base["tls_fragment_sleep"] = hconfigs[ConfigEnum.tls_fragment_sleep]
|
381
|
+
|
382
|
+
if hconfigs[ConfigEnum.tls_mixed_case]:
|
383
|
+
base["tls_mixed_case"] = hconfigs[ConfigEnum.tls_mixed_case]
|
384
|
+
base['host'] = hutils.random.random_case(base['host'])
|
385
|
+
base['sni'] = hutils.random.random_case(base['sni'])
|
386
|
+
base['server'] = hutils.random.random_case(base['server'])
|
387
|
+
if base.get('fakedomain'):
|
388
|
+
base['fakedomain'] = hutils.random.random_case(base['fakedomain'])
|
389
|
+
|
390
|
+
if hconfigs[ConfigEnum.tls_padding_enable]:
|
391
|
+
base["tls_padding_enable"] = hconfigs[ConfigEnum.tls_padding_enable]
|
392
|
+
base["tls_padding_length"] = hconfigs[ConfigEnum.tls_padding_length]
|
393
|
+
|
394
|
+
if "tcp" in proxy.transport:
|
395
|
+
base['transport'] = 'tcp'
|
396
|
+
base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_tcp]}'
|
397
|
+
return base
|
398
|
+
if proxy.transport in ["ws", "WS"]:
|
399
|
+
base['transport'] = 'ws'
|
400
|
+
base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_ws]}'
|
401
|
+
base["host"] = domain
|
402
|
+
return base
|
403
|
+
|
404
|
+
if proxy.transport in [ProxyTransport.httpupgrade]:
|
405
|
+
base['transport'] = 'httpupgrade'
|
406
|
+
base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_httpupgrade]}'
|
407
|
+
base["host"] = domain
|
408
|
+
return base
|
409
|
+
|
410
|
+
if proxy.transport == "grpc":
|
411
|
+
base['transport'] = 'grpc'
|
412
|
+
# base['grpc_mode'] = "multi" if hconfigs[ConfigEnum.core_type]=='xray' else 'gun'
|
413
|
+
base['grpc_mode'] = 'gun'
|
414
|
+
base['grpc_service_name'] = f'{path[base["proto"]]}{hconfigs[ConfigEnum.path_grpc]}'
|
415
|
+
base['path'] = base['grpc_service_name']
|
416
|
+
return base
|
417
|
+
|
418
|
+
if "h1" in proxy.transport:
|
419
|
+
base['transport'] = 'tcp'
|
420
|
+
base['alpn'] = 'http/1.1'
|
421
|
+
return base
|
422
|
+
if ProxyProto.ssh == proxy.proto:
|
423
|
+
base['private_key'] = g.account.ed25519_private_key
|
424
|
+
base['host_key'] = hutils.proxy.get_ssh_hostkeys(False)
|
425
|
+
# base['ssh_port'] = hconfig(ConfigEnum.ssh_server_port)
|
426
|
+
return base
|
427
|
+
return {'name': name, 'msg': 'not valid', 'type': 'error', 'proto': proxy.proto}
|
428
|
+
|
429
|
+
|
430
|
+
class ProxyJsonEncoder(json.JSONEncoder):
|
431
|
+
def default(self, obj):
|
432
|
+
if isinstance(obj, IPv4Address) or isinstance(obj, IPv6Address):
|
433
|
+
return str(obj)
|
434
|
+
return super().default(obj)
|