From 65ac33d514e3075639a477ca3403db196bb86b46 Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Wed, 12 Aug 2020 02:03:00 +0800 Subject: [PATCH] Cleanup codes inja: Using a better implementation for stripping blanks for expressions. --- include/inja.hpp | 48 ++--- scripts/Dockerfile | 5 +- scripts/build.alpine.release.sh | 2 +- scripts/build.macos.release.sh | 2 +- scripts/config.termux.sh | 2 +- src/interfaces.cpp | 36 ++-- src/main.cpp | 38 ++-- src/md5.cpp | 12 +- src/misc.cpp | 25 +-- src/misc.h | 2 +- src/nodemanip.cpp | 2 +- src/script.cpp | 5 +- src/speedtestutil.cpp | 4 +- src/speedtestutil.h | 2 +- src/subexport.cpp | 4 +- src/templates.cpp | 4 +- src/webget.cpp | 4 +- src/webserver.cpp | 370 -------------------------------- src/webserver_libevent.cpp | 35 ++- 19 files changed, 103 insertions(+), 499 deletions(-) delete mode 100644 src/webserver.cpp diff --git a/include/inja.hpp b/include/inja.hpp index c85be0a..4d9f81e 100644 --- a/include/inja.hpp +++ b/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(static_cast(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_ \ No newline at end of file +#endif // INCLUDE_INJA_INJA_HPP_ diff --git a/scripts/Dockerfile b/scripts/Dockerfile index f3ec5bc..d59ec1d 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -1,7 +1,8 @@ -FROM alpine:latest -MAINTAINER Tindy X +FROM alpine:3.12 +LABEL maintainer "tindy.it@gmail.com" # 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 && \ diff --git a/scripts/build.alpine.release.sh b/scripts/build.alpine.release.sh index 875c617..ce35765 100644 --- a/scripts/build.alpine.release.sh +++ b/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 diff --git a/scripts/build.macos.release.sh b/scripts/build.macos.release.sh index fb20241..011b12d 100644 --- a/scripts/build.macos.release.sh +++ b/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 diff --git a/scripts/config.termux.sh b/scripts/config.termux.sh index b49a2ed..5a2a31b 100644 --- a/scripts/config.termux.sh +++ b/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 ../../.. diff --git a/src/interfaces.cpp b/src/interfaces.cpp index 0071a92..34b655d 100644 --- a/src/interfaces.cpp +++ b/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 '"<second), LOG_LEVEL_INFO); //std::cerr<<"Artifact '"< 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"))); }); } diff --git a/src/md5.cpp b/src/md5.cpp index 7b9073e..8f012ea 100644 --- a/src/md5.cpp +++ b/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(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; } } diff --git a/src/misc.cpp b/src/misc.cpp index d890d8d..ea3bb71 100644 --- a/src/misc.cpp +++ b/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< tribool read(const T &value) + template tribool parse(const T &value) { define(value); return *this; diff --git a/src/nodemanip.cpp b/src/nodemanip.cpp index 91c3fa3..5012392 100644 --- a/src/nodemanip.cpp +++ b/src/nodemanip.cpp @@ -146,7 +146,7 @@ int addNodes(std::string link, std::vector &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); } diff --git a/src/script.cpp b/src/script.cpp index 1c10969..129a2e8 100644 --- a/src/script.cpp +++ b/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); diff --git a/src/speedtestutil.cpp b/src/speedtestutil.cpp index b7f5892..dbd9658 100644 --- a/src/speedtestutil.cpp +++ b/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://")) diff --git a/src/speedtestutil.h b/src/speedtestutil.h index 2688f64..b0f1b71 100644 --- a/src/speedtestutil.h +++ b/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 &nodes); void explodeSub(std::string sub, bool sslibev, bool ssrlibev, const std::string &custom_port, std::vector &nodes); int explodeConf(std::string filepath, const std::string &custom_port, bool sslibev, bool ssrlibev, std::vector &nodes); diff --git a/src/subexport.cpp b/src/subexport.cpp index 94504d6..3c744e9 100644 --- a/src/subexport.cpp +++ b/src/subexport.cpp @@ -658,10 +658,10 @@ void rulesetToClash(YAML::Node &base_rule, std::vector &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)) diff --git a/src/templates.cpp b/src/templates.cpp index 31481db..17962a0 100644 --- a/src/templates.cpp +++ b/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 &rules } continue; } - if(strLine.find("FINAL") == 0) + if(startsWith(strLine, "FINAL")) strLine.replace(0, 5, "MATCH"); strLine += "," + rule_group; if(count_least(strLine, ',', 3)) diff --git a/src/webget.cpp b/src/webget.cpp index ae63619..89368fa 100644 --- a/src/webget.cpp +++ b/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); diff --git a/src/webserver.cpp b/src/webserver.cpp deleted file mode 100644 index 9b19eba..0000000 --- a/src/webserver.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "misc.h" -#include "socket.h" -#include "webserver.h" - -typedef std::vector string_array; -int def_timeout = 5; - -struct responseRoute -{ - std::string method; - std::string path; - std::string content_type; - response_callback rc; -}; - -std::vector 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< 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::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"<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!"< 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; -} diff --git a/src/webserver_libevent.cpp b/src/webserver_libevent.cpp index 35ec058..6941b19 100644 --- a/src/webserver_libevent.cpp +++ b/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(&addr), sizeof(addr)); - if (ret < 0) - { - closesocket(nfd); - return -1; - } - ret = listen(nfd, backlog); - if (ret < 0) + if (::bind(nfd, reinterpret_cast(&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(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++)