diff --git a/deps/Makefile b/deps/Makefile index e82d006d8d..82f6dd97f1 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -91,24 +91,23 @@ libssl/openssl/libssl.a: libssl: libssl/openssl/libssl.a -MIN_VERSION := 4.9.0 -GCC_VERSION := $(shell gcc -dumpversion) -SORTED_VERSIONS := $(shell echo -e "$(GCC_VERSION)\n$(MIN_VERSION)" | sort -V) - -REQUIRE_PATCH = false -ifeq ($(MIN_VERSION),$(lastword $(SORTED_VERSIONS))) - REQUIRE_PATCH = true -endif - libhttpserver/libhttpserver/build/src/.libs/libhttpserver.a: libmicrohttpd/libmicrohttpd/src/microhttpd/.libs/libmicrohttpd.a re2/re2/obj/libre2.a cd libhttpserver && rm -rf libhttpserver-*/ || true - cd libhttpserver && tar -zxf libhttpserver-*.tar.gz -#ifeq ($(REQUIRE_PATCH), true) +ifeq ($(CPLUSPLUS),201703L) + cd libhttpserver && ln -fs libhttpserver-0.19.0 libhttpserver + cd libhttpserver && tar -zxf libhttpserver-0.19.0.tar.gz cd libhttpserver/libhttpserver && patch -p1 < ../noexcept.patch cd libhttpserver/libhttpserver && patch -p1 < ../re2_regex.patch -#endif cd libhttpserver/libhttpserver && patch -p1 < ../final_val_post_process.patch cd libhttpserver/libhttpserver && patch -p1 < ../empty_uri_log_crash.patch +else + cd libhttpserver && ln -fs libhttpserver-0.18.2 libhttpserver + cd libhttpserver && tar -zxf libhttpserver-0.18.2.tar.gz + cd libhttpserver/libhttpserver && patch -p1 < ../noexcept_v0.18.2.patch + cd libhttpserver/libhttpserver && patch -p1 < ../re2_regex_v0.18.2.patch + cd libhttpserver/libhttpserver && patch -p1 < ../final_val_post_process_v0.18.2.patch + cd libhttpserver/libhttpserver && patch -p1 < ../empty_uri_log_crash_v0.18.2.patch +endif ifeq ($(UNAME_S),FreeBSD) sed -i -e 's/\/bin\/bash/\/usr\/local\/bin\/bash/' libhttpserver/libhttpserver/bootstrap endif diff --git a/deps/libhttpserver/empty_uri_log_crash_v0.18.2.patch b/deps/libhttpserver/empty_uri_log_crash_v0.18.2.patch new file mode 100644 index 0000000000..9b788eadb2 --- /dev/null +++ b/deps/libhttpserver/empty_uri_log_crash_v0.18.2.patch @@ -0,0 +1,19 @@ +commit 2678fcf0bc7a645a4043f5c194dfc75da35ab072 +Author: Miro Stauder +Date: Tue Jan 24 15:05:11 2023 +0000 + + webserver.patch + +diff --git a/src/webserver.cpp b/src/webserver.cpp +index 38542f2..0ae69dc 100644 +--- a/src/webserver.cpp ++++ b/src/webserver.cpp +@@ -441,7 +441,7 @@ MHD_Result policy_callback (void *cls, const struct sockaddr* addr, socklen_t ad + void* uri_log(void* cls, const char* uri) + { + struct details::modded_request* mr = new details::modded_request(); +- mr->complete_uri = new string(uri); ++ mr->complete_uri = new string(uri == NULL ? "" : uri); + mr->second = false; + return ((void*)mr); + } diff --git a/deps/libhttpserver/final_val_post_process_v0.18.2.patch b/deps/libhttpserver/final_val_post_process_v0.18.2.patch new file mode 100644 index 0000000000..834c41b3a4 --- /dev/null +++ b/deps/libhttpserver/final_val_post_process_v0.18.2.patch @@ -0,0 +1,25 @@ +commit 3dab3a696e61c341029ad459608f2626e6e5547f +Author: Miro Stauder +Date: Mon Jan 9 12:06:29 2023 +0000 + + final_val_post_process.patch + +diff --git a/src/webserver.cpp b/src/webserver.cpp +index 38542f2..e6ef554 100644 +--- a/src/webserver.cpp ++++ b/src/webserver.cpp +@@ -674,6 +674,14 @@ MHD_Result webserver::finalize_answer( + { + if(hrm->is_allowed(method)) + { ++ // NOTE: Here 'MHD_destroy_post_processor' is required for performing a final 'post_process' ++ // of the 'URL Encode'. This ensures ensures the processing of final key without value left ++ // at the end of the buffer. See function internal doc at 'postprocessor.c'. ++ if (mr->pp != NULL) { ++ MHD_destroy_post_processor(mr->pp); ++ mr->pp = NULL; ++ } ++ + mr->dhrs = ((hrm)->*(mr->callback))(*mr->dhr); //copy in memory (move in case) + if (mr->dhrs->get_response_code() == -1) + { diff --git a/deps/libhttpserver/libhttpserver b/deps/libhttpserver/libhttpserver index 6980195184..04da4a00dc 120000 --- a/deps/libhttpserver/libhttpserver +++ b/deps/libhttpserver/libhttpserver @@ -1 +1 @@ -libhttpserver-0.19.0 \ No newline at end of file +libhttpserver-0.18.2 \ No newline at end of file diff --git a/deps/libhttpserver/libhttpserver-0.18.2.tar.gz b/deps/libhttpserver/libhttpserver-0.18.2.tar.gz new file mode 100644 index 0000000000..c5edd61f0d Binary files /dev/null and b/deps/libhttpserver/libhttpserver-0.18.2.tar.gz differ diff --git a/deps/libhttpserver/noexcept_v0.18.2.patch b/deps/libhttpserver/noexcept_v0.18.2.patch new file mode 100644 index 0000000000..91bffffbdd --- /dev/null +++ b/deps/libhttpserver/noexcept_v0.18.2.patch @@ -0,0 +1,127 @@ +commit 28afed88f70420ee256e627d065d21a00d9d7977 +Author: Miro Stauder +Date: Mon Jan 9 12:05:26 2023 +0000 + + noexcept.patch + +diff --git a/src/httpserver/basic_auth_fail_response.hpp b/src/httpserver/basic_auth_fail_response.hpp +index a28fa3d..24bb132 100644 +--- a/src/httpserver/basic_auth_fail_response.hpp ++++ b/src/httpserver/basic_auth_fail_response.hpp +@@ -52,7 +52,7 @@ class basic_auth_fail_response : public string_response + } + + basic_auth_fail_response(const basic_auth_fail_response& other) = default; +- basic_auth_fail_response(basic_auth_fail_response&& other) noexcept = default; ++ basic_auth_fail_response(basic_auth_fail_response&& other) = default; + basic_auth_fail_response& operator=(const basic_auth_fail_response& b) = default; + basic_auth_fail_response& operator=(basic_auth_fail_response&& b) = default; + +diff --git a/src/httpserver/create_webserver.hpp b/src/httpserver/create_webserver.hpp +index 39cb3ec..f43c8f5 100644 +--- a/src/httpserver/create_webserver.hpp ++++ b/src/httpserver/create_webserver.hpp +@@ -48,7 +48,7 @@ class create_webserver + public: + create_webserver() = default; + create_webserver(const create_webserver& b) = default; +- create_webserver(create_webserver&& b) noexcept = default; ++ create_webserver(create_webserver&& b) = default; + create_webserver& operator=(const create_webserver& b) = default; + create_webserver& operator=(create_webserver&& b) = default; + +diff --git a/src/httpserver/deferred_response.hpp b/src/httpserver/deferred_response.hpp +index 9e4601e..a8ba748 100644 +--- a/src/httpserver/deferred_response.hpp ++++ b/src/httpserver/deferred_response.hpp +@@ -61,7 +61,7 @@ class deferred_response : public string_response + } + + deferred_response(const deferred_response& other) = default; +- deferred_response(deferred_response&& other) noexcept = default; ++ deferred_response(deferred_response&& other) = default; + deferred_response& operator=(const deferred_response& b) = default; + deferred_response& operator=(deferred_response&& b) = default; + +diff --git a/src/httpserver/digest_auth_fail_response.hpp b/src/httpserver/digest_auth_fail_response.hpp +index 50abcee..18cf19c 100644 +--- a/src/httpserver/digest_auth_fail_response.hpp ++++ b/src/httpserver/digest_auth_fail_response.hpp +@@ -56,7 +56,7 @@ class digest_auth_fail_response : public string_response + } + + digest_auth_fail_response(const digest_auth_fail_response& other) = default; +- digest_auth_fail_response(digest_auth_fail_response&& other) noexcept = default; ++ digest_auth_fail_response(digest_auth_fail_response&& other) = default; + digest_auth_fail_response& operator=(const digest_auth_fail_response& b) = default; + digest_auth_fail_response& operator=(digest_auth_fail_response&& b) = default; + +diff --git a/src/httpserver/file_response.hpp b/src/httpserver/file_response.hpp +index 0c9386f..2e10f6c 100644 +--- a/src/httpserver/file_response.hpp ++++ b/src/httpserver/file_response.hpp +@@ -50,7 +50,7 @@ class file_response : public http_response + } + + file_response(const file_response& other) = default; +- file_response(file_response&& other) noexcept = default; ++ file_response(file_response&& other) = default; + + file_response& operator=(const file_response& b) = default; + file_response& operator=(file_response&& b) = default; +diff --git a/src/httpserver/http_request.hpp b/src/httpserver/http_request.hpp +index 6aacbfe..0b83fa2 100644 +--- a/src/httpserver/http_request.hpp ++++ b/src/httpserver/http_request.hpp +@@ -227,7 +227,7 @@ class http_request + * @param b http_request b to copy attributes from. + **/ + http_request(const http_request& b) = default; +- http_request(http_request&& b) noexcept = default; ++ http_request(http_request&& b) = default; + + http_request& operator=(const http_request& b) = default; + http_request& operator=(http_request&& b) = default; +diff --git a/src/httpserver/http_resource.hpp b/src/httpserver/http_resource.hpp +index 04f67cb..59829e8 100644 +--- a/src/httpserver/http_resource.hpp ++++ b/src/httpserver/http_resource.hpp +@@ -211,7 +211,7 @@ class http_resource + * Copy constructor + **/ + http_resource(const http_resource& b) = default; +- http_resource(http_resource&& b) noexcept = default; ++ http_resource(http_resource&& b) = default; + http_resource& operator=(const http_resource& b) = default; + http_resource& operator=(http_resource&& b) = default; + +diff --git a/src/httpserver/http_response.hpp b/src/httpserver/http_response.hpp +index 1f3f097..3564f37 100644 +--- a/src/httpserver/http_response.hpp ++++ b/src/httpserver/http_response.hpp +@@ -55,10 +55,10 @@ class http_response + * @param b The http_response object to copy attributes value from. + **/ + http_response(const http_response& b) = default; +- http_response(http_response&& b) noexcept = default; ++ http_response(http_response&& b) = default; + + http_response& operator=(const http_response& b) = default; +- http_response& operator=(http_response&& b) noexcept = default; ++ http_response& operator=(http_response&& b) = default; + + virtual ~http_response() = default; + +diff --git a/src/httpserver/string_response.hpp b/src/httpserver/string_response.hpp +index 43e7580..2043890 100644 +--- a/src/httpserver/string_response.hpp ++++ b/src/httpserver/string_response.hpp +@@ -51,7 +51,7 @@ class string_response : public http_response + } + + string_response(const string_response& other) = default; +- string_response(string_response&& other) noexcept = default; ++ string_response(string_response&& other) = default; + + string_response& operator=(const string_response& b) = default; + string_response& operator=(string_response&& b) = default; diff --git a/deps/libhttpserver/re2_regex_v0.18.2.patch b/deps/libhttpserver/re2_regex_v0.18.2.patch new file mode 100644 index 0000000000..83e833bedb --- /dev/null +++ b/deps/libhttpserver/re2_regex_v0.18.2.patch @@ -0,0 +1,157 @@ +commit ff6527c6b71fd1d33c39b8dca2a89170de5c2263 +Author: Miro Stauder +Date: Mon Jan 9 12:05:55 2023 +0000 + + re2_regex.patch + +diff --git a/examples/Makefile.am b/examples/Makefile.am +index 318a7a8..0da1879 100644 +--- a/examples/Makefile.am ++++ b/examples/Makefile.am +@@ -16,8 +16,12 @@ + # License along with this library; if not, write to the Free Software + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +-LDADD = $(top_builddir)/src/libhttpserver.la +-AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/httpserver/ ++DEPS_PATH=$(top_srcdir)/../../ ++RE2_PATH=$(DEPS_PATH)/re2/re2 ++RE2_IDIR=$(RE2_PATH) ++ ++LDADD = $(top_builddir)/src/libhttpserver.la -L$(RE2_PATH)/obj -lre2 ++AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/httpserver/ -I$(RE2_IDIR) + METASOURCES = AUTO + noinst_PROGRAMS = hello_world service minimal_hello_world custom_error allowing_disallowing_methods handlers hello_with_get_arg setting_headers custom_access_log basic_authentication digest_authentication minimal_https minimal_file_response minimal_deferred url_registration minimal_ip_ban benchmark_select benchmark_threads benchmark_nodelay deferred_with_accumulator + +diff --git a/src/Makefile.am b/src/Makefile.am +index 5e549bb..1fcc59e 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -16,7 +16,11 @@ + # License along with this library; if not, write to the Free Software + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +-AM_CPPFLAGS = -I../ -I$(srcdir)/httpserver/ ++DEPS_PATH=$(top_srcdir)/../../ ++RE2_PATH=$(DEPS_PATH)/re2/re2 ++RE2_IDIR=$(RE2_PATH) ++ ++AM_CPPFLAGS = -I../ -I$(srcdir)/httpserver/ -I$(RE2_IDIR) + METASOURCES = AUTO + lib_LTLIBRARIES = libhttpserver.la + libhttpserver_la_SOURCES = string_utilities.cpp webserver.cpp http_utils.cpp http_request.cpp http_response.cpp string_response.cpp basic_auth_fail_response.cpp digest_auth_fail_response.cpp deferred_response.cpp file_response.cpp http_resource.cpp details/http_endpoint.cpp +@@ -37,7 +41,7 @@ endif + + libhttpserver_la_CFLAGS = $(AM_CFLAGS) + libhttpserver_la_CXXFLAGS = $(AM_CXXFLAGS) +-libhttpserver_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined ++libhttpserver_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -L$(RE2_PATH)/obj -lre2 + + install-data-hook: + (mkdir -p $(DESTDIR)$(includedir) && cd $(DESTDIR)$(includedir) && $(LN_S) -f httpserver.hpp httpserverpp) +diff --git a/src/details/http_endpoint.cpp b/src/details/http_endpoint.cpp +index 584fb50..01292d5 100644 +--- a/src/details/http_endpoint.cpp ++++ b/src/details/http_endpoint.cpp +@@ -52,6 +52,7 @@ http_endpoint::http_endpoint + bool registration, + bool use_regex + ): ++ re_url_normalized(new re2::RE2("")), + family_url(family), + reg_compiled(false) + { +@@ -130,9 +131,19 @@ http_endpoint::http_endpoint + url_normalized += "$"; + try + { +- re_url_normalized = std::regex(url_normalized, std::regex::extended | std::regex::icase | std::regex::nosubs); ++ re2::RE2::Options opts {}; ++ opts.set_case_sensitive(true); ++ opts.set_never_capture(true); ++ ++ re_url_normalized.reset( ++ new re2::RE2(url_normalized, opts) ++ ); ++ ++ if (re_url_normalized->ok() != true) { ++ throw std::invalid_argument("Invalid regex supplied to re2"); ++ } + } +- catch (std::regex_error& e) ++ catch (std::invalid_argument& e) + { + throw std::invalid_argument("Not a valid regex in URL: " + url_normalized); + } +@@ -146,7 +157,7 @@ http_endpoint::http_endpoint(const http_endpoint& h): + url_pars(h.url_pars), + url_pieces(h.url_pieces), + chunk_positions(h.chunk_positions), +- re_url_normalized(h.re_url_normalized), ++ re_url_normalized(new re2::RE2(h.re_url_normalized->pattern())), + family_url(h.family_url), + reg_compiled(h.reg_compiled) + { +@@ -158,7 +169,7 @@ http_endpoint& http_endpoint::operator =(const http_endpoint& h) + url_normalized = h.url_normalized; + family_url = h.family_url; + reg_compiled = h.reg_compiled; +- re_url_normalized = h.re_url_normalized; ++ re_url_normalized.reset(new re2::RE2(h.re_url_normalized->pattern())); + url_pars = h.url_pars; + url_pieces = h.url_pieces; + chunk_positions = h.chunk_positions; +@@ -176,7 +187,7 @@ bool http_endpoint::match(const http_endpoint& url) const + + if(!family_url || url.url_pieces.size() < url_pieces.size()) + { +- return regex_match(url.url_complete, re_url_normalized); ++ return RE2::FullMatch(url.url_complete, *re_url_normalized); + } + + string nn = "/"; +@@ -186,7 +197,7 @@ bool http_endpoint::match(const http_endpoint& url) const + nn += (first ? "" : "/") + url.url_pieces[i]; + first = false; + } +- return regex_match(nn, re_url_normalized); ++ return RE2::FullMatch(nn, *re_url_normalized); + } + + }; +diff --git a/src/httpserver/details/http_endpoint.hpp b/src/httpserver/details/http_endpoint.hpp +index 37fd0d8..ae92782 100644 +--- a/src/httpserver/details/http_endpoint.hpp ++++ b/src/httpserver/details/http_endpoint.hpp +@@ -25,11 +25,12 @@ + #ifndef _HTTP_ENDPOINT_HPP_ + #define _HTTP_ENDPOINT_HPP_ + +-#include ++#include "re2/re2.h" + #include + #include + #include + #include ++#include + + namespace httpserver + { +@@ -136,7 +137,7 @@ class http_endpoint + http_endpoint(): + url_complete("/"), + url_normalized("/"), +- re_url_normalized(std::regex("")), // initialize empty ++ re_url_normalized(new re2::RE2("")), // initialize empty + family_url(false), + reg_compiled(false) + { +@@ -187,7 +188,7 @@ class http_endpoint + /** + * Regex used in comparisons + **/ +- std::regex re_url_normalized; ++ std::unique_ptr re_url_normalized; + + /** + * Boolean indicating wheter the endpoint represents a family diff --git a/lib/ProxySQL_RESTAPI_Server.cpp b/lib/ProxySQL_RESTAPI_Server.cpp index e5f3c967b2..e0aabfa9fa 100644 --- a/lib/ProxySQL_RESTAPI_Server.cpp +++ b/lib/ProxySQL_RESTAPI_Server.cpp @@ -271,17 +271,25 @@ class sync_resource : public http_resource { } public: +#if __cplusplus >= 201703L std::shared_ptr render(const http_request& req) { +#else + const std::shared_ptr render(const http_request& req) { +#endif proxy_info("Render generic request with method %s for uri %s\n", ((string) req.get_method()).c_str(), ((string) req.get_path()).c_str()); json j_err_resp {{ "error", "HTTP method " + (string) req.get_method() + " is not implemented" }}; - auto response = std::shared_ptr(new string_response(j_err_resp.dump())); - response->with_header("Content-Type", "application/json"); - response->with_header("Access-Control-Allow-Origin", "*"); + auto response = std::shared_ptr(new string_response(j_err_resp.dump())); + response->with_header("Content-Type", "application/json"); + response->with_header("Access-Control-Allow-Origin", "*"); - return response; - } + return response; + } +#if __cplusplus >= 201703L std::shared_ptr render_GET(const http_request& req) { +#else + const std::shared_ptr render_GET(const http_request& req) { +#endif const auto args = req.get_args(); // Explicit object creation, otherwise 'array' is initialized @@ -301,7 +309,11 @@ class sync_resource : public http_resource { return process_request(req, s_params); } +#if __cplusplus >= 201703L std::shared_ptr render_POST(const http_request& req) { +#else + const std::shared_ptr render_POST(const http_request& req) { +#endif std::string params = (std::string) req.get_content(); #ifdef DEBUG @@ -323,7 +335,11 @@ class gen_get_endpoint : public http_resource { _get_fn(get_fn) {} +#if __cplusplus >= 201703L std::shared_ptr render_GET(const http_request& req) override { +#else + const std::shared_ptr render_GET(const http_request& req) override { +#endif return this->_get_fn(req); } };