mirror of
https://github.com/MetaCubeX/subconverter.git
synced 2025-11-04 18:19:42 +08: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:
parent
ebe68f64b1
commit
406b0f2022
@ -224,7 +224,7 @@ namespace INIBinding
|
||||
continue;
|
||||
rules_upper_bound -= 2;
|
||||
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++)
|
||||
|
||||
@ -342,7 +342,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
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 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"));
|
||||
|
||||
/// switches with default value
|
||||
@ -612,6 +612,12 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
*status_code = 400;
|
||||
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);
|
||||
if(argPrependInsert)
|
||||
{
|
||||
@ -673,9 +679,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
for(Proxy &x : nodes)
|
||||
x.Group = argGroupName;
|
||||
|
||||
if(subInfo.size() && argAppendUserinfo.get(global.appendUserinfo))
|
||||
response.headers.emplace("Subscription-UserInfo", subInfo);
|
||||
|
||||
//do pre-process now
|
||||
preprocessNodes(nodes, ext);
|
||||
|
||||
@ -886,7 +889,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
|
||||
}
|
||||
writeLog(0, "Generate completed.", LOG_LEVEL_INFO);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
Document jsondata;
|
||||
std::vector<std::string> vArray;
|
||||
if(regMatch(vmess, "vmess://(.*?)@(.*)"))
|
||||
{
|
||||
explodeStdVMess(vmess, node);
|
||||
return;
|
||||
}
|
||||
else if(regMatch(vmess, "vmess://(.*?)\\?(.*)")) //shadowrocket style link
|
||||
|
||||
if(regMatch(vmess, "vmess://([A-Za-z0-9-_]+)\\?(.*)")) //shadowrocket style link
|
||||
{
|
||||
explodeShadowrocket(vmess, node);
|
||||
return;
|
||||
}
|
||||
else if(regMatch(vmess, "vmess://(.*?)@(.*)"))
|
||||
{
|
||||
explodeStdVMess(vmess, node);
|
||||
return;
|
||||
}
|
||||
else if(regMatch(vmess, "vmess1://(.*?)\\?(.*)")) //kitsunebi style link
|
||||
{
|
||||
explodeKitsunebi(vmess, node);
|
||||
|
||||
@ -146,7 +146,10 @@ inline int WebServer::process_request(Request &request, Response &response, std:
|
||||
}
|
||||
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();
|
||||
response.content_type = "text/plain";
|
||||
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_PATCH: request.method = "PATCH"; break;
|
||||
case EVHTTP_REQ_DELETE: request.method = "DELETE"; break;
|
||||
case EVHTTP_REQ_HEAD: request.method = "HEAD"; break;
|
||||
default: break;
|
||||
}
|
||||
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); };
|
||||
|
||||
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_timeout(server.get(), 30);
|
||||
if (event_dispatch() == -1)
|
||||
@ -399,7 +403,7 @@ int WebServer::start_web_server_multi(void *argv)
|
||||
if (evhttp_accept_socket(httpd, nfd) != 0)
|
||||
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_timeout(httpd, 30);
|
||||
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<<" "<<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
|
||||
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
|
||||
enum
|
||||
{
|
||||
@ -30,5 +31,12 @@ enum
|
||||
|
||||
std::string getTime(int type);
|
||||
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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user