From 18d8e69b19e7d0e877e93aae5180e2cd571994e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Sun, 3 Sep 2023 21:20:25 +0000 Subject: [PATCH 01/17] Changing default for set_parser_algorithm --- lib/MySQL_Thread.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 5d6e470be..fec4d366b 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -1141,8 +1141,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.query_processor_iterations=0; variables.query_processor_regex=1; variables.set_query_lock_on_hostgroup=1; - // FIXME: this must become 2 in 2.6.0 - variables.set_parser_algorithm=1; // before 2.6.0 this was 1 , must become 2 + variables.set_parser_algorithm=2; // before 2.6.0 this was 1 variables.reset_connection_algorithm=2; variables.auto_increment_delay_multiplex=5; variables.auto_increment_delay_multiplex_timeout_ms=10000; From 7f75053926f9794f484b18d9ba6d330f57a7af28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 6 Sep 2023 13:41:35 +0000 Subject: [PATCH 02/17] Minor improvement on generateRE_parse1v2 --- lib/set_parser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 807daef21..751b68b80 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -178,6 +178,10 @@ void SetParser::generateRE_parse1v2() { var_patterns.push_back(vp); vp = "\\w+"; // single word var_patterns.push_back(vp); + vp = "\\w+"; // single word + var_patterns.push_back(vp); + vp = "\\w+(?:-\\w+)+"; // multiple words separated by dash, WITHOUT any spaces between words . Used for transaction isolation + var_patterns.push_back(vp); for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { string s = *it + vp + *it; var_patterns.push_back(s); // add with quote From 454ab610f6fbf133bfd906b4268106f3d6e3268e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 8 Sep 2023 07:40:51 +0000 Subject: [PATCH 03/17] Minor improvement on generateRE_parse1v2 --- lib/set_parser.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 751b68b80..bfd4cad02 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -176,11 +176,11 @@ void SetParser::generateRE_parse1v2() { string vp = "NULL"; // NULL var_patterns.push_back(vp); - vp = "\\w+"; // single word - var_patterns.push_back(vp); - vp = "\\w+"; // single word - var_patterns.push_back(vp); - vp = "\\w+(?:-\\w+)+"; // multiple words separated by dash, WITHOUT any spaces between words . Used for transaction isolation + //vp = "\\w+"; // single word + //var_patterns.push_back(vp); + //vp = "(?:\\w|\\d)+"; // single word with letters and digits , for example utf8mb4 and latin1 + //var_patterns.push_back(vp); + vp = "(?:\\w|\\d)+(?:-|\\w|\\d+)*"; // multiple words (letters and digits) separated by dash, WITHOUT any spaces between words . Used ialso for transaction isolation var_patterns.push_back(vp); for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { string s = *it + vp + *it; From 06d45796546d64e239891cfe65987c2abe21928b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 11 Sep 2023 16:49:43 +0000 Subject: [PATCH 04/17] More fixed on Set Parser 2 --- include/set_parser.h | 1 + lib/set_parser.cpp | 29 +++++++++++++++---- .../tests/test_filtered_set_statements-t.cpp | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/include/set_parser.h b/include/set_parser.h index 36391d15a..542186834 100644 --- a/include/set_parser.h +++ b/include/set_parser.h @@ -7,6 +7,7 @@ #include "re2/re2.h" #include "re2/regexp.h" +//#define PARSERDEBUG class SetParser { private: diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index bfd4cad02..fe61f91c0 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -178,14 +178,30 @@ void SetParser::generateRE_parse1v2() { var_patterns.push_back(vp); //vp = "\\w+"; // single word //var_patterns.push_back(vp); - //vp = "(?:\\w|\\d)+"; // single word with letters and digits , for example utf8mb4 and latin1 + { + string vp0 = "(?:\\w|\\d)+"; // single word with letters and digits , for example utf8mb4 and latin1 //var_patterns.push_back(vp); - vp = "(?:\\w|\\d)+(?:-|\\w|\\d+)*"; // multiple words (letters and digits) separated by dash, WITHOUT any spaces between words . Used ialso for transaction isolation - var_patterns.push_back(vp); - for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { - string s = *it + vp + *it; - var_patterns.push_back(s); // add with quote +/* + string vp1 = "(?:" + vp0 + "(?:," + vp0 + ")*)"; // multiple words (letters and digits) separated by commas WITHOUT any spaces between words . Used also for sql_mode , example: ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO + //var_patterns.push_back(vp1); // do NOT add without quote + for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { + string s = *it + vp1 + *it; + var_patterns.push_back(s); // add with quote + } +*/ + string vp2 = "(?:" + vp0 + "(?:-" + vp0 + ")*)"; // multiple words (letters and digits) separated by dash, WITHOUT any spaces between words . Used also for transaction isolation + var_patterns.push_back(vp2); + for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { + string s = *it + vp2 + *it; + var_patterns.push_back(s); // add with quote + } } + //vp = "(?:\\w|\\d)+(?:-|\\w|\\d+)*"; // multiple words (letters and digits) separated by dash, WITHOUT any spaces between words . Used ialso for transaction isolation + //var_patterns.push_back(vp); +// for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { +// string s = *it + vp + *it; +// var_patterns.push_back(s); // add with quote +// } vp = "\\w+(?:,\\w+)+"; // multiple words separated by commas, WITHOUT any spaces between words // NOTE: we do not use multiple words without quotes @@ -365,6 +381,7 @@ VALGRIND_ENABLE_ERROR_REPORTING; } } else if (value4 != "") { // VARIABLE + remove_quotes(value4); if (strcasecmp("transaction_isolation", value4.c_str()) == 0) { value4 = "tx_isolation"; } else if (strcasecmp("transaction_read_only", value4.c_str()) == 0) { diff --git a/test/tap/tests/test_filtered_set_statements-t.cpp b/test/tap/tests/test_filtered_set_statements-t.cpp index fee2dee09..726050ac6 100644 --- a/test/tap/tests/test_filtered_set_statements-t.cpp +++ b/test/tap/tests/test_filtered_set_statements-t.cpp @@ -28,7 +28,7 @@ * TODO: Fill with all the statements that should be properly handled by ProxySQL. */ std::vector> filtered_set_queries { - { "sql_mode", "ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO" }, + { "sql_mode", "'ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO'" }, { "wait_timeout", "28801" }, { "character_set_results", "latin1" }, { "character_set_connection", "latin1" }, From 5ccd4154f6a714030023c38a1d1a7afe79bc3897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 11 Sep 2023 17:29:35 +0000 Subject: [PATCH 05/17] Remove trailing spaces and semicolon from SET statements #4341 --- lib/set_parser.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index fe61f91c0..729dfa6c2 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -79,6 +79,8 @@ std::map> SetParser::parse1() { re2::RE2 re0("^\\s*SET\\s+", *opt2); re2::RE2::Replace(&query, re0, ""); + re2::RE2 re1("(\\s|;)+$", *opt2); // remove trailing spaces and semicolon + re2::RE2::Replace(&query, re1, ""); std::map> result; @@ -359,6 +361,9 @@ std::map> SetParser::parse1v2() { re2::RE2 re0("^\\s*SET\\s+", *parse1v2_opt2); re2::RE2::Replace(&query, re0, ""); + re2::RE2 re1("(\\s|;)+$", *parse1v2_opt2); // remove trailing spaces and semicolon + re2::RE2::Replace(&query, re1, ""); + VALGRIND_ENABLE_ERROR_REPORTING; std::string var; std::string value1, value2, value3, value4, value5; From 707ec90f7b0fa0d8eaa0611555854da4dbfb03f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 12 Sep 2023 21:27:40 +0000 Subject: [PATCH 06/17] Revert "Remove trailing spaces and semicolon from SET statements #4341" This reverts commit 5ccd4154f6a714030023c38a1d1a7afe79bc3897. --- lib/set_parser.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 729dfa6c2..fe61f91c0 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -79,8 +79,6 @@ std::map> SetParser::parse1() { re2::RE2 re0("^\\s*SET\\s+", *opt2); re2::RE2::Replace(&query, re0, ""); - re2::RE2 re1("(\\s|;)+$", *opt2); // remove trailing spaces and semicolon - re2::RE2::Replace(&query, re1, ""); std::map> result; @@ -361,9 +359,6 @@ std::map> SetParser::parse1v2() { re2::RE2 re0("^\\s*SET\\s+", *parse1v2_opt2); re2::RE2::Replace(&query, re0, ""); - re2::RE2 re1("(\\s|;)+$", *parse1v2_opt2); // remove trailing spaces and semicolon - re2::RE2::Replace(&query, re1, ""); - VALGRIND_ENABLE_ERROR_REPORTING; std::string var; std::string value1, value2, value3, value4, value5; From fc7cdfa6999dbea17ab98842799a4207bedfbd28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 13 Sep 2023 18:54:22 +0000 Subject: [PATCH 07/17] Adding more debugging in reg_test_3427 TAP --- .../reg_test_3427-stmt_first_comment1-t.cpp | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/test/tap/tests/reg_test_3427-stmt_first_comment1-t.cpp b/test/tap/tests/reg_test_3427-stmt_first_comment1-t.cpp index 4b03f23fd..2e2e50537 100644 --- a/test/tap/tests/reg_test_3427-stmt_first_comment1-t.cpp +++ b/test/tap/tests/reg_test_3427-stmt_first_comment1-t.cpp @@ -123,6 +123,7 @@ int main(int argc, char** argv) { }; std::string update_mysql_queries {}; string_format(t_update_mysql_servers, update_mysql_queries, WRITER_HOSTGROUP_ID); + diag("Line:%d , Running query: %s", __LINE__ , update_mysql_queries.c_str()); MYSQL_QUERY(proxysql_admin, update_mysql_queries.c_str()); MYSQL_QUERY(proxysql_admin, "LOAD MYSQL SERVERS TO RUNTIME"); @@ -133,10 +134,13 @@ int main(int argc, char** argv) { std::string max_stmt_query {}; string_format(t_max_stmt_query, max_stmt_query, MAX_STMT_NUM_QUERIES); MYSQL_QUERY(proxysql_admin, max_stmt_query.c_str()); + diag("Line:%d , Running query: %s", __LINE__ , max_stmt_query.c_str()); MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); uint32_t query_id = 0; + int rc = 0; + for (uint32_t i = 0; i < RESET_CONNECTION_QUERIES; i++) { if (i <= MAX_STMT_NUM_QUERIES) { query_id = i; @@ -159,20 +163,23 @@ int main(int argc, char** argv) { string_format(query_t, query, query_id); MYSQL_STMT* stmt = mysql_stmt_init(proxysql_mysql); + ok(stmt != NULL , "mysql_stmt_init() succeeded"); if (!stmt) { diag("mysql_stmt_init(), out of memory"); res = EXIT_FAILURE; goto exit; } - ok(stmt != NULL , "mysql_stmt_init() succeeded"); - if (mysql_stmt_prepare(stmt, query.c_str(), strlen(query.c_str()))) { + diag("Line:%d , Preparing query: %s", __LINE__ , query.c_str()); + rc = mysql_stmt_prepare(stmt, query.c_str(), strlen(query.c_str())); + ok(rc == 0, "mysql_stmt_prepare() succeeded"); + if (rc) { diag("mysql_stmt_prepare at line %d failed: %s", __LINE__ , mysql_error(proxysql_mysql)); mysql_close(proxysql_mysql); res = EXIT_FAILURE; goto exit; } else { - ok(1,"mysql_stmt_prepare() succeeded"); + // } if (param) { @@ -194,7 +201,9 @@ int main(int argc, char** argv) { } } - if (mysql_stmt_execute(stmt)) { + rc = mysql_stmt_execute(stmt); + ok(rc == 0, "mysql_stmt_execute() succeeded"); + if (rc) { diag( "mysql_stmt_execute at line %d failed: %s", __LINE__ , mysql_stmt_error(stmt) @@ -202,7 +211,7 @@ int main(int argc, char** argv) { res = EXIT_FAILURE; goto exit; } else { - ok(1,"mysql_stmt_execute() succeeded"); + // } MYSQL_BIND bind[3]; @@ -233,7 +242,9 @@ int main(int argc, char** argv) { bind[2].length = &length[2]; bind[2].error = &error[2]; - if (mysql_stmt_bind_result(stmt, bind)) { + rc = mysql_stmt_bind_result(stmt, bind); + ok(rc == 0, "mysql_stmt_bind_result() succeeded"); + if (rc) { diag( "mysql_stmt_bind_result at line %d failed: %s", __LINE__, mysql_stmt_error(stmt) @@ -241,10 +252,12 @@ int main(int argc, char** argv) { res = EXIT_FAILURE; goto exit; } else { - ok(1,"mysql_stmt_bind_result() succeeded"); + // } - if (mysql_stmt_fetch(stmt) == 1) { + rc = mysql_stmt_fetch(stmt); + ok(rc == 0,"mysql_stmt_fetch() succeeded"); + if (rc == 1) { diag( "mysql_stmt_fetch at line %d failed: %s", __LINE__, mysql_stmt_error(stmt) @@ -252,7 +265,7 @@ int main(int argc, char** argv) { res = EXIT_FAILURE; goto exit; } else { - ok(1,"mysql_stmt_fetch() succeeded"); + // } bool data_match_expected = From 2ddc8186b775eaf8dab374bfcac7cd5a32f9fe3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 13 Sep 2023 18:54:47 +0000 Subject: [PATCH 08/17] Revert "Revert "Remove trailing spaces and semicolon from SET statements #4341"" This reverts commit 707ec90f7b0fa0d8eaa0611555854da4dbfb03f6. --- lib/set_parser.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index fe61f91c0..729dfa6c2 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -79,6 +79,8 @@ std::map> SetParser::parse1() { re2::RE2 re0("^\\s*SET\\s+", *opt2); re2::RE2::Replace(&query, re0, ""); + re2::RE2 re1("(\\s|;)+$", *opt2); // remove trailing spaces and semicolon + re2::RE2::Replace(&query, re1, ""); std::map> result; @@ -359,6 +361,9 @@ std::map> SetParser::parse1v2() { re2::RE2 re0("^\\s*SET\\s+", *parse1v2_opt2); re2::RE2::Replace(&query, re0, ""); + re2::RE2 re1("(\\s|;)+$", *parse1v2_opt2); // remove trailing spaces and semicolon + re2::RE2::Replace(&query, re1, ""); + VALGRIND_ENABLE_ERROR_REPORTING; std::string var; std::string value1, value2, value3, value4, value5; From 09eb50a83e3f5f9fe1a44782c7685046a344042b Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Tue, 21 Nov 2023 13:55:07 +0500 Subject: [PATCH 09/17] Remove any trailing spaces and semicolons from the SET statement --- lib/MySQL_Session.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index d2ac2998a..99afae7fb 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -6032,6 +6032,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C string nq=string((char *)CurrentQuery.QueryPointer,CurrentQuery.QueryLength); RE2::GlobalReplace(&nq,(char *)"^/\\*!\\d\\d\\d\\d\\d SET(.*)\\*/",(char *)"SET\\1"); RE2::GlobalReplace(&nq,(char *)"(?U)/\\*.*\\*/",(char *)""); + // remove trailing space and semicolon if present. See issue#4380 + nq.erase(nq.find_last_not_of(" ;") + 1); /* // we do not threat SET SQL_LOG_BIN as a special case if (match_regexes && match_regexes[0]->match(dig)) { From d34f472b1a5d241b9cae2df64220ea1a847dbe97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 24 Nov 2023 10:38:21 +0000 Subject: [PATCH 10/17] Disable TAP reg_test_3273_ssl_con-t --- test/tap/tests/reg_test_3273_ssl_con-t.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/tap/tests/reg_test_3273_ssl_con-t.cpp b/test/tap/tests/reg_test_3273_ssl_con-t.cpp index 6cc59cd3d..32d187e15 100644 --- a/test/tap/tests/reg_test_3273_ssl_con-t.cpp +++ b/test/tap/tests/reg_test_3273_ssl_con-t.cpp @@ -84,6 +84,11 @@ int main(int argc, char** argv) { return -1; } + // temporary disable the whole test + plan(1); + ok(1, "Dummy ok"); + return exit_status(); + plan(2 + tc_rules.size()); diag("Checking ProxySQL idle CPU usage"); From 786be5f89b67433f807950c857cf69d4d1f111d9 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Mon, 27 Nov 2023 12:00:02 +0500 Subject: [PATCH 11/17] Updated TAP test * Added functionality for generating strings composed of randomly selected characters from ';' and ' ', with lengths ranging from 1 to 8. These generated strings are intended to be appended to executed queries. --- test/tap/tests/set_testing-240-t.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/tap/tests/set_testing-240-t.cpp b/test/tap/tests/set_testing-240-t.cpp index 0576bc4b8..2cd9cff09 100644 --- a/test/tap/tests/set_testing-240-t.cpp +++ b/test/tap/tests/set_testing-240-t.cpp @@ -82,6 +82,29 @@ class var_counter { } }; +// Generate string containing randomly chosen characters between +// ';' and ' ', with length between 1 and 8 +std::string generate_random_noise() { + // Seed the random number generator with the current time + std::srand(static_cast(std::time(nullptr))); + + static const char characters[] = { ';', ' ' }; + static const int numCharacters = sizeof(characters) / sizeof(char); + + // max lengh of string is 8 + const int length = std::rand() % 8 + 1; + + std::string randomString; + randomString.reserve(length); + + for (int i = 0; i < length; ++i) { + char randomChar = characters[std::rand() % numCharacters]; + randomString.push_back(randomChar); + } + + return randomString; +} + //std::unordered_map unknown_var_counters; std::unordered_map vars_counters; @@ -160,6 +183,7 @@ void * my_conn_thread(void *arg) { diag("Thread_id: %lu, random number: %d . Query/ies: %s", mysql->thread_id, r2, testCases[r2].command.c_str()); std::vector commands = split(testCases[r2].command.c_str(), ';'); for (auto c : commands) { + c += generate_random_noise(); if (mysql_query(mysql, c.c_str())) { if (silent==0) { fprintf(stderr,"ERROR while running -- \"%s\" : (%d) %s\n", c.c_str(), mysql_errno(mysql), mysql_error(mysql)); From 5a0dc26353f800015e7321e5687e802b80ebc661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 30 Nov 2023 08:46:58 +0100 Subject: [PATCH 12/17] Log loading errors for 'WebInterface' and 'LDAPAuth' plugins --- src/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 2c8220356..9c26be71d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -959,6 +959,8 @@ static void LoadPlugins() { if (GloWebInterface) { //GloAdmin->init_WebInterfacePlugin(); //GloAdmin->load_ldap_variables_to_runtime(); + } else { + proxy_error("Failed to load 'Web_Interface' plugin\n"); } } } @@ -985,6 +987,11 @@ static void LoadPlugins() { exit(EXIT_FAILURE); } else { GloMyLdapAuth = create_MySQL_LDAP_Authentication(); + + if (!GloMyLdapAuth) { + proxy_error("Failed to load 'MySQL_LDAP_Authentication' plugin\n"); + } + // we are removing this from here, and copying in // ProxySQL_Main_init_phase2___not_started // the keep record of these two lines to make sure we don't From bb0f2da42c557a1182896a644c1e58f3382fdd5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 30 Nov 2023 08:48:09 +0100 Subject: [PATCH 13/17] Fix Valgrind reported 'realloc' of zero length --- lib/mysql_data_stream.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 5eea659e2..dd2f2e2d3 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -736,7 +736,12 @@ int MySQL_Data_Stream::write_to_net() { memmove(ssl_write_buf, ssl_write_buf+n, ssl_write_len-n); } ssl_write_len -= n; - ssl_write_buf = (char*)realloc(ssl_write_buf, ssl_write_len); + if (ssl_write_len) { + ssl_write_buf = (char*)realloc(ssl_write_buf, ssl_write_len); + } else { + free(ssl_write_buf); + ssl_write_buf = NULL; + } //proxy_info("new ssl_write_len: %u\n", ssl_write_len); //if (ssl_write_len) { // return n; // stop here @@ -887,7 +892,12 @@ int MySQL_Data_Stream::write_to_net_poll() { memmove(ssl_write_buf, ssl_write_buf+n, ssl_write_len-n); } ssl_write_len -= n; - ssl_write_buf = (char*)realloc(ssl_write_buf, ssl_write_len); + if (ssl_write_len) { + ssl_write_buf = (char*)realloc(ssl_write_buf, ssl_write_len); + } else { + free(ssl_write_buf); + ssl_write_buf = NULL; + } //proxy_info("new ssl_write_len: %u\n", ssl_write_len); if (ssl_write_len) { return n; // stop here From 0e5fe23f3633e7eee77e4f51bb78198cc07a4809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 30 Nov 2023 09:05:07 +0100 Subject: [PATCH 14/17] Remove global 'static strings' from 'libhttpserver' Invalid double-free were taking place during plugin de-initialization due to ODR violations motivated by these objects. Simplest solution is making them not require 'allocation/deallocation'. --- deps/Makefile | 1 + .../replace_static_global_strings.patch | 390 ++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 deps/libhttpserver/replace_static_global_strings.patch diff --git a/deps/Makefile b/deps/Makefile index 945c31a0a..fdf78dd6d 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -116,6 +116,7 @@ libhttpserver/libhttpserver/build/src/.libs/libhttpserver.a: libmicrohttpd/libmi #endif cd libhttpserver/libhttpserver && patch -p1 < ../final_val_post_process.patch cd libhttpserver/libhttpserver && patch -p1 < ../empty_uri_log_crash.patch + cd libhttpserver/libhttpserver && patch -p0 < ../replace_static_global_strings.patch ifeq ($(UNAME_S),FreeBSD) sed -i -e 's/\/bin\/bash/\/usr\/local\/bin\/bash/' libhttpserver/libhttpserver/bootstrap endif diff --git a/deps/libhttpserver/replace_static_global_strings.patch b/deps/libhttpserver/replace_static_global_strings.patch new file mode 100644 index 000000000..f87ff2eaa --- /dev/null +++ b/deps/libhttpserver/replace_static_global_strings.patch @@ -0,0 +1,390 @@ +diff --git src/http_utils.cpp src/http_utils.cpp +index caefabc..fed5d9e 100644 +--- src/http_utils.cpp ++++ src/http_utils.cpp +@@ -137,98 +137,98 @@ const int http_utils::http_not_extended = MHD_HTTP_NOT_EXTENDED; + + const int http_utils::shoutcast_response = MHD_ICY_FLAG; + +-const std::string http_utils::http_header_accept = MHD_HTTP_HEADER_ACCEPT; +-const std::string http_utils::http_header_accept_charset = ++const char* http_utils::http_header_accept = MHD_HTTP_HEADER_ACCEPT; ++const char* http_utils::http_header_accept_charset = + MHD_HTTP_HEADER_ACCEPT_CHARSET; +-const std::string http_utils::http_header_accept_encoding = ++const char* http_utils::http_header_accept_encoding = + MHD_HTTP_HEADER_ACCEPT_ENCODING; +-const std::string http_utils::http_header_accept_language = ++const char* http_utils::http_header_accept_language = + MHD_HTTP_HEADER_ACCEPT_LANGUAGE; +-const std::string http_utils::http_header_accept_ranges = ++const char* http_utils::http_header_accept_ranges = + MHD_HTTP_HEADER_ACCEPT_RANGES; +-const std::string http_utils::http_header_age = MHD_HTTP_HEADER_AGE; +-const std::string http_utils::http_header_allow = MHD_HTTP_HEADER_ALLOW; +-const std::string http_utils::http_header_authorization = ++const char* http_utils::http_header_age = MHD_HTTP_HEADER_AGE; ++const char* http_utils::http_header_allow = MHD_HTTP_HEADER_ALLOW; ++const char* http_utils::http_header_authorization = + MHD_HTTP_HEADER_AUTHORIZATION; +-const std::string http_utils::http_header_cache_control = ++const char* http_utils::http_header_cache_control = + MHD_HTTP_HEADER_CACHE_CONTROL; +-const std::string http_utils::http_header_connection = ++const char* http_utils::http_header_connection = + MHD_HTTP_HEADER_CONNECTION; +-const std::string http_utils::http_header_content_encoding = ++const char* http_utils::http_header_content_encoding = + MHD_HTTP_HEADER_CONTENT_ENCODING; +-const std::string http_utils::http_header_content_language = ++const char* http_utils::http_header_content_language = + MHD_HTTP_HEADER_CONTENT_LANGUAGE; +-const std::string http_utils::http_header_content_length = ++const char* http_utils::http_header_content_length = + MHD_HTTP_HEADER_CONTENT_LENGTH; +-const std::string http_utils::http_header_content_location = ++const char* http_utils::http_header_content_location = + MHD_HTTP_HEADER_CONTENT_LOCATION; +-const std::string http_utils::http_header_content_md5 = ++const char* http_utils::http_header_content_md5 = + MHD_HTTP_HEADER_CONTENT_MD5; +-const std::string http_utils::http_header_content_range = ++const char* http_utils::http_header_content_range = + MHD_HTTP_HEADER_CONTENT_RANGE; +-const std::string http_utils::http_header_content_type = ++const char* http_utils::http_header_content_type = + MHD_HTTP_HEADER_CONTENT_TYPE; +-const std::string http_utils::http_header_date = MHD_HTTP_HEADER_DATE; +-const std::string http_utils::http_header_etag = MHD_HTTP_HEADER_ETAG; +-const std::string http_utils::http_header_expect = MHD_HTTP_HEADER_EXPECT; +-const std::string http_utils::http_header_expires = MHD_HTTP_HEADER_EXPIRES; +-const std::string http_utils::http_header_from = MHD_HTTP_HEADER_FROM; +-const std::string http_utils::http_header_host = MHD_HTTP_HEADER_HOST; +-const std::string http_utils::http_header_if_match = MHD_HTTP_HEADER_IF_MATCH; +-const std::string http_utils::http_header_if_modified_since = ++const char* http_utils::http_header_date = MHD_HTTP_HEADER_DATE; ++const char* http_utils::http_header_etag = MHD_HTTP_HEADER_ETAG; ++const char* http_utils::http_header_expect = MHD_HTTP_HEADER_EXPECT; ++const char* http_utils::http_header_expires = MHD_HTTP_HEADER_EXPIRES; ++const char* http_utils::http_header_from = MHD_HTTP_HEADER_FROM; ++const char* http_utils::http_header_host = MHD_HTTP_HEADER_HOST; ++const char* http_utils::http_header_if_match = MHD_HTTP_HEADER_IF_MATCH; ++const char* http_utils::http_header_if_modified_since = + MHD_HTTP_HEADER_IF_MODIFIED_SINCE; +-const std::string http_utils::http_header_if_none_match = ++const char* http_utils::http_header_if_none_match = + MHD_HTTP_HEADER_IF_NONE_MATCH; +-const std::string http_utils::http_header_if_range = MHD_HTTP_HEADER_IF_RANGE; +-const std::string http_utils::http_header_if_unmodified_since = ++const char* http_utils::http_header_if_range = MHD_HTTP_HEADER_IF_RANGE; ++const char* http_utils::http_header_if_unmodified_since = + MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE; +-const std::string http_utils::http_header_last_modified = ++const char* http_utils::http_header_last_modified = + MHD_HTTP_HEADER_LAST_MODIFIED; +-const std::string http_utils::http_header_location = MHD_HTTP_HEADER_LOCATION; +-const std::string http_utils::http_header_max_forwards = ++const char* http_utils::http_header_location = MHD_HTTP_HEADER_LOCATION; ++const char* http_utils::http_header_max_forwards = + MHD_HTTP_HEADER_MAX_FORWARDS; +-const std::string http_utils::http_header_pragma = MHD_HTTP_HEADER_PRAGMA; +-const std::string http_utils::http_header_proxy_authenticate = ++const char* http_utils::http_header_pragma = MHD_HTTP_HEADER_PRAGMA; ++const char* http_utils::http_header_proxy_authenticate = + MHD_HTTP_HEADER_PROXY_AUTHENTICATE; +-const std::string http_utils::http_header_proxy_authentication = ++const char* http_utils::http_header_proxy_authentication = + MHD_HTTP_HEADER_PROXY_AUTHORIZATION; +-const std::string http_utils::http_header_range = MHD_HTTP_HEADER_RANGE; +-const std::string http_utils::http_header_referer = MHD_HTTP_HEADER_REFERER; +-const std::string http_utils::http_header_retry_after = ++const char* http_utils::http_header_range = MHD_HTTP_HEADER_RANGE; ++const char* http_utils::http_header_referer = MHD_HTTP_HEADER_REFERER; ++const char* http_utils::http_header_retry_after = + MHD_HTTP_HEADER_RETRY_AFTER; +-const std::string http_utils::http_header_server = MHD_HTTP_HEADER_SERVER; +-const std::string http_utils::http_header_te = MHD_HTTP_HEADER_TE; +-const std::string http_utils::http_header_trailer = MHD_HTTP_HEADER_TRAILER; +-const std::string http_utils::http_header_transfer_encoding = ++const char* http_utils::http_header_server = MHD_HTTP_HEADER_SERVER; ++const char* http_utils::http_header_te = MHD_HTTP_HEADER_TE; ++const char* http_utils::http_header_trailer = MHD_HTTP_HEADER_TRAILER; ++const char* http_utils::http_header_transfer_encoding = + MHD_HTTP_HEADER_TRANSFER_ENCODING; +-const std::string http_utils::http_header_upgrade = MHD_HTTP_HEADER_UPGRADE; +-const std::string http_utils::http_header_user_agent = ++const char* http_utils::http_header_upgrade = MHD_HTTP_HEADER_UPGRADE; ++const char* http_utils::http_header_user_agent = + MHD_HTTP_HEADER_USER_AGENT; +-const std::string http_utils::http_header_vary = MHD_HTTP_HEADER_VARY; +-const std::string http_utils::http_header_via = MHD_HTTP_HEADER_VIA; +-const std::string http_utils::http_header_warning = MHD_HTTP_HEADER_WARNING; +-const std::string http_utils::http_header_www_authenticate = ++const char* http_utils::http_header_vary = MHD_HTTP_HEADER_VARY; ++const char* http_utils::http_header_via = MHD_HTTP_HEADER_VIA; ++const char* http_utils::http_header_warning = MHD_HTTP_HEADER_WARNING; ++const char* http_utils::http_header_www_authenticate = + MHD_HTTP_HEADER_WWW_AUTHENTICATE; + +-const std::string http_utils::http_version_1_0 = MHD_HTTP_VERSION_1_0; +-const std::string http_utils::http_version_1_1 = MHD_HTTP_VERSION_1_1; ++const char* http_utils::http_version_1_0 = MHD_HTTP_VERSION_1_0; ++const char* http_utils::http_version_1_1 = MHD_HTTP_VERSION_1_1; + +-const std::string http_utils::http_method_connect = MHD_HTTP_METHOD_CONNECT; +-const std::string http_utils::http_method_delete = MHD_HTTP_METHOD_DELETE; +-const std::string http_utils::http_method_get = MHD_HTTP_METHOD_GET; +-const std::string http_utils::http_method_head = MHD_HTTP_METHOD_HEAD; +-const std::string http_utils::http_method_options = MHD_HTTP_METHOD_OPTIONS; +-const std::string http_utils::http_method_post = MHD_HTTP_METHOD_POST; +-const std::string http_utils::http_method_put = MHD_HTTP_METHOD_PUT; +-const std::string http_utils::http_method_trace = MHD_HTTP_METHOD_TRACE; +-const std::string http_utils::http_method_patch = MHD_HTTP_METHOD_PATCH; ++const char* http_utils::http_method_connect = MHD_HTTP_METHOD_CONNECT; ++const char* http_utils::http_method_delete = MHD_HTTP_METHOD_DELETE; ++const char* http_utils::http_method_get = MHD_HTTP_METHOD_GET; ++const char* http_utils::http_method_head = MHD_HTTP_METHOD_HEAD; ++const char* http_utils::http_method_options = MHD_HTTP_METHOD_OPTIONS; ++const char* http_utils::http_method_post = MHD_HTTP_METHOD_POST; ++const char* http_utils::http_method_put = MHD_HTTP_METHOD_PUT; ++const char* http_utils::http_method_trace = MHD_HTTP_METHOD_TRACE; ++const char* http_utils::http_method_patch = MHD_HTTP_METHOD_PATCH; + +-const std::string http_utils::http_post_encoding_form_urlencoded = ++const char* http_utils::http_post_encoding_form_urlencoded = + MHD_HTTP_POST_ENCODING_FORM_URLENCODED; +-const std::string http_utils::http_post_encoding_multipart_formdata = ++const char* http_utils::http_post_encoding_multipart_formdata = + MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA; + +-const std::string http_utils::text_plain = "text/plain"; ++const char* http_utils::text_plain = "text/plain"; + + std::vector http_utils::tokenize_url( + const std::string& str, +diff --git src/httpserver/http_utils.hpp src/httpserver/http_utils.hpp +index e2aa033..5059e06 100644 +--- src/httpserver/http_utils.hpp ++++ src/httpserver/http_utils.hpp +@@ -189,71 +189,71 @@ class http_utils + static const int shoutcast_response; + + /* See also: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */ +- static const std::string http_header_accept; +- static const std::string http_header_accept_charset; +- static const std::string http_header_accept_encoding; +- static const std::string http_header_accept_language; +- static const std::string http_header_accept_ranges; +- static const std::string http_header_age; +- static const std::string http_header_allow; +- static const std::string http_header_authorization; +- static const std::string http_header_cache_control; +- static const std::string http_header_connection; +- static const std::string http_header_content_encoding; +- static const std::string http_header_content_language; +- static const std::string http_header_content_length; +- static const std::string http_header_content_location; +- static const std::string http_header_content_md5; +- static const std::string http_header_content_range; +- static const std::string http_header_content_type; +- static const std::string http_header_date; +- static const std::string http_header_etag; +- static const std::string http_header_expect; +- static const std::string http_header_expires; +- static const std::string http_header_from; +- static const std::string http_header_host; +- static const std::string http_header_if_match; +- static const std::string http_header_if_modified_since; +- static const std::string http_header_if_none_match; +- static const std::string http_header_if_range; +- static const std::string http_header_if_unmodified_since; +- static const std::string http_header_last_modified; +- static const std::string http_header_location; +- static const std::string http_header_max_forwards; +- static const std::string http_header_pragma; +- static const std::string http_header_proxy_authenticate; +- static const std::string http_header_proxy_authentication; +- static const std::string http_header_range; +- static const std::string http_header_referer; +- static const std::string http_header_retry_after; +- static const std::string http_header_server; +- static const std::string http_header_te; +- static const std::string http_header_trailer; +- static const std::string http_header_transfer_encoding; +- static const std::string http_header_upgrade; +- static const std::string http_header_user_agent; +- static const std::string http_header_vary; +- static const std::string http_header_via; +- static const std::string http_header_warning; +- static const std::string http_header_www_authenticate; +- +- static const std::string http_version_1_0; +- static const std::string http_version_1_1; +- +- static const std::string http_method_connect; +- static const std::string http_method_delete; +- static const std::string http_method_head; +- static const std::string http_method_get; +- static const std::string http_method_options; +- static const std::string http_method_post; +- static const std::string http_method_put; +- static const std::string http_method_trace; +- static const std::string http_method_patch; +- +- static const std::string http_post_encoding_form_urlencoded; +- static const std::string http_post_encoding_multipart_formdata; +- +- static const std::string text_plain; ++ static const char* http_header_accept; ++ static const char* http_header_accept_charset; ++ static const char* http_header_accept_encoding; ++ static const char* http_header_accept_language; ++ static const char* http_header_accept_ranges; ++ static const char* http_header_age; ++ static const char* http_header_allow; ++ static const char* http_header_authorization; ++ static const char* http_header_cache_control; ++ static const char* http_header_connection; ++ static const char* http_header_content_encoding; ++ static const char* http_header_content_language; ++ static const char* http_header_content_length; ++ static const char* http_header_content_location; ++ static const char* http_header_content_md5; ++ static const char* http_header_content_range; ++ static const char* http_header_content_type; ++ static const char* http_header_date; ++ static const char* http_header_etag; ++ static const char* http_header_expect; ++ static const char* http_header_expires; ++ static const char* http_header_from; ++ static const char* http_header_host; ++ static const char* http_header_if_match; ++ static const char* http_header_if_modified_since; ++ static const char* http_header_if_none_match; ++ static const char* http_header_if_range; ++ static const char* http_header_if_unmodified_since; ++ static const char* http_header_last_modified; ++ static const char* http_header_location; ++ static const char* http_header_max_forwards; ++ static const char* http_header_pragma; ++ static const char* http_header_proxy_authenticate; ++ static const char* http_header_proxy_authentication; ++ static const char* http_header_range; ++ static const char* http_header_referer; ++ static const char* http_header_retry_after; ++ static const char* http_header_server; ++ static const char* http_header_te; ++ static const char* http_header_trailer; ++ static const char* http_header_transfer_encoding; ++ static const char* http_header_upgrade; ++ static const char* http_header_user_agent; ++ static const char* http_header_vary; ++ static const char* http_header_via; ++ static const char* http_header_warning; ++ static const char* http_header_www_authenticate; ++ ++ static const char* http_version_1_0; ++ static const char* http_version_1_1; ++ ++ static const char* http_method_connect; ++ static const char* http_method_delete; ++ static const char* http_method_head; ++ static const char* http_method_get; ++ static const char* http_method_options; ++ static const char* http_method_post; ++ static const char* http_method_put; ++ static const char* http_method_trace; ++ static const char* http_method_patch; ++ ++ static const char* http_post_encoding_form_urlencoded; ++ static const char* http_post_encoding_multipart_formdata; ++ ++ static const char* text_plain; + + static std::vector tokenize_url(const std::string&, + const char separator = '/' +diff --git src/webserver.cpp src/webserver.cpp +index 96e53b5..a7be951 100644 +--- src/webserver.cpp ++++ src/webserver.cpp +@@ -537,22 +537,22 @@ MHD_Result webserver::requests_answer_first_step( + const char *encoding = MHD_lookup_connection_value ( + connection, + MHD_HEADER_KIND, +- http_utils::http_header_content_type.c_str() ++ http_utils::http_header_content_type + ); + + if ( post_process_enabled && + ( + 0x0 != encoding && + ((0 == strncasecmp ( +- http_utils::http_post_encoding_form_urlencoded.c_str(), ++ http_utils::http_post_encoding_form_urlencoded, + encoding, +- http_utils::http_post_encoding_form_urlencoded.size() ++ strlen(http_utils::http_post_encoding_form_urlencoded) + ) + ) + || (0 == strncasecmp ( +- http_utils::http_post_encoding_multipart_formdata.c_str(), ++ http_utils::http_post_encoding_multipart_formdata, + encoding, +- http_utils::http_post_encoding_multipart_formdata.size() ++ strlen(http_utils::http_post_encoding_multipart_formdata) + ))) + ) + ) +@@ -803,43 +803,43 @@ MHD_Result webserver::answer_to_connection(void* cls, MHD_Connection* connection + *(mr->complete_uri) + " METHOD: " + method + ); + +- if( 0 == strcasecmp(method, http_utils::http_method_get.c_str())) ++ if( 0 == strcasecmp(method, http_utils::http_method_get)) + { + mr->callback = &http_resource::render_GET; + } +- else if (0 == strcmp(method, http_utils::http_method_post.c_str())) ++ else if (0 == strcmp(method, http_utils::http_method_post)) + { + mr->callback = &http_resource::render_POST; + mr->has_body = true; + } +- else if (0 == strcasecmp(method, http_utils::http_method_put.c_str())) ++ else if (0 == strcasecmp(method, http_utils::http_method_put)) + { + mr->callback = &http_resource::render_PUT; + mr->has_body = true; + } +- else if (0 == strcasecmp(method,http_utils::http_method_delete.c_str())) ++ else if (0 == strcasecmp(method,http_utils::http_method_delete)) + { + mr->callback = &http_resource::render_DELETE; + mr->has_body = true; + } +- else if (0 == strcasecmp(method, http_utils::http_method_patch.c_str())) ++ else if (0 == strcasecmp(method, http_utils::http_method_patch)) + { + mr->callback = &http_resource::render_PATCH; + mr->has_body = true; + } +- else if (0 == strcasecmp(method, http_utils::http_method_head.c_str())) ++ else if (0 == strcasecmp(method, http_utils::http_method_head)) + { + mr->callback = &http_resource::render_HEAD; + } +- else if (0 ==strcasecmp(method,http_utils::http_method_connect.c_str())) ++ else if (0 ==strcasecmp(method,http_utils::http_method_connect)) + { + mr->callback = &http_resource::render_CONNECT; + } +- else if (0 == strcasecmp(method, http_utils::http_method_trace.c_str())) ++ else if (0 == strcasecmp(method, http_utils::http_method_trace)) + { + mr->callback = &http_resource::render_TRACE; + } +- else if (0 ==strcasecmp(method,http_utils::http_method_options.c_str())) ++ else if (0 ==strcasecmp(method,http_utils::http_method_options)) + { + mr->callback = &http_resource::render_OPTIONS; + } From a31f58fc3b8162a0b76bd64b2d56d67a94c5658a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 30 Nov 2023 09:20:02 +0100 Subject: [PATCH 15/17] Add escaped URL tokenization to 'libhttpserver' Previously 'libhttpserver' only exposed method 'get_path_pieces()', this method makes use of the internal 'standardized_url' for tokenizing the URL. This method has the limitation of performing the escaping prior to the tokenization of elements, incurring into improper tokenization. The new introduced function 'get_url_pieces()' corrects this behavior. --- deps/Makefile | 1 + deps/libhttpserver/expose_raw_url.patch | 109 ++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 deps/libhttpserver/expose_raw_url.patch diff --git a/deps/Makefile b/deps/Makefile index fdf78dd6d..1d9d5ab8f 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -116,6 +116,7 @@ libhttpserver/libhttpserver/build/src/.libs/libhttpserver.a: libmicrohttpd/libmi #endif cd libhttpserver/libhttpserver && patch -p1 < ../final_val_post_process.patch cd libhttpserver/libhttpserver && patch -p1 < ../empty_uri_log_crash.patch + cd libhttpserver/libhttpserver && patch -p0 < ../expose_raw_url.patch cd libhttpserver/libhttpserver && patch -p0 < ../replace_static_global_strings.patch ifeq ($(UNAME_S),FreeBSD) sed -i -e 's/\/bin\/bash/\/usr\/local\/bin\/bash/' libhttpserver/libhttpserver/bootstrap diff --git a/deps/libhttpserver/expose_raw_url.patch b/deps/libhttpserver/expose_raw_url.patch new file mode 100644 index 000000000..6be22c1e6 --- /dev/null +++ b/deps/libhttpserver/expose_raw_url.patch @@ -0,0 +1,109 @@ +diff --git src/httpserver/details/modded_request.hpp src/httpserver/details/modded_request.hpp +index 1ebe5b1..32d4154 100644 +--- src/httpserver/details/modded_request.hpp ++++ src/httpserver/details/modded_request.hpp +@@ -38,6 +38,7 @@ struct modded_request + struct MHD_PostProcessor *pp = 0x0; + std::string* complete_uri = 0x0; + std::string* standardized_url = 0x0; ++ std::string* url = 0x0; + webserver* ws = 0x0; + + const std::shared_ptr (httpserver::http_resource::*callback)(const httpserver::http_request&); +@@ -65,6 +66,9 @@ struct modded_request + delete dhr; //TODO: verify. It could be an error + delete complete_uri; + delete standardized_url; ++ if (url) { ++ delete url; ++ } + } + + }; +diff --git src/httpserver/http_request.hpp src/httpserver/http_request.hpp +index 0b83fa2..419585d 100644 +--- src/httpserver/http_request.hpp ++++ src/httpserver/http_request.hpp +@@ -77,6 +77,15 @@ class http_request + return path; + } + ++ /** ++ * Method used to get the path requested ++ * @return string representing the path requested. ++ **/ ++ const std::string& get_url() const ++ { ++ return url; ++ } ++ + /** + * Method used to get all pieces of the path requested; considering an url splitted by '/'. + * @return a vector of strings containing all pieces +@@ -86,6 +95,22 @@ class http_request + return http::http_utils::tokenize_url(path); + } + ++ /** ++ * Method used to get all pieces of the path requested; considering an url splitted by '/'. ++ * @return a vector of strings containing all pieces ++ **/ ++ const std::vector get_url_pieces() const ++ { ++ const std::vector url_pieces { http::http_utils::tokenize_url(url) }; ++ std::vector dec_pieces { url_pieces }; ++ ++ for (std::string& p : dec_pieces) { ++ http::base_unescaper(p, nullptr); ++ } ++ ++ return dec_pieces; ++ } ++ + /** + * Method used to obtain a specified piece of the path; considering an url splitted by '/'. + * @param index the index of the piece selected +@@ -233,6 +258,7 @@ class http_request + http_request& operator=(http_request&& b) = default; + + std::string path; ++ std::string url; + std::string method; + std::map args; + std::string content = ""; +@@ -317,6 +343,15 @@ class http_request + this->path = path; + } + ++ /** ++ * Sets the raw (unescaped) URL path. Used for 'get_pieces()' ++ * @param url The path searched by the request ++ **/ ++ void set_url(const std::string& url) ++ { ++ this->url = url; ++ } ++ + /** + * Method used to set the request METHOD + * @param method The method to set for the request +diff --git src/webserver.cpp src/webserver.cpp +index e7dd335..96e53b5 100644 +--- src/webserver.cpp ++++ src/webserver.cpp +@@ -750,6 +750,7 @@ MHD_Result webserver::complete_request( + mr->ws = this; + + mr->dhr->set_path(mr->standardized_url->c_str()); ++ mr->dhr->set_url(mr->url->c_str()); + mr->dhr->set_method(method); + mr->dhr->set_version(version); + +@@ -793,6 +794,7 @@ MHD_Result webserver::answer_to_connection(void* cls, MHD_Connection* connection + + base_unescaper(t_url, static_cast(cls)->unescaper); + mr->standardized_url = new string(http_utils::standardize_url(t_url)); ++ mr->url = new string(url); + + mr->has_body = false; + From c2d58b3ab453e39d01fc5ffadb44b33f238c8323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 30 Nov 2023 09:26:38 +0100 Subject: [PATCH 16/17] Disable 'examples' compilation for 'libhttpserver' --- deps/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/Makefile b/deps/Makefile index 1d9d5ab8f..94b2e7627 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -122,7 +122,7 @@ ifeq ($(UNAME_S),FreeBSD) sed -i -e 's/\/bin\/bash/\/usr\/local\/bin\/bash/' libhttpserver/libhttpserver/bootstrap endif cd libhttpserver/libhttpserver && ./bootstrap && mkdir build - cd libhttpserver/libhttpserver/build && LDFLAGS=-L$(shell pwd)/libmicrohttpd/libmicrohttpd/src/microhttpd/.libs/ CPPFLAGS=-I$(shell pwd)/libmicrohttpd/libmicrohttpd/src/include ../configure --disable-doxygen-doc --disable-doxygen-dot --disable-doxygen-man --disable-doxygen-html --enable-fastopen=false + cd libhttpserver/libhttpserver/build && LDFLAGS=-L$(shell pwd)/libmicrohttpd/libmicrohttpd/src/microhttpd/.libs/ CPPFLAGS=-I$(shell pwd)/libmicrohttpd/libmicrohttpd/src/include ../configure --disable-doxygen-doc --disable-doxygen-dot --disable-doxygen-man --disable-doxygen-html --enable-fastopen=false --disable-examples cd libhttpserver/libhttpserver/build && CC=${CC} CXX=${CXX} ${MAKE} libhttpserver: libhttpserver/libhttpserver/build/src/.libs/libhttpserver.a From 2aa6d506ee3e273e52bf8cbe8d903446cd2a5b76 Mon Sep 17 00:00:00 2001 From: Miro Stauder Date: Tue, 5 Dec 2023 11:43:21 +0100 Subject: [PATCH 17/17] Create CI-3p-sqlalchemy.yml --- .github/workflows/CI-3p-sqlalchemy.yml | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/CI-3p-sqlalchemy.yml diff --git a/.github/workflows/CI-3p-sqlalchemy.yml b/.github/workflows/CI-3p-sqlalchemy.yml new file mode 100644 index 000000000..9be2100a3 --- /dev/null +++ b/.github/workflows/CI-3p-sqlalchemy.yml @@ -0,0 +1,30 @@ +name: CI-3p-sqlalchemy + +on: + push: + branches: [ "v2.x" ] + paths-ignore: + - '.github/**' + - '**.md' + pull_request: + branches: [ "v2.x" ] + paths-ignore: + - '.github/**' + - '**.md' +# schedule: +# - cron: '15 13 * * 3' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + +jobs: + cache: + uses: sysown/proxysql/.github/workflows/ci-builds.yml@GH-Actions + secrets: inherit + + run: + needs: [ "cache" ] + uses: sysown/proxysql/.github/workflows/ci-3p-sqlalchemy.yml@GH-Actions + secrets: inherit +