Skip to content

Commit

Permalink
Enhancements
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tindy2013 committed Mar 20, 2022
1 parent ebe68f6 commit 406b0f2
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/config/binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
Expand Down
13 changes: 8 additions & 5 deletions src/handler/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}

Expand Down
9 changes: 5 additions & 4 deletions src/parser/subparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,15 @@ 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://(.*?)@(.*)"))

if(regMatch(vmess, "vmess://([A-Za-z0-9-_]+)\\?(.*)")) //shadowrocket style link
{
explodeStdVMess(vmess, node);
explodeShadowrocket(vmess, node);
return;
}
else if(regMatch(vmess, "vmess://(.*?)\\?(.*)")) //shadowrocket style link
else if(regMatch(vmess, "vmess://(.*?)@(.*)"))
{
explodeShadowrocket(vmess, node);
explodeStdVMess(vmess, node);
return;
}
else if(regMatch(vmess, "vmess1://(.*?)\\?(.*)")) //kitsunebi style link
Expand Down
10 changes: 7 additions & 3 deletions src/server/webserver_libevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
25 changes: 25 additions & 0 deletions src/utils/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions src/utils/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define LOGGER_H_INCLUDED

#include <string>
#include <typeinfo>

enum
{
Expand Down Expand Up @@ -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

0 comments on commit 406b0f2

Please sign in to comment.