diff --git a/ini_reader.h b/ini_reader.h index 674c57a..ae718bc 100644 --- a/ini_reader.h +++ b/ini_reader.h @@ -7,6 +7,7 @@ typedef std::map> ini_data_struct; typedef std::multimap string_multimap; +typedef std::vector string_array; class INIReader { @@ -31,13 +32,9 @@ private: bool chkIgnore(std::string section) { bool excluded = false, included = false; - if(count(exclude_sections.begin(), exclude_sections.end(), section) > 0) - excluded = true; - if(include_sections.size() != 0) - { - if(count(include_sections.begin(), include_sections.end(), section) > 0) - included = true; - } + excluded = std::find(exclude_sections.cbegin(), exclude_sections.cend(), section) != exclude_sections.cend(); + if(include_sections.size()) + included = std::find(include_sections.cbegin(), include_sections.cend(), section) != include_sections.cend(); else included = true; diff --git a/main.cpp b/main.cpp index f32be8b..dcacfd6 100644 --- a/main.cpp +++ b/main.cpp @@ -17,6 +17,7 @@ #include "multithread.h" //common settings +std::string pref_path = "pref.ini"; string_array def_exclude_remarks, def_include_remarks, rulesets; std::vector ruleset_content_array; std::string listen_address = "127.0.0.1", default_url, managed_config_prefix; @@ -61,10 +62,9 @@ void setcd(char *argv[]) } -std::string refreshRulesets() +std::string refreshRulesets(string_array &ruleset_list, std::vector &rca) { - guarded_mutex guard(on_configuring); - eraseElements(ruleset_content_array); + eraseElements(rca); std::string rule_group, rule_url; ruleset_content rc; @@ -76,7 +76,7 @@ std::string refreshRulesets() else proxy = proxy_ruleset; - for(std::string &x : rulesets) + for(std::string &x : ruleset_list) { /* vArray = split(x, ","); @@ -93,7 +93,7 @@ std::string refreshRulesets() { std::cerr<<"Adding rule '"< rca; + + if(!url.size()) + url = default_url; + if(!url.size() || !target.size()) + return "Invalid request!"; + if(!api_mode || cfw_child_process) + readConf(); + + if(groups.size()) + { + extra_group = split(groups, "@"); + if(!extra_group.size()) + extra_group = clash_extra_group; + } + else + extra_group = clash_extra_group; + + if(ruleset.size()) + { + extra_ruleset = split(ruleset, "@"); + if(!extra_ruleset.size()) + { + if(update_ruleset_on_request || cfw_child_process) + refreshRulesets(rulesets, ruleset_content_array); + rca = ruleset_content_array; + } + else + { + refreshRulesets(extra_ruleset, rca); + } + } + else + { + if(update_ruleset_on_request || cfw_child_process) + refreshRulesets(rulesets, ruleset_content_array); + rca = ruleset_content_array; + } extra_settings ext; if(emoji == "true") @@ -259,13 +299,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) ext.nodelist = nodelist == "true"; ext.surge_ssr_path = surge_ssr_path; - if(!url.size()) - url = default_url; - if(!url.size() || !target.size()) - return "Invalid request!"; - if(!api_mode || cfw_child_process) - readConf(); - string_array urls = split(url, "|"); std::vector nodes; int groupID = 0; @@ -290,8 +323,6 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) } if(!nodes.size()) return "No nodes were found!"; - if(update_ruleset_on_request || cfw_child_process) - refreshRulesets(); std::cerr<<"Generate target: "; if(target == "clash" || target == "clashr") @@ -302,21 +333,22 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) else base_content = webGet(clash_rule_base, getSystemProxy()); - output_content = netchToClash(nodes, base_content, ruleset_content_array, clash_extra_group, target == "clashr", ext); + output_content = netchToClash(nodes, base_content, rca, extra_group, target == "clashr", ext); if(upload == "true") uploadGist("clash", upload_path, output_content, false); return output_content; } else if(target == "surge") { - std::cerr<<"Surge "< std::string { - return refreshRulesets(); + return refreshRulesets(rulesets, ruleset_content_array); }); append_response("GET", "/readconf", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string diff --git a/misc.cpp b/misc.cpp index a98ad61..6f3a20c 100644 --- a/misc.cpp +++ b/misc.cpp @@ -402,6 +402,7 @@ std::string trim(const std::string& str) std::string getUrlArg(std::string url, std::string request) { std::smatch result; + /* if (regex_search(url.cbegin(), url.cend(), result, std::regex(request + "=(.*?)&"))) { return result[1]; @@ -414,6 +415,15 @@ std::string getUrlArg(std::string url, std::string request) { return std::string(); } + */ + + string_array vArray, arglist = split(url, "&"); + for(std::string &x : arglist) + { + if(regex_search(x.cbegin(), x.cend(), result, std::regex("^" + request + "=(.*)$"))) + return result[1]; + } + return std::string(); } std::string replace_all_distinct(std::string str, std::string old_value, std::string new_value) @@ -430,22 +440,43 @@ std::string replace_all_distinct(std::string str, std::string old_value, std::st bool regFind(std::string src, std::string target) { - std::regex reg(target); - return regex_search(src, reg); + try + { + std::regex reg(target); + return regex_search(src, reg); + } + catch (std::regex_error &e) + { + return false; + } } std::string regReplace(std::string src, std::string match, std::string rep) { std::string result = ""; - std::regex reg(match); - regex_replace(back_inserter(result), src.begin(), src.end(), reg, rep); + try + { + std::regex reg(match); + regex_replace(back_inserter(result), src.begin(), src.end(), reg, rep); + } + catch (std::regex_error &e) + { + result = src; + } return result; } bool regMatch(std::string src, std::string match) { - std::regex reg(match); - return regex_match(src, reg); + try + { + std::regex reg(match); + return regex_match(src, reg); + } + catch (std::regex_error &e) + { + return false; + } } std::string speedCalc(double speed) @@ -735,6 +766,19 @@ std::string to_string(const YAML::Node &node) return ss.str(); } +int to_int(std::string &s, int def_vaule) +{ + int retval = 0; + char c; + std::stringstream ss(s); + if(!(ss >> retval)) + return def_vaule; + else if(ss >> c) + return def_vaule; + else + return retval; +} + std::string getFormData(const std::string &raw_data) { std::stringstream strstrm; diff --git a/misc.h b/misc.h index 2cd3186..9bb80b4 100644 --- a/misc.h +++ b/misc.h @@ -52,6 +52,7 @@ void removeUTF8BOM(std::string &data); int shortAssemble(unsigned short num_a, unsigned short num_b); void shortDisassemble(int source, unsigned short &num_a, unsigned short &num_b); std::string to_string(const YAML::Node &node); +int to_int(std::string &s, int def_vaule = 0); std::string fileGet(std::string path, bool binary = true); int fileWrite(std::string path, std::string content, bool overwrite); @@ -78,7 +79,7 @@ namespace std template std::string to_string(const T& n) { std::ostringstream ss; - ss << n ; + ss << n; return ss.str(); } } diff --git a/rules/LocalAreaNetwork.list b/rules/LocalAreaNetwork.list index 0688b1e..a8b9e68 100644 --- a/rules/LocalAreaNetwork.list +++ b/rules/LocalAreaNetwork.list @@ -4,7 +4,7 @@ IP-CIDR,10.0.0.0/8 IP-CIDR,172.16.0.0/12 IP-CIDR,127.0.0.0/8 IP-CIDR,100.64.0.0/10 -IP-CIDR,::1/128 -IP-CIDR,fc00::/7 -IP-CIDR,fe80::/10 -IP-CIDR,fd00::/8 +IP-CIDR6,::1/128 +IP-CIDR6,fc00::/7 +IP-CIDR6,fe80::/10 +IP-CIDR6,fd00::/8 diff --git a/subexport.cpp b/subexport.cpp index d8cafec..2f658c7 100644 --- a/subexport.cpp +++ b/subexport.cpp @@ -610,7 +610,7 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s ini.SetCurrentSection("Proxy"); ini.EraseSection(); - ini.Set("DIRECT", "direct"); + ini.Set("{NONAME}", "DIRECT = direct"); for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); diff --git a/webserver.cpp b/webserver.cpp index ca3361c..6a754ca 100644 --- a/webserver.cpp +++ b/webserver.cpp @@ -10,6 +10,7 @@ #include "webserver.h" typedef std::vector string_array; +int def_timeout = 5; struct responseRoute { @@ -21,7 +22,7 @@ struct responseRoute std::vector responses; -//for use of multi-thread socket test +//for use of multi-thread typedef std::lock_guard guarded_mutex; int working_thread = 0, max_send_failure = 10; bool SERVER_EXIT_FLAG = false; @@ -206,6 +207,21 @@ void send_file(std::string arguments, int sock) sendall(sock, "0\r\n\r\n"); } +int setTimeout(SOCKET s, int timeout) +{ + int ret = -1; +#ifdef _WIN32 + ret = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(int)); + ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(int)); +#else + struct timeval timeo = {0, timeout * 1000}; + ret = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeo, sizeof(timeo)); + ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeo, sizeof(timeo)); +#endif + def_timeout = timeout; + return ret; +} + void handle_req(std::string request, int client_sock) { working_acc(); @@ -220,8 +236,7 @@ void handle_req(std::string request, int client_sock) goto end; } - printf("handle_cmd: %s\n", command); - printf("handle_path: %s\n", arguments); + std::cerr<<"handle_cmd: "< #include #include +#include #include #include @@ -22,10 +23,18 @@ struct responseRoute std::vector responses; +static inline void buffer_cleanup(struct evbuffer *eb) +{ + evbuffer_free(eb); + #ifdef MALLOC_TRIM + malloc_trim(0); + #endif // MALLOC_TRIM +} + static inline int process_request(const char *method_str, std::string uri, std::string &postdata, std::string &content_type, std::string &return_data) { std::string path, arguments; - //std::cerr << "handle_cmd: " << method_str << std::endl << "handle_uri: " << uri << std::endl; + std::cerr << "handle_cmd: " << method_str << std::endl << "handle_uri: " << uri << std::endl; if(strFind(uri, "?")) { @@ -56,7 +65,7 @@ static inline int process_request(const char *method_str, std::string uri, std:: void OnReq(evhttp_request *req, void *args) { const char *req_content_type = evhttp_find_header(req->input_headers, "Content-Type"), *req_ac_method = evhttp_find_header(req->input_headers, "Access-Control-Request-Method"); - const char *req_method = req_ac_method == NULL ? EVBUFFER_LENGTH(req->input_buffer) == 0 ? "GET" : "POST" : "OPTIONS", *uri = evhttp_request_get_uri(req); + const char *req_method = req_ac_method == NULL ? EVBUFFER_LENGTH(req->input_buffer) == 0 ? "GET" : "POST" : "OPTIONS", *uri = req->uri; int retVal; std::string postdata, content_type, return_data; @@ -73,7 +82,8 @@ void OnReq(evhttp_request *req, void *args) retVal = process_request(req_method, uri, postdata, content_type, return_data); - auto *OutBuf = evhttp_request_get_output_buffer(req); + //auto *OutBuf = evhttp_request_get_output_buffer(req); + struct evbuffer *OutBuf = evbuffer_new(); if (!OutBuf) return; @@ -83,7 +93,6 @@ void OnReq(evhttp_request *req, void *args) evhttp_add_header(req->output_headers, "Access-Control-Allow-Origin", "*"); evhttp_add_header(req->output_headers, "Access-Control-Allow-Headers", "*"); evhttp_send_reply(req, HTTP_OK, "", NULL); - return; break; case 0: //found normal if(content_type.size()) @@ -92,6 +101,7 @@ void OnReq(evhttp_request *req, void *args) { evhttp_add_header(req->output_headers, "Location", return_data.c_str()); evhttp_send_reply(req, HTTP_MOVETEMP, "", NULL); + buffer_cleanup(OutBuf); return; } else @@ -108,6 +118,7 @@ void OnReq(evhttp_request *req, void *args) default: //undefined behavior evhttp_send_error(req, HTTP_INTERNAL, ""); } + buffer_cleanup(OutBuf); } int start_web_server(void *argv)