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:
Tindy X 2022-03-20 17:34:01 +08:00
parent ebe68f64b1
commit 406b0f2022
No known key found for this signature in database
GPG Key ID: C6AD413169968D58
6 changed files with 56 additions and 15 deletions

View File

@ -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++)

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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