Enhancements

Add better error handling.
Add support for version field of Snell nodes.
Optimize codes.
This commit is contained in:
Tindy X 2022-01-23 01:04:16 +08:00
parent 9419738959
commit 2f78eafa2c
No known key found for this signature in database
GPG Key ID: C6AD413169968D58
7 changed files with 41 additions and 24 deletions

View File

@ -162,7 +162,7 @@ int addNodes(std::string link, std::vector<Proxy> &allNodes, int groupID, parse_
writeLog(LOG_TYPE_INFO, "Parsing subscription data...");
if(explodeConfContent(strSub, nodes) == 0)
{
writeLog(LOG_TYPE_ERROR, "Invalid subscription!");
writeLog(LOG_TYPE_ERROR, "Invalid subscription: '" + link + "'!");
return -1;
}
if(startsWith(strSub, "ssd://"))

View File

@ -3,10 +3,6 @@
#include <numeric>
#include <cmath>
#include <climits>
#include <rapidjson/writer.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <yaml-cpp/yaml.h>
#include "../../config/regmatch.h"
#include "../../generator/config/subexport.h"
@ -295,7 +291,7 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
case ProxyType::VMess:
singleproxy["type"] = "vmess";
singleproxy["uuid"] = x.UserId;
singleproxy["alterId"] = static_cast<uint32_t>(x.AlterId);
singleproxy["alterId"] = x.AlterId;
singleproxy["cipher"] = x.EncryptMethod;
singleproxy["tls"] = x.TLSSecure;
if(!scv.is_undef())
@ -433,6 +429,8 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
case ProxyType::Snell:
singleproxy["type"] = "snell";
singleproxy["psk"] = x.Password;
if(x.AlterId != 0)
singleproxy["version"] = x.AlterId;
if(!x.OBFS.empty())
{
singleproxy["obfs-opts"]["mode"] = x.OBFS;

View File

@ -65,7 +65,7 @@ struct Proxy
String OBFS;
String OBFSParam;
String UserId;
uint8_t AlterId = 0;
uint16_t AlterId = 0;
String TransferProtocol;
String FakeType;
bool TLSSecure = false;

View File

@ -105,12 +105,13 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
node.Path = path;
}
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, tribool udp, tribool tfo, tribool scv)
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, uint16_t version, tribool udp, tribool tfo, tribool scv)
{
commonConstruct(node, ProxyType::Snell, group, remarks, server, port, udp, tfo, scv, tribool());
node.Password = password;
node.OBFS = obfs;
node.Host = host;
node.AlterId = version;
}
void explodeVmess(std::string vmess, Proxy &node)
@ -140,7 +141,7 @@ void explodeVmess(std::string vmess, Proxy &node)
return;
}
jsondata.Parse(vmess.data());
if(jsondata.HasParseError())
if(jsondata.HasParseError() || !jsondata.IsObject())
return;
version = "1"; //link without version will treat as version 1
@ -198,7 +199,7 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes)
regGetMatch(content, "((?1)wssettings)", 2, 0, &wsset);
json.Parse(content.data());
if(json.HasParseError())
if(json.HasParseError() || !json.IsObject())
return;
try
{
@ -382,7 +383,7 @@ void explodeSSD(std::string link, std::vector<Proxy> &nodes)
link = urlSafeBase64Decode(link.substr(6));
jsondata.Parse(link.c_str());
if(jsondata.HasParseError())
if(jsondata.HasParseError() || !jsondata.IsObject())
return;
if(!jsondata.HasMember("servers"))
return;
@ -460,7 +461,7 @@ void explodeSSAndroid(std::string ss, std::vector<Proxy> &nodes)
//first add some extra data before parsing
ss = "{\"nodes\":" + ss + "}";
json.Parse(ss.data());
if(json.HasParseError())
if(json.HasParseError() || !json.IsObject())
return;
for(uint32_t i = 0; i < json["nodes"].Size(); i++)
@ -495,7 +496,7 @@ void explodeSSConf(std::string content, std::vector<Proxy> &nodes)
int index = nodes.size();
json.Parse(content.data());
if(json.HasParseError())
if(json.HasParseError() || !json.IsObject())
return;
const char *section = json.HasMember("version") && json.HasMember("servers") ? "servers" : "configs";
if(!json.HasMember(section))
@ -571,7 +572,7 @@ void explodeSSRConf(std::string content, std::vector<Proxy> &nodes)
int index = nodes.size();
json.Parse(content.data());
if(json.HasParseError())
if(json.HasParseError() || !json.IsObject())
return;
if(json.HasMember("local_port") && json.HasMember("local_address")) //single libev config
@ -842,7 +843,7 @@ void explodeNetch(std::string netch, Proxy &node)
netch = urlSafeBase64Decode(netch.substr(8));
json.Parse(netch.data());
if(json.HasParseError())
if(json.HasParseError() || !json.IsObject())
return;
type = GetMember(json, "Type");
group = GetMember(json, "Group");
@ -924,9 +925,10 @@ void explodeNetch(std::string netch, Proxy &node)
case "Snell"_hash:
obfs = GetMember(json, "OBFS");
host = GetMember(json, "Host");
aid = GetMember(json, "AlterId");
if(group.empty())
group = SNELL_DEFAULT_GROUP;
snellConstruct(node, group, remark, address, port, password, obfs, host, udp, tfo, scv);
snellConstruct(node, group, remark, address, port, password, obfs, host, to_int(aid, 0), udp, tfo, scv);
break;
default:
return;
@ -1133,8 +1135,9 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
singleproxy["psk"] >> password;
singleproxy["obfs-opts"]["mode"] >>= obfs;
singleproxy["obfs-opts"]["host"] >>= host;
singleproxy["version"] >>= aid;
snellConstruct(node, group, ps, server, port, password, obfs, host, udp, tfo, scv);
snellConstruct(node, group, ps, server, port, password, obfs, host, to_int(aid, 0), udp, tfo, scv);
break;
default:
continue;
@ -1309,6 +1312,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, mod_url, mod_md5; //ss
std::string id, net, tls, host, edge, path; //v2
std::string protocol, protoparam; //ssr
std::string version;
std::string itemName, itemVal, config;
std::vector<std::string> configs, vArray, headers, header;
tribool udp, tfo, scv, tls13;
@ -1637,6 +1641,9 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
case "skip-cert-verify"_hash:
scv = itemVal;
break;
case "version"_hash:
version = itemVal;
break;
default:
continue;
}
@ -1644,7 +1651,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes)
if(host.empty() && !isIPv4(server) && !isIPv6(server))
host = server;
snellConstruct(node, SNELL_DEFAULT_GROUP, remarks, server, port, password, plugin, host, udp, tfo, scv);
snellConstruct(node, SNELL_DEFAULT_GROUP, remarks, server, port, password, plugin, host, to_int(version, 0), udp, tfo, scv);
break;
default:
switch(hash_(remarks))
@ -1947,7 +1954,7 @@ void explodeSSTap(std::string sstap, std::vector<Proxy> &nodes)
Proxy node;
uint32_t index = nodes.size();
json.Parse(sstap.data());
if(json.HasParseError())
if(json.HasParseError() || !json.IsObject())
return;
for(uint32_t i = 0; i < json["configs"].Size(); i++)
@ -2003,7 +2010,7 @@ void explodeNetchConf(std::string netch, std::vector<Proxy> &nodes)
uint32_t index = nodes.size();
json.Parse(netch.data());
if(json.HasParseError())
if(json.HasParseError() || !json.IsObject())
return;
if(!json.HasMember("Server"))

View File

@ -26,7 +26,7 @@ void ssConstruct(Proxy &node, const std::string &group, const std::string &remar
void socksConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
void httpConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, bool tls, tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void trojanConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &network, const std::string &host, const std::string &path, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, uint16_t version = 0, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
void explodeVmess(std::string vmess, Proxy &node);
void explodeSSR(std::string ssr, Proxy &node);
void explodeSS(std::string ss, Proxy &node);

View File

@ -139,8 +139,19 @@ inline int WebServer::process_request(Request &request, Response &response, std:
if(x.method == request.method && x.path == request.url)
{
response_callback &rc = x.rc;
return_data = rc(request, response);
response.content_type = x.content_type;
try
{
return_data = rc(request, response);
response.content_type = x.content_type;
}
catch(std::exception &e)
{
return_data = "Internal server error while processing request path '" + request.url + "' with arguments '" + request.argument + "'!\n what(): ";
return_data += e.what();
response.content_type = "text/plain";
response.status_code = 500;
writeLog(0, return_data, LOG_LEVEL_ERROR);
}
return 0;
}
}

View File

@ -6,7 +6,7 @@
template <typename T> void exception_thrower(T e)
{
if(!e)
throw std::runtime_error("assert");
throw std::runtime_error("rapidjson assertion failed");
}
#ifdef RAPIDJSON_ASSERT
@ -15,6 +15,7 @@ template <typename T> void exception_thrower(T e)
#define RAPIDJSON_ASSERT(x) exception_thrower(x)
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/error/en.h>
#include <string>
inline void operator >> (const rapidjson::Value& value, std::string& i)