Browse Source

Cleanup codes

inja: Using a better implementation for stripping blanks for expressions.
Tindy X 5 years ago
parent
commit
65ac33d514

+ 24 - 24
include/inja.hpp

@@ -1460,7 +1460,9 @@ struct LexerConfig {
   std::string statement_close_force_rstrip {"-%}"};
   std::string line_statement {"##"};
   std::string expression_open {"{{"};
+  std::string expression_open_force_lstrip {"{{-"};
   std::string expression_close {"}}"};
+  std::string expression_close_force_rstrip {"-}}"};
   std::string comment_open {"{#"};
   std::string comment_close {"#}"};
   std::string open_chars {"#{"};
@@ -1485,6 +1487,9 @@ struct LexerConfig {
     if (open_chars.find(expression_open[0]) == std::string::npos) {
       open_chars += expression_open[0];
     }
+    if (open_chars.find(expression_open_force_lstrip[0]) == std::string::npos) {
+      open_chars += expression_open_force_lstrip[0];
+    }
     if (open_chars.find(comment_open[0]) == std::string::npos) {
       open_chars += comment_open[0];
     }
@@ -1786,7 +1791,7 @@ struct Token {
     Unknown,
     Eof,
   };
-  
+
   Kind kind {Kind::Unknown};
   nonstd::string_view text;
 
@@ -1895,6 +1900,7 @@ class Lexer {
   enum class State {
     Text,
     ExpressionStart,
+    ExpressionStartForceLstrip,
     ExpressionBody,
     LineStart,
     LineBody,
@@ -1918,8 +1924,6 @@ class Lexer {
   nonstd::string_view m_in;
   size_t tok_start;
   size_t pos;
-  bool temp_trim_flag = false;
-
 
   Token scan_body(nonstd::string_view close, Token::Kind closeKind, nonstd::string_view close_trim = nonstd::string_view(), bool trim = false) {
   again:
@@ -1942,22 +1946,13 @@ class Lexer {
       return tok;
     }
 
-    if (ch == '-') {
-      if (inja::string_view::starts_with(m_in.substr(tok_start + 1), close)) {
-        tok_start += 1;
-        temp_trim_flag = true;
-      } else
-        return make_token(Token::Kind::Unknown);
-    }
-
     if (inja::string_view::starts_with(m_in.substr(tok_start), close)) {
       state = State::Text;
       pos = tok_start + close.size();
       Token tok = make_token(closeKind);
-      if (trim || temp_trim_flag) {
+      if (trim) {
         skip_whitespaces_and_first_newline();
       }
-      temp_trim_flag = false;
       return tok;
     }
 
@@ -2192,7 +2187,12 @@ public:
       nonstd::string_view open_str = m_in.substr(pos);
       bool must_lstrip = false;
       if (inja::string_view::starts_with(open_str, config.expression_open)) {
-        state = State::ExpressionStart;
+        if (inja::string_view::starts_with(open_str, config.expression_open_force_lstrip)) {
+          state = State::ExpressionStartForceLstrip;
+          must_lstrip = true;
+        } else {
+          state = State::ExpressionStart;
+        }
       } else if (inja::string_view::starts_with(open_str, config.statement_open)) {
         if (inja::string_view::starts_with(open_str, config.statement_open_no_lstrip)) {
           state = State::StatementStartNoLstrip;
@@ -2227,11 +2227,11 @@ public:
     case State::ExpressionStart: {
       state = State::ExpressionBody;
       pos += config.expression_open.size();
-      // whitespace control
-      if (m_in[pos] == '-') {
-        pos += 1;
-        temp_trim_flag = true;
-      }
+      return make_token(Token::Kind::ExpressionOpen);
+    }
+    case State::ExpressionStartForceLstrip: {
+      state = State::ExpressionBody;
+      pos += config.expression_open_force_lstrip.size();
       return make_token(Token::Kind::ExpressionOpen);
     }
     case State::LineStart: {
@@ -2260,7 +2260,7 @@ public:
       return make_token(Token::Kind::CommentOpen);
     }
     case State::ExpressionBody:
-      return scan_body(config.expression_close, Token::Kind::ExpressionClose);
+      return scan_body(config.expression_close, Token::Kind::ExpressionClose, config.expression_close_force_rstrip);
     case State::LineBody:
       return scan_body("\n", Token::Kind::LineStatementClose);
     case State::StatementBody:
@@ -2869,7 +2869,7 @@ class Parser {
         // Functions
         } else if (peek_tok.kind == Token::Kind::LeftParen) {
           operator_stack.emplace(std::make_shared<FunctionNode>(static_cast<std::string>(tok.text), tok.text.data() - tmpl.content.c_str()));
-          function_stack.emplace(operator_stack.top().get(), current_paren_level);       
+          function_stack.emplace(operator_stack.top().get(), current_paren_level);
 
         // Variables
         } else {
@@ -3477,10 +3477,10 @@ class Renderer : public NodeVisitor  {
   void visit(const JsonNode& node) {
     if (json_additional_data.contains(node.ptr)) {
       json_eval_stack.push(&json_additional_data[node.ptr]);
-    
+
     } else if (json_input->contains(node.ptr)) {
       json_eval_stack.push(&(*json_input)[node.ptr]);
-    
+
     } else {
       // Try to evaluate as a no-argument callback
       auto function_data = function_storage.find_function(node.name, 0);
@@ -4137,4 +4137,4 @@ inline void render_to(std::ostream &os, nonstd::string_view input, const json &d
 // #include "template.hpp"
 
 
-#endif // INCLUDE_INJA_INJA_HPP_
+#endif // INCLUDE_INJA_INJA_HPP_

+ 3 - 2
scripts/Dockerfile

@@ -1,7 +1,8 @@
-FROM alpine:latest
-MAINTAINER Tindy X <[email protected]>
+FROM alpine:3.12
+LABEL maintainer "[email protected]"
 
 # build minimized
+WORKDIR /
 RUN apk add --no-cache --virtual .build-tools git g++ build-base linux-headers cmake python2 && \
     apk add --no-cache --virtual .build-deps curl-dev rapidjson-dev libevent-dev pcre2-dev yaml-cpp-dev && \
     git clone https://github.com/svaarala/duktape --depth=1 && \

+ 1 - 1
scripts/build.alpine.release.sh

@@ -40,6 +40,6 @@ g++ -o base/subconverter $(find CMakeFiles/subconverter.dir/src/ -name "*.o")  -
 
 cd base
 chmod +rx subconverter
-chmod +r *
+chmod +r ./*
 cd ..
 mv base subconverter

+ 1 - 1
scripts/build.macos.release.sh

@@ -43,7 +43,7 @@ c++ -Xlinker -unexported_symbol -Xlinker "*" -o base/subconverter -framework Cor
 
 cd base
 chmod +rx subconverter
-chmod +r *
+chmod +r ./*
 cd ..
 mv base subconverter
 

+ 1 - 1
scripts/config.termux.sh

@@ -25,7 +25,7 @@ cc -c -O3 -o duktape.o duktape.c
 cc -c -O3 -o duk_module_node.o -I. ../extras/module-node/duk_module_node.c
 ar cr libduktape.a duktape.o
 ar cr libduktape_module.a duk_module_node.o
-install -m0644 *.a /data/data/com.termux/files/usr/lib
+install -m0644 ./*.a /data/data/com.termux/files/usr/lib
 install -m0644 duk*.h /data/data/com.termux/files/usr/include
 install -m0644 ../extras/module-node/duk_module_node.h /data/data/com.termux/files/usr/include
 cd ../../..

+ 17 - 19
src/interfaces.cpp

@@ -1451,10 +1451,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
         expand.define(true);
 
     /// read preference from argument, assign global var if not in argument
-    ext.tfo.read(tfo).read(tfo_flag);
-    ext.udp.read(udp).read(udp_flag);
-    ext.skip_cert_verify.read(scv).read(scv_flag);
-    ext.tls13.read(tls13).read(tls13_flag);
+    ext.tfo.parse(tfo).parse(tfo_flag);
+    ext.udp.parse(udp).parse(udp_flag);
+    ext.skip_cert_verify.parse(scv).parse(scv_flag);
+    ext.tls13.parse(tls13).parse(tls13_flag);
 
     ext.sort_flag = sort_flag.get(do_sort);
     use_sort_script.define(sort_script.size() != 0);
@@ -2032,11 +2032,11 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
         singlegroup["type"] = type;
         for(unsigned int i = 1; i < dummy_str_array.size(); i++)
         {
-            if(dummy_str_array[i].find("url") == 0)
+            if(startsWith(dummy_str_array[i], "url"))
                 singlegroup["url"] = trim(dummy_str_array[i].substr(dummy_str_array[i].find("=") + 1));
-            else if(dummy_str_array[i].find("interval") == 0)
+            else if(startsWith(dummy_str_array[i], "interval"))
                 singlegroup["interval"] = trim(dummy_str_array[i].substr(dummy_str_array[i].find("=") + 1));
-            else if(dummy_str_array[i].find("policy-path") == 0)
+            else if(startsWith(dummy_str_array[i], "policy-path"))
                 links.emplace_back(trim(dummy_str_array[i].substr(dummy_str_array[i].find("=") + 1)));
             else
                 singlegroup["proxies"].push_back(trim(dummy_str_array[i]));
@@ -2114,9 +2114,7 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
     std::string::size_type lineSize;
     for(std::string &x : dummy_str_array)
     {
-        if(x.find("USER-AGENT") == 0 || x.find("URL-REGEX") == 0 || x.find("PROCESS-NAME") == 0 || x.find("AND") == 0 || x.find("OR") == 0) //remove unsupported types
-            continue;
-        else if(x.find("RULE-SET") == 0)
+        if(startsWith(x, "RULE-SET"))
         {
             strArray = split(x, ",");
             if(strArray.size() != 3)
@@ -2135,7 +2133,7 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
                     strLine.erase(--lineSize);
                 if(!lineSize || strLine[0] == ';' || strLine[0] == '#' || (lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored
                     continue;
-                else if(strLine.find("USER-AGENT") == 0 || strLine.find("URL-REGEX") == 0 || strLine.find("PROCESS-NAME") == 0 || strLine.find("AND") == 0 || strLine.find("OR") == 0) //remove unsupported types
+                else if(!std::any_of(clash_rule_type.begin(), clash_rule_type.end(), [&strLine](std::string type){return startsWith(strLine, type);})) //remove unsupported types
                     continue;
                 strLine += strArray[2];
                 if(count_least(strLine, ',', 3))
@@ -2145,6 +2143,8 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS)
             ss.clear();
             continue;
         }
+        else if(!std::any_of(clash_rule_type.begin(), clash_rule_type.end(), [&strLine](std::string type){return startsWith(strLine, type);}))
+            continue;
         rule.push_back(x);
     }
     clash[rule_name] = rule;
@@ -2456,12 +2456,10 @@ int simpleGenerator()
     std::string proxy = parseProxy(proxy_subscription);
     Request request;
     Response response;
-    int &ret_code = response.status_code;
-    string_map &headers = response.headers;
     for(std::string &x : sections)
     {
         arguments.clear();
-        ret_code = 200;
+        response.status_code = 200;
         //std::cerr<<"Generating artifact '"<<x<<"'...\n";
         writeLog(0, "Generating artifact '" + x + "'...", LOG_LEVEL_INFO);
         ini.EnterSection(x);
@@ -2508,7 +2506,7 @@ int simpleGenerator()
             request.argument = arguments;
             content = subconverter(request, response);
         }
-        if(ret_code != 200)
+        if(response.status_code != 200)
         {
             //std::cerr<<"Artifact '"<<x<<"' generate ERROR! Reason: "<<content<<"\n\n";
             writeLog(0, "Artifact '" + x + "' generate ERROR! Reason: " + content + "\n", LOG_LEVEL_ERROR);
@@ -2517,12 +2515,12 @@ int simpleGenerator()
             continue;
         }
         fileWrite(path, content, true);
-        auto iter = std::find_if(headers.begin(), headers.end(), [](auto y){ return y.first == "Subscription-UserInfo"; });
-        if(iter != headers.end())
+        auto iter = std::find_if(response.headers.begin(), response.headers.end(), [](auto y){ return y.first == "Subscription-UserInfo"; });
+        if(iter != response.headers.end())
             writeLog(0, "User Info for artifact '" + x + "': " + subInfoToMessage(iter->second), LOG_LEVEL_INFO);
         //std::cerr<<"Artifact '"<<x<<"' generate SUCCESS!\n\n";
         writeLog(0, "Artifact '" + x + "' generate SUCCESS!\n", LOG_LEVEL_INFO);
-        eraseElements(headers);
+        eraseElements(response.headers);
     }
     //std::cerr<<"All artifact generated. Exiting...\n";
     writeLog(0, "All artifact generated. Exiting...", LOG_LEVEL_INFO);
@@ -2537,7 +2535,7 @@ std::string renderTemplate(RESPONSE_CALLBACK_ARGS)
     std::string path = UrlDecode(getUrlArg(argument, "path"));
     writeLog(0, "Trying to render template '" + path + "'...", LOG_LEVEL_INFO);
 
-    if(path.find(template_path) != 0 || !fileExist(path))
+    if(startsWith(path, template_path) || !fileExist(path))
     {
         *status_code = 404;
         return "Not found";

+ 13 - 25
src/main.cpp

@@ -135,7 +135,7 @@ int main(int argc, char *argv[])
     generateBase();
 
     std::string env_api_mode = GetEnv("API_MODE"), env_managed_prefix = GetEnv("MANAGED_PREFIX"), env_token = GetEnv("API_TOKEN");
-    api_mode = tribool().read(toLower(env_api_mode)).get(api_mode);
+    api_mode = tribool().parse(toLower(env_api_mode)).get(api_mode);
     if(env_managed_prefix.size())
         managed_config_prefix = env_managed_prefix;
     if(env_token.size())
@@ -156,15 +156,12 @@ int main(int argc, char *argv[])
 
     append_response("GET", "/refreshrules", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string
     {
-        std::string &argument = request.argument;
-        int *status_code = &response.status_code;
-
         if(access_token.size())
         {
-            std::string token = getUrlArg(argument, "token");
+            std::string token = getUrlArg(request.argument, "token");
             if(token != access_token)
             {
-                *status_code = 403;
+                response.status_code = 403;
                 return "Forbidden\n";
             }
         }
@@ -175,15 +172,12 @@ int main(int argc, char *argv[])
 
     append_response("GET", "/readconf", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string
     {
-        std::string &argument = request.argument;
-        int *status_code = &response.status_code;
-
         if(access_token.size())
         {
-            std::string token = getUrlArg(argument, "token");
+            std::string token = getUrlArg(request.argument, "token");
             if(token != access_token)
             {
-                *status_code = 403;
+                response.status_code = 403;
                 return "Forbidden\n";
             }
         }
@@ -194,27 +188,23 @@ int main(int argc, char *argv[])
 
     append_response("POST", "/updateconf", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string
     {
-        std::string &argument = request.argument;
-        std::string postdata = request.postdata;
-        int *status_code = &response.status_code;
-
         if(access_token.size())
         {
-            std::string token = getUrlArg(argument, "token");
+            std::string token = getUrlArg(request.argument, "token");
             if(token != access_token)
             {
-                *status_code = 403;
+                response.status_code = 403;
                 return "Forbidden\n";
             }
         }
-        std::string type = getUrlArg(argument, "type");
+        std::string type = getUrlArg(request.argument, "type");
         if(type == "form")
-            fileWrite(pref_path, getFormData(postdata), true);
+            fileWrite(pref_path, getFormData(request.postdata), true);
         else if(type == "direct")
-            fileWrite(pref_path, postdata, true);
+            fileWrite(pref_path, request.postdata, true);
         else
         {
-            *status_code = 501;
+            response.status_code = 501;
             return "Not Implemented\n";
         }
 
@@ -247,15 +237,13 @@ int main(int argc, char *argv[])
     {
         append_response("GET", "/get", "text/plain;charset=utf-8", [](RESPONSE_CALLBACK_ARGS) -> std::string
         {
-            std::string &argument = request.argument;
-            std::string url = UrlDecode(getUrlArg(argument, "url"));
+            std::string url = UrlDecode(getUrlArg(request.argument, "url"));
             return webGet(url, "");
         });
 
         append_response("GET", "/getlocal", "text/plain;charset=utf-8", [](RESPONSE_CALLBACK_ARGS) -> std::string
         {
-            std::string &argument = request.argument;
-            return fileGet(UrlDecode(getUrlArg(argument, "path")));
+            return fileGet(UrlDecode(getUrlArg(request.argument, "path")));
         });
     }
 

+ 5 - 7
src/md5.cpp

@@ -596,14 +596,13 @@ namespace md5 {
         unsigned char* sig_p;
         char* str_p;
         char* max_p;
-        unsigned int high, low;
 
         str_p = str_;
         max_p = str_ + str_len;
 
         for (sig_p = (unsigned char*)signature_; sig_p < (unsigned char*)signature_ + MD5_SIZE; sig_p++) {
-            high = *sig_p / 16;
-            low = *sig_p % 16;
+            unsigned int high = *sig_p / 16;
+            unsigned int low = *sig_p % 16;
             /* account for 2 chars */
             if (str_p + 1 >= max_p) {
                 break;
@@ -640,15 +639,14 @@ namespace md5 {
         unsigned char *sig_p;
         const char *str_p;
         char* hex;
-        unsigned int high, low, val;
 
         hex = (char*)md5::HEX_STRING;
         sig_p = static_cast<unsigned char*>(signature_);
 
         for (str_p = str_; str_p < str_ + MD5_SIZE * 2; str_p += 2) {
-            high = strchr(hex, *str_p) - hex;
-            low = strchr(hex, *(str_p + 1)) - hex;
-            val = high * 16 + low;
+            unsigned int high = strchr(hex, *str_p) - hex;
+            unsigned int low = strchr(hex, *(str_p + 1)) - hex;
+            unsigned int val = high * 16 + low;
             *sig_p++ = val;
         }
     }

+ 10 - 15
src/misc.cpp

@@ -77,10 +77,8 @@ std::string ACPToUTF8(const std::string &str_src)
     memset(str, 0, len + 1);
     WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
     std::string strTemp = str;
-    if(wstr)
-        delete[] wstr;
-    if(str)
-        delete[] str;
+    delete[] wstr;
+    delete[] str;
     return strTemp;
 #else
     return str_src;
@@ -209,7 +207,7 @@ std::string base64_encode(const std::string &string_to_encode)
     unsigned int in_len = string_to_encode.size();
 
     std::string ret;
-    int i = 0, j;
+    int i = 0;
     unsigned char char_array_3[3];
     unsigned char char_array_4[4];
 
@@ -231,6 +229,7 @@ std::string base64_encode(const std::string &string_to_encode)
 
     if (i)
     {
+        int j;
         for(j = i; j < 3; j++)
             char_array_3[j] = '\0';
 
@@ -445,10 +444,9 @@ std::string getSystemProxy()
     return std::string();
 #else
     string_array proxy_env = {"all_proxy", "ALL_PROXY", "http_proxy", "HTTP_PROXY", "https_proxy", "HTTPS_PROXY"};
-    char* proxy;
     for(std::string &x : proxy_env)
     {
-        proxy = getenv(x.c_str());
+        char* proxy = getenv(x.c_str());
         if(proxy != NULL)
             return std::string(proxy);
     }
@@ -842,7 +840,7 @@ bool isInScope(const std::string &path)
     if(path.find(":\\") != path.npos || path.find("..") != path.npos)
         return false;
 #else
-    if(path.find("/") == 0 || path.find("..") != path.npos)
+    if(startsWith(path, "/") || path.find("..") != path.npos)
         return false;
 #endif // _WIN32
     return true;
@@ -1036,10 +1034,9 @@ bool is_str_utf8(const std::string &data)
 {
     const char *str = data.c_str();
     unsigned int nBytes = 0;
-    unsigned char chr;
     for (unsigned int i = 0; str[i] != '\0'; ++i)
     {
-        chr = *(str + i);
+        unsigned char chr = *(str + i);
         if (nBytes == 0)
         {
             if (chr >= 0x80)
@@ -1122,7 +1119,7 @@ std::string getFormData(const std::string &raw_data)
     {
         if(i == 0)
             boundary = line.substr(0, line.length() - 1); // Get boundary
-        else if(line.find(boundary) == 0)
+        else if(startsWith(line, boundary))
             break; // The end
         else if(line.length() == 1)
         {
@@ -1134,11 +1131,10 @@ std::string getFormData(const std::string &raw_data)
             while(!endfile)
             {
                 int j = 0;
-                int k;
                 while(j < 256 && strstrm.get(c) && !endfile)
                 {
                     buffer[j] = c;
-                    k = 0;
+                    int k = 0;
                     // Verify if we are at the end
                     while(boundary[bl - 1 - k] == buffer[j - k])
                     {
@@ -1165,10 +1161,9 @@ std::string getFormData(const std::string &raw_data)
 std::string UTF8ToCodePoint(const std::string &data)
 {
     std::stringstream ss;
-    int charcode;
     for(std::string::size_type i = 0; i < data.size(); i++)
     {
-        charcode = data[i] & 0xff;
+        int charcode = data[i] & 0xff;
         if((charcode >> 7) == 0)
         {
             ss<<data[i];

+ 1 - 1
src/misc.h

@@ -190,7 +190,7 @@ public:
         return *this;
     }
 
-    template <typename T> tribool read(const T &value)
+    template <typename T> tribool parse(const T &value)
     {
         define(value);
         return *this;

+ 1 - 1
src/nodemanip.cpp

@@ -146,7 +146,7 @@ int addNodes(std::string link, std::vector<nodeInfo> &allNodes, int groupID, con
             writeLog(LOG_TYPE_ERROR, "Invalid configuration file!");
             return -1;
         }
-        if(strSub.find("ssd://") == 0)
+        if(startsWith(strSub, "ssd://"))
         {
             getSubInfoFromSSD(strSub, subInfo);
         }

+ 2 - 3
src/script.cpp

@@ -65,10 +65,9 @@ duk_ret_t cb_resolve_module(duk_context *ctx)
     const char *requested_id = duk_get_string(ctx, 0);
     const char *parent_id = duk_get_string(ctx, 1);  /* calling module */
     //const char *resolved_id;
-    std::string resolved_id;
-    if(strlen(parent_id))
+    std::string resolved_id, parent_path = parent_id;
+    if(!parent_path.empty())
     {
-        std::string parent_path = parent_id;
         string_size pos = parent_path.rfind("/");
         if(pos != parent_path.npos)
             resolved_id += parent_path.substr(0, pos + 1);

+ 2 - 2
src/speedtestutil.cpp

@@ -647,7 +647,7 @@ void explodeSocks(std::string link, const std::string &custom_port, nodeInfo &no
     node.proxyStr = socksConstruct(group, remarks, server, port, username, password);
 }
 
-void explodeHTTP(const std::string link, const std::string &custom_port, nodeInfo &node)
+void explodeHTTP(const std::string &link, const std::string &custom_port, nodeInfo &node)
 {
     std::string group, remarks, server, port, username, password;
     server = getUrlArg(link, "server");
@@ -1942,7 +1942,7 @@ int explodeConfContent(const std::string &content, const std::string &custom_por
         return SPEEDTEST_ERROR_NONE;
 }
 
-void explode(std::string link, bool sslibev, bool ssrlibev, const std::string &custom_port, nodeInfo &node)
+void explode(const std::string &link, bool sslibev, bool ssrlibev, const std::string &custom_port, nodeInfo &node)
 {
     // TODO: replace strFind with startsWith if appropriate
     if(strFind(link, "ssr://"))

+ 1 - 1
src/speedtestutil.h

@@ -21,7 +21,7 @@ void explodeQuan(const std::string &quan, const std::string &custom_port, nodeIn
 void explodeShadowrocket(std::string kit, const std::string &custom_port, nodeInfo &node);
 void explodeKitsunebi(std::string kit, const std::string &custom_port, nodeInfo &node);
 /// Parse a link
-void explode(std::string link, bool sslibev, bool ssrlibev, const std::string &custom_port, nodeInfo &node);
+void explode(const std::string &link, bool sslibev, bool ssrlibev, const std::string &custom_port, nodeInfo &node);
 void explodeSSD(std::string link, bool libev, const std::string &custom_port, std::vector<nodeInfo> &nodes);
 void explodeSub(std::string sub, bool sslibev, bool ssrlibev, const std::string &custom_port, std::vector<nodeInfo> &nodes);
 int explodeConf(std::string filepath, const std::string &custom_port, bool sslibev, bool ssrlibev, std::vector<nodeInfo> &nodes);

+ 2 - 2
src/subexport.cpp

@@ -658,10 +658,10 @@ void rulesetToClash(YAML::Node &base_rule, std::vector<ruleset_content> &ruleset
             writeLog(0, "Failed to fetch ruleset or ruleset is empty: '" + x.rule_path + "'!", LOG_LEVEL_WARNING);
             continue;
         }
-        if(retrieved_rules.find("[]") == 0)
+        if(startsWith(retrieved_rules, "[]"))
         {
             strLine = retrieved_rules.substr(2);
-            if(strLine.find("FINAL") == 0)
+            if(startsWith(strLine, "FINAL"))
                 strLine.replace(0, 5, "MATCH");
             strLine += "," + rule_group;
             if(count_least(strLine, ',', 3))

+ 2 - 2
src/templates.cpp

@@ -17,7 +17,7 @@ namespace inja
 {
     void convert_dot_to_json_pointer(nonstd::string_view dot, std::string& out)
     {
-        out = std::move(JsonNode(dot, 0).ptr);
+        out = JsonNode::convert_dot_to_json_ptr(dot);
     }
 }
 
@@ -283,7 +283,7 @@ int renderClashScript(YAML::Node &base_rule, std::vector<ruleset_content> &rules
                 }
                 continue;
             }
-            if(strLine.find("FINAL") == 0)
+            if(startsWith(strLine, "FINAL"))
                 strLine.replace(0, 5, "MATCH");
             strLine += "," + rule_group;
             if(count_least(strLine, ',', 3))

+ 2 - 2
src/webget.cpp

@@ -96,7 +96,7 @@ static inline void curl_set_common_options(CURL *curl_handle, const char *url, c
 }
 
 //static std::string curlGet(const std::string &url, const std::string &proxy, std::string &response_headers, CURLcode &return_code, const string_map &request_headers)
-static int curlGet(const FetchArgument argument, FetchResult &result)
+static int curlGet(const FetchArgument &argument, FetchResult &result)
 {
     CURL *curl_handle;
     std::string *data = result.content, new_url = argument.url;
@@ -281,7 +281,7 @@ int curlPost(const std::string &url, const std::string &data, const std::string
 
     if(res == CURLE_OK)
     {
-        res = curl_easy_getinfo(curl_handle, CURLINFO_HTTP_CODE, &retVal);
+        curl_easy_getinfo(curl_handle, CURLINFO_HTTP_CODE, &retVal);
     }
 
     curl_easy_cleanup(curl_handle);

+ 0 - 370
src/webserver.cpp

@@ -1,370 +0,0 @@
-#include <iostream>
-#include <fstream>
-#include <map>
-#include <atomic>
-#include <thread>
-#include <pthread.h>
-
-#include "misc.h"
-#include "socket.h"
-#include "webserver.h"
-
-typedef std::vector<std::string> string_array;
-int def_timeout = 5;
-
-struct responseRoute
-{
-    std::string method;
-    std::string path;
-    std::string content_type;
-    response_callback rc;
-};
-
-std::vector<responseRoute> responses;
-
-//for use of multi-thread
-int max_send_failure = 10;
-std::atomic_bool SERVER_EXIT_FLAG(false);
-std::atomic_int working_thread(0)
-
-int sendall(SOCKET sock, std::string data)
-{
-    unsigned int total = 0, bytesleft = data.size();
-    int sent = 0;
-    const char* datastr = data.data();
-    while(total < bytesleft)
-    {
-        sent = send(sock, datastr + total, bytesleft, 0);
-        if(sent < 0)
-        {
-            std::cerr<<strerror(errno)<<std::endl;
-            if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
-            {
-                continue;
-            }
-            else
-            {
-                break;
-            }
-        }
-        total += sent;
-        bytesleft -= sent;
-    }
-    return sent == -1 ? -1 : 0;
-}
-
-void wrong_req(SOCKET sock)
-{
-    std::string response = "HTTP/1.1 501 Not Implemented\r\n"
-                           "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\n"
-                           "Content-Type: text/plain\r\n\r\n"
-                           "The command is not yet completed\r\n";
-
-    if (sendall(sock, response) == -1)
-    {
-        std::cerr << "Sending failed!" << std::endl;
-    }
-}
-
-void file_not_found(std::string arguments, int sock)
-{
-    std::string prompt_info = "Not found:  " + arguments;
-    std::string response = "HTTP/1.1 404 Not Found\r\n"
-                           "Content-Type: text/plain\r\nConnection: close\r\n"
-                           "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\n"
-                           "Content-Length: " + std::__cxx11::to_string(prompt_info.size()) + "\r\n\r\n" + prompt_info + "\r\n";
-
-    if (sendall(sock, response) == -1)
-    {
-        printf("Sending error!");
-        return;
-    }
-}
-
-void send_header(SOCKET send_to, std::string content_type)
-{
-    std::string header = "HTTP/1.1 200 OK\r\nConnection: close\r\nCache-Control: no-cache, no-store, must-revalidate\r\nAccess-Control-Allow-Origin: *\r\n";
-    if(content_type.size())
-        header += "Content-Type: " + content_type + "\r\n";
-    if(sendall(send_to, header) == -1)
-    {
-        printf("Sending error!");
-    }
-}
-
-void send_options_header(SOCKET send_to)
-{
-    std::string header = "HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\n";
-    if(sendall(send_to, header) == -1)
-    {
-        printf("Sending error!");
-    }
-}
-
-char* file_type(const char* arg)
-{
-    char * temp;
-    if ((temp=strrchr(arg,'.')) != NULL)
-    {
-        return temp+1;
-    }
-    return nullptr;
-}
-
-void serve_options(SOCKET sock)
-{
-    send_options_header(sock);
-    std::string extra_header = "Content-Length: 0\r\n\r\n";
-    sendall(sock, extra_header);
-    sendall(sock, "\r\n\r\n");
-}
-
-void serve_content(SOCKET sock, std::string type, std::string content)
-{
-    send_header(sock, type.data());
-    std::string extra_header = "Content-Length: " + std::__cxx11::to_string(content.size()) + "\r\n";
-    sendall(sock, extra_header);
-    send(sock, "\r\n", 2, 0);
-    if (sendall(sock, content) == -1)
-    {
-        printf("Sending error!");
-    }
-    sendall(sock, "\r\n\r\n");
-}
-
-void send_file(std::string arguments, int sock)
-{
-    char* extension = file_type(arguments.data());
-    std::string content_type = "text/plain", data;
-    char sizestr[16] = {};
-    int len;
-
-    if (strcmp(extension, "html") == 0)
-    {
-        content_type = "text/html";
-    }
-    if (strcmp(extension, "gif") == 0)
-    {
-        content_type = "image/gif";
-    }
-    if (strcmp(extension, "jpg") == 0)
-    {
-        content_type = "image/jpg";
-    }
-
-    send_header(sock, content_type);
-    sendall(sock, "Transfer-Encoding: chunked\r\n\r\n");
-    data = fileGet(arguments);
-    len = data.size();
-    sprintf(sizestr, "%x\r\n", len);
-    if (sendall(sock, sizestr) == -1)
-    {
-        printf("Sending error!");
-    }
-    if (sendall(sock, data) == -1)
-    {
-        printf("Sending error!");
-    }
-    len = 2;
-    sendall(sock, "\r\n");
-
-    len = 7;
-    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 = {timeout / 1000, (timeout % 1000) * 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_thread++;
-    std::cerr<<"worker startup"<<std::endl;
-    string_array vArray;
-    char command[16] = {};
-    char arguments[BUFSIZ] = {};
-    std::string uri, args, target, postdata;
-
-    if (sscanf(request.data(), "%s%s", command, arguments) != 2)
-    {
-        goto end;
-    }
-
-    std::cerr<<"handle_cmd:    "<<command<<"\n"<<"handle_path:   "<<arguments<<"\n";
-
-    vArray = split(arguments, "?");
-
-    if(vArray.size() > 2)
-    {
-        wrong_req(client_sock);
-        goto end;
-    }
-    else if(vArray.size() > 1)
-    {
-        uri = vArray[0];
-        args = vArray[1];
-    }
-    else
-        uri = arguments;
-
-    if(strcmp(command, "POST") == 0)
-    {
-        if(request.find("\r\n\r\n") != request.npos)
-            postdata = request.substr(request.find("\r\n\r\n") + 4);
-    }
-    else if(strcmp(command, "OPTIONS") == 0)
-    {
-        serve_options(client_sock);
-        goto end;
-    }
-
-    for(std::vector<responseRoute>::iterator iter = responses.begin(); iter != responses.end(); ++iter)
-    {
-        if(iter->method.compare(command) == 0 && iter->path == uri)
-        {
-            response_callback &rc = iter->rc;
-            serve_content(client_sock, iter->content_type, rc(args, postdata));
-            goto end;
-        }
-    }
-    file_not_found(uri, client_sock);
-
-end:
-    std::cerr<<"worker stop"<<std::endl;
-    sleep(1);
-    closesocket(client_sock);
-    working_thread--;
-}
-
-void append_response(const std::string &type, const std::string &request, const std::string &content_type, response_callback response)
-{
-    responseRoute rr;
-    rr.method = type;
-    rr.path = request;
-    rr.content_type = content_type;
-    rr.rc = response;
-    responses.push_back(std::move(rr));
-}
-
-void stop_web_server()
-{
-    SERVER_EXIT_FLAG = true;
-}
-
-int start_web_server(void *argv)
-{
-    struct listener_args *args = (listener_args*)argv;
-    args->max_workers = 1;
-    return start_web_server_multi(args);
-}
-
-int start_web_server_multi(void *argv)
-{
-    //log startup
-    struct listener_args *args = (listener_args*)argv;
-    std::string listen_address = args->listen_address, request;
-    int port = args->port, max_conn = args->max_conn, max_workers = args->max_workers, numbytes, worker_index = 0;
-    socklen_t sock_size = sizeof(struct sockaddr_in);
-    char buf[BUFSIZ];
-    struct sockaddr_in user_socket, server_addr;
-    SOCKET acc_socket;
-    int server_socket, fail_counter = 0;
-    server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
-    std::thread workers[max_workers];
-
-    if (server_socket == -1)
-    {
-        //log socket error
-        std::cerr<<"socket build error!"<<std::endl;
-        return 0;
-    }
-
-    ZeroMemory(&server_addr, sizeof(server_addr));
-    server_addr.sin_family = AF_INET;
-    server_addr.sin_port = htons((short)port);
-    server_addr.sin_addr.s_addr = inet_addr(listen_address.data());
-    if (::bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
-    {
-        //log bind error
-        std::cerr<<"socket bind error!"<<std::endl;
-        closesocket(server_socket);
-        return 0;
-    }
-    if (listen(server_socket, max_conn) == -1 )
-    {
-        //log listen error
-        std::cerr<<"socket listen error!"<<std::endl;
-        closesocket(server_socket);
-        return 0;
-    }
-    setTimeout(server_socket, 500);
-
-    while(true)
-    {
-        acc_socket = accept(server_socket, (struct sockaddr *)&user_socket, &sock_size); //wait for connection
-        if(acc_socket < 0)
-        {
-            if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
-            {
-                fail_counter++;
-                if(fail_counter > max_send_failure)
-                    break;
-                continue;
-            }
-            else
-            {
-                break;
-            }
-        }
-        request = "";
-        while(true) //receive the complete request
-        {
-            numbytes = recv(acc_socket, buf, BUFSIZ - 1, 0);
-            if(numbytes > 0) //received
-                request.append(buf);
-            if(numbytes < 0)
-            {
-                if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
-                {
-                    continue;
-                }
-                else
-                {
-                    break;
-                }
-            }
-            if(numbytes == 0)
-                break;
-        }
-
-        //handle_req(buf, acc_socket);
-
-        while(working_thread >= max_workers)
-        {
-            sleep(10);
-            if(SERVER_EXIT_FLAG)
-                break;
-        }
-        while(workers[worker_index].get_id() != std::thread::id())
-        {
-            worker_index++;
-        }
-        workers[worker_index] = std::thread(handle_req, request, acc_socket);
-        workers[worker_index].detach();
-        worker_index++;
-        if(worker_index > max_workers)
-            worker_index = 0;
-    }
-    return 0;
-}

+ 15 - 20
src/webserver_libevent.cpp

@@ -55,7 +55,7 @@ static inline int process_request(Request &request, Response &response, std::str
 
     for(responseRoute &x : responses)
     {
-        if(request.method == "OPTIONS" && request.postdata.find(x.method) != 0 && x.path == request.url)
+        if(request.method == "OPTIONS" && startsWith(request.postdata, x.method) && x.path == request.url)
         {
             return 1;
         }
@@ -227,19 +227,23 @@ void* httpserver_dispatch(void *arg)
 
 int httpserver_bindsocket(std::string listen_address, int listen_port, int backlog)
 {
-    int ret;
     SOCKET nfd;
     nfd = socket(AF_INET, SOCK_STREAM, 0);
     if (nfd <= 0)
+        return -1;
+
+    int one = 1;
+    if (setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int)) < 0)
     {
         closesocket(nfd);
         return -1;
     }
-
-    int one = 1;
-    ret = setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int));
 #ifdef SO_NOSIGPIPE
-    ret = setsockopt(nfd, SOL_SOCKET, SO_NOSIGPIPE, (char *)&one, sizeof(int));
+    if (setsockopt(nfd, SOL_SOCKET, SO_NOSIGPIPE, (char *)&one, sizeof(int)) < 0)
+    {
+        closesocket(nfd);
+        return -1;
+    }
 #endif
 
     struct sockaddr_in addr;
@@ -248,14 +252,7 @@ int httpserver_bindsocket(std::string listen_address, int listen_port, int backl
     addr.sin_addr.s_addr = inet_addr(listen_address.data());
     addr.sin_port = htons(listen_port);
 
-    ret = ::bind(nfd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
-    if (ret < 0)
-    {
-        closesocket(nfd);
-        return -1;
-    }
-    ret = listen(nfd, backlog);
-    if (ret < 0)
+    if (::bind(nfd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0 || listen(nfd, backlog) < 0)
     {
         closesocket(nfd);
         return -1;
@@ -272,7 +269,7 @@ int start_web_server_multi(void *argv)
     struct listener_args *args = reinterpret_cast<listener_args*>(argv);
     std::string listen_address = args->listen_address;
     int port = args->port, nthreads = args->max_workers;
-    int i, ret;
+    int i;
 
     int nfd = httpserver_bindsocket(listen_address, port, args->max_conn);
     if (nfd < 0)
@@ -288,18 +285,16 @@ int start_web_server_multi(void *argv)
         struct evhttp *httpd = evhttp_new(base[i]);
         if (httpd == NULL)
             return -1;
-        ret = evhttp_accept_socket(httpd, nfd);
-        if (ret != 0)
+        if (evhttp_accept_socket(httpd, nfd) != 0)
             return -1;
 
         evhttp_set_allowed_methods(httpd, EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_OPTIONS);
         evhttp_set_gencb(httpd, OnReq, nullptr);
         evhttp_set_timeout(httpd, 30);
-        ret = pthread_create(&ths[i], NULL, httpserver_dispatch, base[i]);
-        if (ret != 0)
+        if (pthread_create(&ths[i], NULL, httpserver_dispatch, base[i]) != 0)
             return -1;
     }
-    while(!SERVER_EXIT_FLAG)
+    while (!SERVER_EXIT_FLAG)
         sleep(200); //block forever until receive stop signal
 
     for (i = 0; i < nthreads; i++)