mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2026-11-02 01:33:04 +00:00
Enhancements
Fix incorrect order of tolerance and timeout field in custom group config. Fix Content-Disposition header for better support on browsers. Fix parsing of some Shadowrocket links. Support HEAD request that only return Subscription-UserInfo (#434). Add more detail info to crash report.
This commit is contained in:
6 files changed
+56
-15
No files matched your search
@@ -224,7 +224,7 @@ namespace INIBinding
|
|||||||
continue;
|
continue;
|
||||||
rules_upper_bound -= 2;
|
rules_upper_bound -= 2;
|
||||||
conf.Url = vArray[rules_upper_bound];
|
conf.Url = vArray[rules_upper_bound];
|
||||||
parseGroupTimes(vArray[rules_upper_bound + 1], &conf.Interval, &conf.Tolerance, &conf.Timeout);
|
parseGroupTimes(vArray[rules_upper_bound + 1], &conf.Interval, &conf.Timeout, &conf.Tolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i = 2; i < rules_upper_bound; i++)
|
for(unsigned int i = 2; i < rules_upper_bound; i++)
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
std::string argGroupName = urlDecode(getUrlArg(argument, "group")), argUploadPath = getUrlArg(argument, "upload_path");
|
std::string argGroupName = urlDecode(getUrlArg(argument, "group")), argUploadPath = getUrlArg(argument, "upload_path");
|
||||||
std::string argIncludeRemark = urlDecode(getUrlArg(argument, "include")), argExcludeRemark = urlDecode(getUrlArg(argument, "exclude"));
|
std::string argIncludeRemark = urlDecode(getUrlArg(argument, "include")), argExcludeRemark = urlDecode(getUrlArg(argument, "exclude"));
|
||||||
std::string argCustomGroups = urlSafeBase64Decode(getUrlArg(argument, "groups")), argCustomRulesets = urlSafeBase64Decode(getUrlArg(argument, "ruleset")), argExternalConfig = urlDecode(getUrlArg(argument, "config"));
|
std::string argCustomGroups = urlSafeBase64Decode(getUrlArg(argument, "groups")), argCustomRulesets = urlSafeBase64Decode(getUrlArg(argument, "ruleset")), argExternalConfig = urlDecode(getUrlArg(argument, "config"));
|
||||||
std::string argDeviceID = getUrlArg(argument, "dev_id"), argFilename = getUrlArg(argument, "filename"), argUpdateInterval = getUrlArg(argument, "interval"), argUpdateStrict = getUrlArg(argument, "strict");
|
std::string argDeviceID = getUrlArg(argument, "dev_id"), argFilename = urlDecode(getUrlArg(argument, "filename")), argUpdateInterval = getUrlArg(argument, "interval"), argUpdateStrict = getUrlArg(argument, "strict");
|
||||||
std::string argRenames = urlDecode(getUrlArg(argument, "rename")), argFilterScript = urlDecode(getUrlArg(argument, "filter_script"));
|
std::string argRenames = urlDecode(getUrlArg(argument, "rename")), argFilterScript = urlDecode(getUrlArg(argument, "filter_script"));
|
||||||
|
|
||||||
/// switches with default value
|
/// switches with default value
|
||||||
@@ -612,6 +612,12 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
*status_code = 400;
|
*status_code = 400;
|
||||||
return "No nodes were found!";
|
return "No nodes were found!";
|
||||||
}
|
}
|
||||||
|
if(subInfo.size() && argAppendUserinfo.get(global.appendUserinfo))
|
||||||
|
response.headers.emplace("Subscription-UserInfo", subInfo);
|
||||||
|
|
||||||
|
if(request.method == "HEAD")
|
||||||
|
return "";
|
||||||
|
|
||||||
argPrependInsert.define(global.prependInsert);
|
argPrependInsert.define(global.prependInsert);
|
||||||
if(argPrependInsert)
|
if(argPrependInsert)
|
||||||
{
|
{
|
||||||
@@ -673,9 +679,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
for(Proxy &x : nodes)
|
for(Proxy &x : nodes)
|
||||||
x.Group = argGroupName;
|
x.Group = argGroupName;
|
||||||
|
|
||||||
if(subInfo.size() && argAppendUserinfo.get(global.appendUserinfo))
|
|
||||||
response.headers.emplace("Subscription-UserInfo", subInfo);
|
|
||||||
|
|
||||||
//do pre-process now
|
//do pre-process now
|
||||||
preprocessNodes(nodes, ext);
|
preprocessNodes(nodes, ext);
|
||||||
|
|
||||||
@@ -886,7 +889,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
|||||||
}
|
}
|
||||||
writeLog(0, "Generate completed.", LOG_LEVEL_INFO);
|
writeLog(0, "Generate completed.", LOG_LEVEL_INFO);
|
||||||
if(argFilename.size())
|
if(argFilename.size())
|
||||||
response.headers.emplace("Content-Disposition", "attachment; filename=\"" + argFilename + "\"");
|
response.headers.emplace("Content-Disposition", "attachment; filename=\"" + argFilename + "\"; filename*=utf-8''" + urlEncode(argFilename));
|
||||||
return output_content;
|
return output_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,16 +120,17 @@ void explodeVmess(std::string vmess, Proxy &node)
|
|||||||
std::string version, ps, add, port, type, id, aid, net, path, host, tls, sni;
|
std::string version, ps, add, port, type, id, aid, net, path, host, tls, sni;
|
||||||
Document jsondata;
|
Document jsondata;
|
||||||
std::vector<std::string> vArray;
|
std::vector<std::string> vArray;
|
||||||
if(regMatch(vmess, "vmess://(.*?)@(.*)"))
|
|
||||||
{
|
if(regMatch(vmess, "vmess://([A-Za-z0-9-_]+)\\?(.*)")) //shadowrocket style link
|
||||||
explodeStdVMess(vmess, node);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(regMatch(vmess, "vmess://(.*?)\\?(.*)")) //shadowrocket style link
|
|
||||||
{
|
{
|
||||||
explodeShadowrocket(vmess, node);
|
explodeShadowrocket(vmess, node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(regMatch(vmess, "vmess://(.*?)@(.*)"))
|
||||||
|
{
|
||||||
|
explodeStdVMess(vmess, node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if(regMatch(vmess, "vmess1://(.*?)\\?(.*)")) //kitsunebi style link
|
else if(regMatch(vmess, "vmess1://(.*?)\\?(.*)")) //kitsunebi style link
|
||||||
{
|
{
|
||||||
explodeKitsunebi(vmess, node);
|
explodeKitsunebi(vmess, node);
|
||||||
|
|||||||
@@ -146,7 +146,10 @@ inline int WebServer::process_request(Request &request, Response &response, std:
|
|||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
return_data = "Internal server error while processing request path '" + request.url + "' with arguments '" + request.argument + "'!\n what(): ";
|
return_data = "Internal server error while processing request path '" + request.url + "' with arguments '" + request.argument + "'!";
|
||||||
|
return_data += "\n exception: ";
|
||||||
|
return_data += type(e);
|
||||||
|
return_data += "\n what(): ";
|
||||||
return_data += e.what();
|
return_data += e.what();
|
||||||
response.content_type = "text/plain";
|
response.content_type = "text/plain";
|
||||||
response.status_code = 500;
|
response.status_code = 500;
|
||||||
@@ -234,6 +237,7 @@ void WebServer::on_request(evhttp_request *req, void *args)
|
|||||||
case EVHTTP_REQ_PUT: request.method = "PUT"; break;
|
case EVHTTP_REQ_PUT: request.method = "PUT"; break;
|
||||||
case EVHTTP_REQ_PATCH: request.method = "PATCH"; break;
|
case EVHTTP_REQ_PATCH: request.method = "PATCH"; break;
|
||||||
case EVHTTP_REQ_DELETE: request.method = "DELETE"; break;
|
case EVHTTP_REQ_DELETE: request.method = "DELETE"; break;
|
||||||
|
case EVHTTP_REQ_HEAD: request.method = "HEAD"; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
request.url = uri;
|
request.url = uri;
|
||||||
@@ -315,7 +319,7 @@ int WebServer::start_web_server(void *argv)
|
|||||||
|
|
||||||
auto call_on_request = [&](evhttp_request *req, void *args) { on_request(req, args); };
|
auto call_on_request = [&](evhttp_request *req, void *args) { on_request(req, args); };
|
||||||
|
|
||||||
evhttp_set_allowed_methods(server.get(), EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_OPTIONS | EVHTTP_REQ_PUT | EVHTTP_REQ_PATCH | EVHTTP_REQ_DELETE);
|
evhttp_set_allowed_methods(server.get(), EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_OPTIONS | EVHTTP_REQ_PUT | EVHTTP_REQ_PATCH | EVHTTP_REQ_DELETE | EVHTTP_REQ_HEAD);
|
||||||
evhttp_set_gencb(server.get(), wrap(call_on_request), nullptr);
|
evhttp_set_gencb(server.get(), wrap(call_on_request), nullptr);
|
||||||
evhttp_set_timeout(server.get(), 30);
|
evhttp_set_timeout(server.get(), 30);
|
||||||
if (event_dispatch() == -1)
|
if (event_dispatch() == -1)
|
||||||
@@ -399,7 +403,7 @@ int WebServer::start_web_server_multi(void *argv)
|
|||||||
if (evhttp_accept_socket(httpd, nfd) != 0)
|
if (evhttp_accept_socket(httpd, nfd) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
evhttp_set_allowed_methods(httpd, EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_OPTIONS | EVHTTP_REQ_PUT | EVHTTP_REQ_PATCH | EVHTTP_REQ_DELETE);
|
evhttp_set_allowed_methods(httpd, EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_OPTIONS | EVHTTP_REQ_PUT | EVHTTP_REQ_PATCH | EVHTTP_REQ_DELETE | EVHTTP_REQ_HEAD);
|
||||||
evhttp_set_gencb(httpd, wrap(call_on_request), nullptr);
|
evhttp_set_gencb(httpd, wrap(call_on_request), nullptr);
|
||||||
evhttp_set_timeout(httpd, 30);
|
evhttp_set_timeout(httpd, 30);
|
||||||
if (pthread_create(&ths[i], nullptr, httpserver_dispatch, base[i]) != 0)
|
if (pthread_create(&ths[i], nullptr, httpserver_dispatch, base[i]) != 0)
|
||||||
|
|||||||
@@ -42,3 +42,28 @@ void writeLog(int type, const std::string &content, int level)
|
|||||||
std::cerr<<getTime(2)<<" ["<<getpid()<<" "<<std::this_thread::get_id()<<"]"<<levels[level % 6];
|
std::cerr<<getTime(2)<<" ["<<getpid()<<" "<<std::this_thread::get_id()<<"]"<<levels[level % 6];
|
||||||
std::cerr<<" "<<content<<"\n";
|
std::cerr<<" "<<content<<"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
std::string demangle(const char* name)
|
||||||
|
{
|
||||||
|
int status = -4;
|
||||||
|
std::unique_ptr<char, void(*)(void*)> res {
|
||||||
|
abi::__cxa_demangle(name, NULL, NULL, &status),
|
||||||
|
std::free
|
||||||
|
};
|
||||||
|
return (status == 0) ? res.get() : name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
std::string demangle(const char* name)
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#define LOGGER_H_INCLUDED
|
#define LOGGER_H_INCLUDED
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -30,5 +31,12 @@ enum
|
|||||||
|
|
||||||
std::string getTime(int type);
|
std::string getTime(int type);
|
||||||
void writeLog(int type, const std::string &content, int level = LOG_LEVEL_VERBOSE);
|
void writeLog(int type, const std::string &content, int level = LOG_LEVEL_VERBOSE);
|
||||||
|
std::string demangle(const char* name);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::string type(const T& t) {
|
||||||
|
|
||||||
|
return demangle(typeid(t).name());
|
||||||
|
}
|
||||||
|
|
||||||
#endif // LOGGER_H_INCLUDED
|
#endif // LOGGER_H_INCLUDED
|
||||||
Reference in new issue
Block a user