mirror of
https://github.com/MetaCubeX/subconverter.git
synced 2025-11-04 18:19:42 +08:00
Enhancements
Add URL aliasing support to shorten request URL. Add support for parsing and exporting Snell server in configurations. Add numbering system to process duplicated node names. Optimize codes.
This commit is contained in:
parent
4b5e0e1346
commit
52c8eff182
@ -88,6 +88,9 @@ template:
|
||||
- {key: clash.allow_lan, value: true}
|
||||
- {key: clash.log_level, value: info}
|
||||
|
||||
aliases:
|
||||
- {uri: /v, target: /version}
|
||||
|
||||
server:
|
||||
listen: 0.0.0.0
|
||||
port: 25500
|
||||
|
||||
@ -174,6 +174,9 @@ clash.socks_port=7891
|
||||
clash.allow_lan=true
|
||||
clash.log_level=info
|
||||
|
||||
[aliases]
|
||||
/v=/version
|
||||
|
||||
[server]
|
||||
;Address to bind on for Web Server
|
||||
listen=0.0.0.0
|
||||
|
||||
@ -31,6 +31,7 @@ bool print_debug_info = false, cfw_child_process = false, append_userinfo = true
|
||||
std::string access_token;
|
||||
extern std::string custom_group;
|
||||
extern int global_log_level;
|
||||
string_map aliases_map;
|
||||
|
||||
//global variables for template
|
||||
std::string template_path;
|
||||
@ -541,9 +542,9 @@ void readYAMLConf(YAML::Node &node)
|
||||
if(node["template"]["globals"].IsSequence())
|
||||
{
|
||||
eraseElements(global_vars);
|
||||
std::string key, value;
|
||||
for(size_t i = 0; i < node["template"]["globals"].size(); i++)
|
||||
{
|
||||
std::string key, value;
|
||||
node["template"]["globals"][i]["key"] >> key;
|
||||
node["template"]["globals"][i]["value"] >> value;
|
||||
global_vars[key] = value;
|
||||
@ -551,6 +552,18 @@ void readYAMLConf(YAML::Node &node)
|
||||
}
|
||||
}
|
||||
|
||||
if(node["aliases"].IsSequence())
|
||||
{
|
||||
reset_redirect();
|
||||
for(size_t i = 0; i < node["aliases"].size(); i++)
|
||||
{
|
||||
std::string uri, target;
|
||||
node["aliases"][i]["uri"] >> uri;
|
||||
node["aliases"][i]["target"] >> target;
|
||||
append_redirect(uri, target);
|
||||
}
|
||||
}
|
||||
|
||||
if(node["server"].IsDefined())
|
||||
{
|
||||
node["server"]["listen"] >> listen_address;
|
||||
@ -767,6 +780,16 @@ void readConf()
|
||||
}
|
||||
global_vars["managed_config_prefix"] = managed_config_prefix;
|
||||
|
||||
if(ini.SectionExist("aliases"))
|
||||
{
|
||||
ini.EnterSection("aliases");
|
||||
string_multimap tempmap;
|
||||
ini.GetItems(tempmap);
|
||||
reset_redirect();
|
||||
for(auto &x : tempmap)
|
||||
append_redirect(x.first, x.second);
|
||||
}
|
||||
|
||||
ini.EnterSection("server");
|
||||
ini.GetIfExist("listen", listen_address);
|
||||
ini.GetIntIfExist("port", listen_port);
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
typedef std::string::size_type string_size;
|
||||
typedef std::vector<std::string> string_array;
|
||||
typedef std::map<std::string, std::string> string_map;
|
||||
typedef const std::string &refCnstStr;
|
||||
|
||||
static const std::string base64_chars =
|
||||
|
||||
@ -32,6 +32,7 @@ enum
|
||||
SPEEDTEST_MESSAGE_FOUNDSS,
|
||||
SPEEDTEST_MESSAGE_FOUNDSSR,
|
||||
SPEEDTEST_MESSAGE_FOUNDTROJAN,
|
||||
SPEEDTEST_MESSAGE_FOUNDSNELL,
|
||||
SPEEDTEST_MESSAGE_WELCOME,
|
||||
SPEEDTEST_MESSAGE_FOUNDSUB,
|
||||
SPEEDTEST_MESSAGE_GOTSERVER,
|
||||
@ -73,6 +74,7 @@ enum
|
||||
#define SOCKS_DEFAULT_GROUP "SocksProvider"
|
||||
#define HTTP_DEFAULT_GROUP "HTTPProvider"
|
||||
#define TROJAN_DEFAULT_GROUP "TrojanProvider"
|
||||
#define SNELL_DEFAULT_GROUP "SnellProvider"
|
||||
|
||||
void printMsg(int index, nodeInfo *node, bool rpcmode);
|
||||
void printMsgWithDict(int index, bool rpcmode, std::vector<std::string> dict, std::vector<std::string> trans);
|
||||
|
||||
@ -1079,6 +1079,18 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
||||
node.proxyStr = trojanConstruct(ps, server, port, password, host, true);
|
||||
break;
|
||||
case "snell"_hash:
|
||||
group = SNELL_DEFAULT_GROUP;
|
||||
singleproxy["psk"] >> password;
|
||||
if(singleproxy["obfs-opts"].IsDefined())
|
||||
{
|
||||
singleproxy["obfs-opts"]["mode"] >> obfs;
|
||||
singleproxy["obfs-opts"]["host"] >> host;
|
||||
}
|
||||
|
||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
||||
node.proxyStr = snellConstruct(ps, server, port, password, obfs, host);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -1418,6 +1430,33 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
||||
|
||||
node.proxyStr = trojanConstruct(remarks, server, port, password, host, true);
|
||||
break;
|
||||
case "snell"_hash:
|
||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL;
|
||||
node.group = SNELL_DEFAULT_GROUP;
|
||||
|
||||
server = trim(configs[1]);
|
||||
port = custom_port.empty() ? trim(configs[2]) : custom_port;
|
||||
|
||||
for(i = 3; i < configs.size(); i++)
|
||||
{
|
||||
vArray = split(configs[i], "=");
|
||||
if(vArray.size() != 2)
|
||||
continue;
|
||||
itemName = trim(vArray[0]);
|
||||
itemVal = trim(vArray[1]);
|
||||
switch(hash_(itemName))
|
||||
{
|
||||
case "psk"_hash: password = itemVal; break;
|
||||
case "obfs"_hash: plugin = itemVal; break;
|
||||
case "obfs-host"_hash: host = itemVal; break;
|
||||
default: continue;
|
||||
}
|
||||
}
|
||||
if(host.empty() && !isIPv4(server) && !isIPv6(server))
|
||||
host = server;
|
||||
|
||||
node.proxyStr = snellConstruct(remarks, server, port, password, plugin, host);
|
||||
break;
|
||||
default:
|
||||
switch(hash_(remarks))
|
||||
{
|
||||
|
||||
@ -13,6 +13,7 @@ std::string ssConstruct(std::string server, std::string port, std::string passwo
|
||||
std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password);
|
||||
std::string httpConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls = false);
|
||||
std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure);
|
||||
std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host);
|
||||
void explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &node);
|
||||
void explodeSSR(std::string ssr, bool ss_libev, bool libev, const std::string &custom_port, nodeInfo &node);
|
||||
void explodeSS(std::string ss, bool libev, const std::string &custom_port, nodeInfo &node);
|
||||
|
||||
@ -251,6 +251,29 @@ std::string trojanConstruct(std::string remarks, std::string server, std::string
|
||||
return sb.GetString();
|
||||
}
|
||||
|
||||
std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host)
|
||||
{
|
||||
rapidjson::StringBuffer sb;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||
writer.StartObject();
|
||||
writer.Key("Type");
|
||||
writer.String("Snell");
|
||||
writer.Key("Remark");
|
||||
writer.String(remarks.data());
|
||||
writer.Key("Hostname");
|
||||
writer.String(server.data());
|
||||
writer.Key("Port");
|
||||
writer.Int(to_int(port));
|
||||
writer.Key("Password");
|
||||
writer.String(password.data());
|
||||
writer.Key("OBFS");
|
||||
writer.String(obfs.data());
|
||||
writer.Key("Host");
|
||||
writer.String(host.data());
|
||||
writer.EndObject();
|
||||
return sb.GetString();
|
||||
}
|
||||
|
||||
std::string vmessLinkConstruct(std::string remarks, std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string path, std::string host, std::string tls)
|
||||
{
|
||||
rapidjson::StringBuffer sb;
|
||||
@ -867,10 +890,15 @@ void netchToClash(std::vector<nodeInfo> &nodes, YAML::Node &yamlnode, string_arr
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "] " + x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), x.remarks) > 0)
|
||||
x.remarks += "$";
|
||||
|
||||
remark = x.remarks;
|
||||
int cnt = 2;
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
{
|
||||
remark = x.remarks + " " + std::to_string(cnt);
|
||||
cnt++;
|
||||
}
|
||||
x.remarks = remark;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = GetMember(json, "Port");
|
||||
username = GetMember(json, "Username");
|
||||
@ -1009,6 +1037,19 @@ void netchToClash(std::vector<nodeInfo> &nodes, YAML::Node &yamlnode, string_arr
|
||||
if(ext.skip_cert_verify)
|
||||
singleproxy["skip-cert-verify"] = true;
|
||||
break;
|
||||
case SPEEDTEST_MESSAGE_FOUNDSNELL:
|
||||
obfs = GetMember(json, "OBFS");
|
||||
host = GetMember(json, "Host");
|
||||
singleproxy["type"] = "snell";
|
||||
singleproxy["psk"] = password;
|
||||
if(obfs.size())
|
||||
{
|
||||
singleproxy["obfs-opts"]["mode"] = obfs;
|
||||
singleproxy["obfs-opts"]["host"] = host;
|
||||
}
|
||||
if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty())
|
||||
singleproxy["password"].SetTag("str");
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -1173,10 +1214,14 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
x.remarks = "[" + type + "] " + x.remarks;
|
||||
remark = x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), x.remarks) > 0)
|
||||
x.remarks += "$";
|
||||
int cnt = 2;
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
{
|
||||
remark = x.remarks + " " + std::to_string(cnt);
|
||||
cnt++;
|
||||
}
|
||||
x.remarks = remark;
|
||||
|
||||
remark = x.remarks;
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
username = GetMember(json, "Username");
|
||||
@ -1274,6 +1319,13 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, std::string &base_conf, s
|
||||
if(ext.skip_cert_verify)
|
||||
proxy += ", skip-cert-verify=1";
|
||||
break;
|
||||
case SPEEDTEST_MESSAGE_FOUNDSNELL:
|
||||
obfs = GetMember(json, "OBFS");
|
||||
host = GetMember(json, "Host");
|
||||
proxy = "snell, " + hostname + ", " + port + ", psk=" + password;
|
||||
if(obfs.size())
|
||||
proxy += ", obfs=" + obfs + ", obfs-host=" + host;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -1719,10 +1771,14 @@ void netchToQuan(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rules
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "] " + x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), x.remarks) > 0)
|
||||
x.remarks += "$";
|
||||
|
||||
remark = x.remarks;
|
||||
int cnt = 2;
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
{
|
||||
remark = x.remarks + " " + std::to_string(cnt);
|
||||
cnt++;
|
||||
}
|
||||
x.remarks = remark;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
@ -1984,10 +2040,14 @@ void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rule
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "] " + x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), x.remarks) > 0)
|
||||
x.remarks += "$";
|
||||
|
||||
remark = x.remarks;
|
||||
int cnt = 2;
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
{
|
||||
remark = x.remarks + " " + std::to_string(cnt);
|
||||
cnt++;
|
||||
}
|
||||
x.remarks = remark;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
@ -2110,6 +2170,16 @@ void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rule
|
||||
continue;
|
||||
rules_upper_bound -= 2;
|
||||
break;
|
||||
case "ssid"_hash:
|
||||
if(rules_upper_bound < 4)
|
||||
continue;
|
||||
proxies = vArray[0] + ",";
|
||||
proxies += std::accumulate(vArray.begin() + 3, vArray.end(), vArray[2], [](std::string a, std::string b)
|
||||
{
|
||||
return std::move(a) + "," + std::move(replace_all_distinct(b, "=", ":"));
|
||||
});
|
||||
ini.Set("{NONAME}", vArray[1] + "=" + proxies); //insert order
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -2361,10 +2431,16 @@ void netchToMellow(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rul
|
||||
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "] " + x.remarks;
|
||||
remark = x.remarks;
|
||||
|
||||
remark = x.remarks;
|
||||
int cnt = 2;
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
remark = x.remarks = x.remarks + "$";
|
||||
{
|
||||
remark = x.remarks + " " + std::to_string(cnt);
|
||||
cnt++;
|
||||
}
|
||||
x.remarks = remark;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
username = GetMember(json, "Username");
|
||||
@ -2514,12 +2590,16 @@ std::string netchToLoon(std::vector<nodeInfo> &nodes, std::string &base_conf, st
|
||||
|
||||
if(ext.append_proxy_type)
|
||||
x.remarks = "[" + type + "] " + x.remarks;
|
||||
remark = x.remarks;
|
||||
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), x.remarks) > 0)
|
||||
x.remarks += "$";
|
||||
|
||||
remark = x.remarks;
|
||||
int cnt = 2;
|
||||
while(std::count(remarks_list.begin(), remarks_list.end(), remark) > 0)
|
||||
{
|
||||
remark = x.remarks + " " + std::to_string(cnt);
|
||||
cnt++;
|
||||
}
|
||||
x.remarks = remark;
|
||||
|
||||
hostname = GetMember(json, "Hostname");
|
||||
port = std::to_string((unsigned short)stoi(GetMember(json, "Port")));
|
||||
username = GetMember(json, "Username");
|
||||
|
||||
@ -14,6 +14,8 @@ struct listener_args
|
||||
};
|
||||
|
||||
void append_response(std::string method, std::string uri, std::string content_type, response_callback response);
|
||||
void append_redirect(std::string uri, std::string target);
|
||||
void reset_redirect();
|
||||
int start_web_server(void *argv);
|
||||
int start_web_server_multi(void *argv);
|
||||
void stop_web_server();
|
||||
|
||||
@ -30,6 +30,7 @@ struct responseRoute
|
||||
};
|
||||
|
||||
std::vector<responseRoute> responses;
|
||||
string_map redirect_map;
|
||||
|
||||
static inline void buffer_cleanup(struct evbuffer *eb)
|
||||
{
|
||||
@ -68,6 +69,14 @@ static inline int process_request(const char *method_str, std::string uri, std::
|
||||
}
|
||||
}
|
||||
|
||||
auto iter = redirect_map.find(uri);
|
||||
if(iter != redirect_map.end())
|
||||
{
|
||||
return_data = iter->second;
|
||||
content_type = "REDIRECT";
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -290,3 +299,13 @@ void append_response(std::string method, std::string uri, std::string content_ty
|
||||
rr.rc = response;
|
||||
responses.emplace_back(rr);
|
||||
}
|
||||
|
||||
void append_redirect(std::string uri, std::string target)
|
||||
{
|
||||
redirect_map[uri] = target;
|
||||
}
|
||||
|
||||
void reset_redirect()
|
||||
{
|
||||
eraseElements(redirect_map);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user