From 18bc6251ab01e35be2a491b99b81d85737aaa59f Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 16:31:45 -0800 Subject: [PATCH 01/12] Add TLS-PSK authentication support via callback mechanism This adds support for TLS Pre-Shared Key (PSK) authentication, allowing secure connections without certificates using a shared secret key. Changes: - Add psk_cred_handler() builder method to create_webserver - Add psk_cred_handler_callback typedef for PSK credential lookup - Implement psk_cred_handler_func() static callback using GnuTLS - Add MHD_OPTION_GNUTLS_PSK_CRED_HANDLER option when PSK is configured - Add AM_CONDITIONAL for HAVE_GNUTLS in configure.ac - Remove deprecated AC_HEADER_STDC macro - Add minimal_https_psk example demonstrating PSK usage - Add conditional GnuTLS linking in test/Makefile.am - Update README.md with PSK documentation and example The callback receives a username and returns the hex-encoded PSK, or an empty string for unknown users. --- README.md | 54 +++++++++++++++++++++++++ configure.ac | 3 +- examples/Makefile.am | 6 +++ examples/minimal_https_psk.cpp | 63 +++++++++++++++++++++++++++++ src/httpserver/create_webserver.hpp | 7 ++++ src/httpserver/webserver.hpp | 11 +++++ src/webserver.cpp | 43 ++++++++++++++++++++ test/Makefile.am | 4 ++ 8 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 examples/minimal_https_psk.cpp diff --git a/README.md b/README.md index b0a4c0e8..83f0b5b6 100644 --- a/README.md +++ b/README.md @@ -313,6 +313,7 @@ You can also check this example on [github](https://github.com/etr/libhttpserver * _.https_mem_cert(**const std::string&** filename):_ String representing the path to a file containing the certificate to be used by the HTTPS daemon. This must be used in conjunction with `https_mem_key`. * _.https_mem_trust(**const std::string&** filename):_ String representing the path to a file containing the CA certificate to be used by the HTTPS daemon to authenticate and trust clients certificates. The presence of this option activates the request of certificate to the client. The request to the client is marked optional, and it is the responsibility of the server to check the presence of the certificate if needed. Note that most browsers will only present a client certificate only if they have one matching the specified CA, not sending any certificate otherwise. * _.https_priorities(**const std::string&** priority_string):_ SSL/TLS protocol version and ciphers. Must be followed by a string specifying the SSL/TLS protocol versions and ciphers that are acceptable for the application. The string is passed unchanged to gnutls_priority_init. If this option is not specified, `"NORMAL"` is used. +* _.psk_cred_handler(**psk_cred_handler_callback** handler):_ Sets a callback function for TLS-PSK (Pre-Shared Key) authentication. The callback receives a username and should return the corresponding hex-encoded PSK, or an empty string if the user is unknown. This option requires `use_ssl()`, `cred_type(http::http_utils::PSK)`, and an appropriate `https_priorities()` string that enables PSK cipher suites. PSK authentication allows TLS without certificates by using a shared secret key. #### Minimal example using HTTPS ```cpp @@ -346,6 +347,59 @@ To test the above example, you can run the following command from a terminal: You can also check this example on [github](https://github.com/etr/libhttpserver/blob/master/examples/minimal_https.cpp). +#### Minimal example using TLS-PSK +```cpp + #include + #include + #include + + using namespace httpserver; + + // Simple PSK database - in production, use secure storage + std::map psk_database = { + {"client1", "0123456789abcdef0123456789abcdef"}, + {"client2", "fedcba9876543210fedcba9876543210"} + }; + + // PSK credential handler callback + std::string psk_handler(const std::string& username) { + auto it = psk_database.find(username); + if (it != psk_database.end()) { + return it->second; + } + return ""; // Return empty string for unknown users + } + + class hello_world_resource : public http_resource { + public: + std::shared_ptr render(const http_request&) { + return std::shared_ptr( + new string_response("Hello, World (via TLS-PSK)!")); + } + }; + + int main(int argc, char** argv) { + webserver ws = create_webserver(8080) + .use_ssl() + .cred_type(http::http_utils::PSK) + .psk_cred_handler(psk_handler) + .https_priorities("NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2:+PSK:+DHE-PSK"); + + hello_world_resource hwr; + ws.register_resource("/hello", &hwr); + ws.start(true); + + return 0; + } +``` +To test the above example, you can run the following command from a terminal using gnutls-cli: + + gnutls-cli --pskusername=client1 --pskkey=0123456789abcdef0123456789abcdef -p 8080 localhost + +Then type `GET /hello HTTP/1.1` followed by `Host: localhost` and two newlines. + +You can also check this example on [github](https://github.com/etr/libhttpserver/blob/master/examples/minimal_https_psk.cpp). + ### IP Blacklisting/Whitelisting libhttpserver supports IP blacklisting and whitelisting as an internal feature. This section explains the startup options related with IP blacklisting/whitelisting. See the [specific section](#ip-blacklisting-and-whitelisting) to read more about the topic. * _.ban_system() and .no_ban_system:_ Can be used to enable/disable the ban system. `on` by default. diff --git a/configure.ac b/configure.ac index 66b8e757..1197c136 100644 --- a/configure.ac +++ b/configure.ac @@ -83,7 +83,6 @@ case "$host" in esac # Checks for header files. -AC_HEADER_STDC AC_CHECK_HEADER([stdint.h],[],[AC_MSG_ERROR("stdint.h not found")]) AC_CHECK_HEADER([inttypes.h],[],[AC_MSG_ERROR("inttypes.h not found")]) AC_CHECK_HEADER([errno.h],[],[AC_MSG_ERROR("errno.h not found")]) @@ -250,6 +249,8 @@ if test x"$have_gnutls" = x"yes"; then AM_CFLAGS="$AM_CXXFLAGS -DHAVE_GNUTLS" fi +AM_CONDITIONAL([HAVE_GNUTLS],[test x"$have_gnutls" = x"yes"]) + DX_HTML_FEATURE(ON) DX_CHM_FEATURE(OFF) DX_CHI_FEATURE(OFF) diff --git a/examples/Makefile.am b/examples/Makefile.am index 0fe116af..79b84ae2 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -42,3 +42,9 @@ benchmark_select_SOURCES = benchmark_select.cpp benchmark_threads_SOURCES = benchmark_threads.cpp benchmark_nodelay_SOURCES = benchmark_nodelay.cpp file_upload_SOURCES = file_upload.cpp + +if HAVE_GNUTLS +noinst_PROGRAMS += minimal_https_psk +minimal_https_psk_SOURCES = minimal_https_psk.cpp +minimal_https_psk_LDADD = $(LDADD) -lgnutls +endif diff --git a/examples/minimal_https_psk.cpp b/examples/minimal_https_psk.cpp new file mode 100644 index 00000000..9bb02ef6 --- /dev/null +++ b/examples/minimal_https_psk.cpp @@ -0,0 +1,63 @@ +/* + This file is part of libhttpserver + Copyright (C) 2011-2024 Sebastiano Merlino + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +*/ + +#include +#include +#include + +#include + +// Simple PSK database - in production, use secure storage +std::map psk_database = { + {"client1", "0123456789abcdef0123456789abcdef"}, + {"client2", "fedcba9876543210fedcba9876543210"} +}; + +// PSK credential handler callback +// Returns the hex-encoded PSK for the given username, or empty string if not found +std::string psk_handler(const std::string& username) { + auto it = psk_database.find(username); + if (it != psk_database.end()) { + return it->second; + } + return ""; // Return empty string for unknown users +} + +class hello_world_resource : public httpserver::http_resource { + public: + std::shared_ptr render(const httpserver::http_request&) { + return std::shared_ptr( + new httpserver::string_response("Hello, World (via TLS-PSK)!")); + } +}; + +int main() { + httpserver::webserver ws = httpserver::create_webserver(8080) + .use_ssl() + .cred_type(httpserver::http::http_utils::PSK) + .psk_cred_handler(psk_handler) + .https_priorities("NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2:+PSK:+DHE-PSK"); + + hello_world_resource hwr; + ws.register_resource("/hello", &hwr); + ws.start(true); + + return 0; +} diff --git a/src/httpserver/create_webserver.hpp b/src/httpserver/create_webserver.hpp index c6d61e4d..fca96d91 100644 --- a/src/httpserver/create_webserver.hpp +++ b/src/httpserver/create_webserver.hpp @@ -46,6 +46,7 @@ typedef std::function(const http_request&)> rende typedef std::function validator_ptr; typedef std::function log_access_ptr; typedef std::function log_error_ptr; +typedef std::function psk_cred_handler_callback; class create_webserver { public: @@ -223,6 +224,11 @@ class create_webserver { return *this; } + create_webserver& psk_cred_handler(psk_cred_handler_callback handler) { + _psk_cred_handler = handler; + return *this; + } + create_webserver& digest_auth_random(const std::string& digest_auth_random) { _digest_auth_random = digest_auth_random; return *this; @@ -384,6 +390,7 @@ class create_webserver { std::string _https_mem_trust = ""; std::string _https_priorities = ""; http::http_utils::cred_type_T _cred_type = http::http_utils::NONE; + psk_cred_handler_callback _psk_cred_handler = nullptr; std::string _digest_auth_random = ""; int _nonce_nc_size = 0; http::http_utils::policy_T _default_policy = http::http_utils::ACCEPT; diff --git a/src/httpserver/webserver.hpp b/src/httpserver/webserver.hpp index b2cbb1a6..05b43a32 100644 --- a/src/httpserver/webserver.hpp +++ b/src/httpserver/webserver.hpp @@ -45,6 +45,10 @@ #include #include +#ifdef HAVE_GNUTLS +#include +#endif // HAVE_GNUTLS + #include "httpserver/http_utils.hpp" #include "httpserver/create_webserver.hpp" #include "httpserver/details/http_endpoint.hpp" @@ -153,6 +157,7 @@ class webserver { const std::string https_mem_trust; const std::string https_priorities; const http::http_utils::cred_type_T cred_type; + const psk_cred_handler_callback psk_cred_handler; const std::string digest_auth_random; const int nonce_nc_size; bool running; @@ -210,6 +215,12 @@ class webserver { MHD_Result complete_request(MHD_Connection* connection, struct details::modded_request* mr, const char* version, const char* method); +#ifdef HAVE_GNUTLS + static int psk_cred_handler_func(gnutls_session_t session, + const char* username, + gnutls_datum_t* key); +#endif // HAVE_GNUTLS + friend MHD_Result policy_callback(void *cls, const struct sockaddr* addr, socklen_t addrlen); friend void error_log(void* cls, const char* fmt, va_list ap); friend void access_log(webserver* cls, std::string uri); diff --git a/src/webserver.cpp b/src/webserver.cpp index 6e0c7ead..c7fc9c9b 100644 --- a/src/webserver.cpp +++ b/src/webserver.cpp @@ -142,6 +142,7 @@ webserver::webserver(const create_webserver& params): https_mem_trust(params._https_mem_trust), https_priorities(params._https_priorities), cred_type(params._cred_type), + psk_cred_handler(params._psk_cred_handler), digest_auth_random(params._digest_auth_random), nonce_nc_size(params._nonce_nc_size), running(false), @@ -276,6 +277,11 @@ bool webserver::start(bool blocking) { if (cred_type != http_utils::NONE) { iov.push_back(gen(MHD_OPTION_HTTPS_CRED_TYPE, cred_type)); } + + if (psk_cred_handler != nullptr && use_ssl) { + iov.push_back(gen(MHD_OPTION_GNUTLS_PSK_CRED_HANDLER, + (intptr_t)&psk_cred_handler_func, this)); + } #endif // HAVE_GNUTLS iov.push_back(gen(MHD_OPTION_END, 0, nullptr)); @@ -396,6 +402,43 @@ void webserver::disallow_ip(const string& ip) { allowances.erase(ip_representation(ip)); } +#ifdef HAVE_GNUTLS +int webserver::psk_cred_handler_func(gnutls_session_t session, + const char* username, + gnutls_datum_t* key) { + webserver* ws = static_cast( + gnutls_session_get_ptr(session)); + + if (ws == nullptr || ws->psk_cred_handler == nullptr) { + return -1; + } + + std::string psk_hex = ws->psk_cred_handler(std::string(username)); + if (psk_hex.empty()) { + return -1; + } + + // Convert hex string to binary + size_t psk_len = psk_hex.size() / 2; + key->data = static_cast(gnutls_malloc(psk_len)); + if (key->data == nullptr) { + return -1; + } + + size_t output_size = psk_len; + int ret = gnutls_hex2bin(psk_hex.c_str(), psk_hex.size(), + key->data, &output_size); + if (ret < 0) { + gnutls_free(key->data); + key->data = nullptr; + return -1; + } + + key->size = static_cast(output_size); + return 0; +} +#endif // HAVE_GNUTLS + MHD_Result policy_callback(void *cls, const struct sockaddr* addr, socklen_t addrlen) { // Parameter needed to respect MHD interface, but not needed here. std::ignore = addrlen; diff --git a/test/Makefile.am b/test/Makefile.am index 68ddb554..58fd4c84 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -39,6 +39,10 @@ http_resource_SOURCES = unit/http_resource_test.cpp noinst_HEADERS = littletest.hpp AM_CXXFLAGS += -lcurl -Wall -fPIC +if HAVE_GNUTLS +AM_CXXFLAGS += -lgnutls +endif + if COND_GCOV AM_CFLAGS += -O0 --coverage --no-inline AM_CXXFLAGS += -O0 --coverage --no-inline From 90383a15724b924b73afee5ad170c66acc375029 Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 16:42:33 -0800 Subject: [PATCH 02/12] Update GitHub Actions to v4 (cache and checkout) --- .github/workflows/verify-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index 77530449..cf872d9b 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -264,7 +264,7 @@ jobs: coverage: nocoverage steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -312,7 +312,7 @@ jobs: - name: IWYU from cache (for testing) id: cache-IWYU - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: include-what-you-use key: ${{ matrix.os }}-${{ matrix.c-compiler }}-include-what-you-use-pre-built @@ -341,7 +341,7 @@ jobs: - name: CURL from cache (for testing) id: cache-CURL - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: curl-7.75.0 key: ${{ matrix.os }}-CURL-pre-built @@ -386,7 +386,7 @@ jobs: - name: Fetch libmicrohttpd from cache id: cache-libmicrohttpd - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: libmicrohttpd-0.9.64 key: ${{ matrix.os }}-${{ matrix.c-compiler }}-libmicrohttpd-pre-built From 47530ed515beb0097fb40dd4ecd8e116fcd11bae Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 16:53:40 -0800 Subject: [PATCH 03/12] Fix linker error: link all examples against gnutls when available The library now uses GnuTLS functions (gnutls_malloc, gnutls_free, gnutls_hex2bin) for PSK support, so all examples need to link against gnutls when HAVE_GNUTLS is defined, not just the PSK example. --- examples/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Makefile.am b/examples/Makefile.am index 79b84ae2..cf838c30 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -44,7 +44,7 @@ benchmark_nodelay_SOURCES = benchmark_nodelay.cpp file_upload_SOURCES = file_upload.cpp if HAVE_GNUTLS +LDADD += -lgnutls noinst_PROGRAMS += minimal_https_psk minimal_https_psk_SOURCES = minimal_https_psk.cpp -minimal_https_psk_LDADD = $(LDADD) -lgnutls endif From f5df6833465a62339c9f95c1ee7ef4f3eacbf242 Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 17:25:07 -0800 Subject: [PATCH 04/12] Update CI for Ubuntu 24.04 compatibility - Update sanitizer builds (asan, lsan, tsan, ubsan) from clang-13 to clang-18 - Move clang-11, clang-12, clang-13 tests to ubuntu-22.04 - Add new clang-14 through clang-17 tests on ubuntu-latest - Add gcc-11 through gcc-14 tests - Remove obsolete ubuntu-20.04 jobs (gcc-7, gcc-8, clang-6 through clang-10) - Update IWYU job to use clang-18 on ubuntu-latest - Fix cpplint errors: add missing includes and fix namespace indentation Co-Authored-By: Claude Opus 4.5 --- .github/workflows/verify-build.yml | 109 +++++++++++----------- examples/allowing_disallowing_methods.cpp | 2 + examples/basic_authentication.cpp | 3 + examples/custom_access_log.cpp | 2 + examples/custom_error.cpp | 2 + examples/deferred_with_accumulator.cpp | 3 + examples/digest_authentication.cpp | 2 + examples/file_upload.cpp | 3 + examples/handlers.cpp | 2 + examples/hello_with_get_arg.cpp | 3 + examples/hello_world.cpp | 2 + examples/minimal_deferred.cpp | 4 + examples/minimal_file_response.cpp | 2 + examples/minimal_hello_world.cpp | 2 + examples/minimal_https.cpp | 2 + examples/minimal_ip_ban.cpp | 2 + examples/service.cpp | 1 + examples/setting_headers.cpp | 2 + examples/url_registration.cpp | 3 + src/file_info.cpp | 1 + src/http_request.cpp | 3 + src/http_resource.cpp | 2 + src/http_response.cpp | 2 + src/http_utils.cpp | 6 +- src/httpserver/deferred_response.hpp | 4 +- src/webserver.cpp | 5 +- 26 files changed, 117 insertions(+), 57 deletions(-) diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index cf872d9b..e5a75e1e 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -58,8 +58,8 @@ jobs: os-type: ubuntu build-type: asan compiler-family: clang - c-compiler: clang-13 - cc-compiler: clang++-13 + c-compiler: clang-18 + cc-compiler: clang++-18 debug: debug coverage: nocoverage # This test gives false positives on newer versions of clang @@ -78,8 +78,8 @@ jobs: os-type: ubuntu build-type: lsan compiler-family: clang - c-compiler: clang-13 - cc-compiler: clang++-13 + c-compiler: clang-18 + cc-compiler: clang++-18 debug: debug coverage: nocoverage - test-group: extra @@ -87,8 +87,8 @@ jobs: os-type: ubuntu build-type: tsan compiler-family: clang - c-compiler: clang-13 - cc-compiler: clang++-13 + c-compiler: clang-18 + cc-compiler: clang++-18 debug: debug coverage: nocoverage - test-group: extra @@ -96,26 +96,26 @@ jobs: os-type: ubuntu build-type: ubsan compiler-family: clang - c-compiler: clang-13 - cc-compiler: clang++-13 + c-compiler: clang-18 + cc-compiler: clang++-18 debug: debug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-latest os-type: ubuntu build-type: none compiler-family: gcc - c-compiler: gcc-7 - cc-compiler: g++-7 + c-compiler: gcc-9 + cc-compiler: g++-9 debug: nodebug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-latest os-type: ubuntu build-type: none compiler-family: gcc - c-compiler: gcc-8 - cc-compiler: g++-8 + c-compiler: gcc-10 + cc-compiler: g++-10 debug: nodebug coverage: nocoverage - test-group: extra @@ -123,8 +123,8 @@ jobs: os-type: ubuntu build-type: none compiler-family: gcc - c-compiler: gcc-9 - cc-compiler: g++-9 + c-compiler: gcc-11 + cc-compiler: g++-11 debug: nodebug coverage: nocoverage - test-group: extra @@ -132,53 +132,62 @@ jobs: os-type: ubuntu build-type: none compiler-family: gcc - c-compiler: gcc-10 - cc-compiler: g++-10 + c-compiler: gcc-12 + cc-compiler: g++-12 debug: nodebug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-latest os-type: ubuntu build-type: none - compiler-family: clang - c-compiler: clang-6.0 - cc-compiler: clang++-6.0 + compiler-family: gcc + c-compiler: gcc-13 + cc-compiler: g++-13 debug: nodebug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-latest + os-type: ubuntu + build-type: none + compiler-family: gcc + c-compiler: gcc-14 + cc-compiler: g++-14 + debug: nodebug + coverage: nocoverage + - test-group: extra + os: ubuntu-22.04 os-type: ubuntu build-type: none compiler-family: clang - c-compiler: clang-7 - cc-compiler: clang++-7 + c-compiler: clang-11 + cc-compiler: clang++-11 debug: nodebug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-22.04 os-type: ubuntu build-type: none compiler-family: clang - c-compiler: clang-8 - cc-compiler: clang++-8 + c-compiler: clang-12 + cc-compiler: clang++-12 debug: nodebug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-22.04 os-type: ubuntu build-type: none compiler-family: clang - c-compiler: clang-9 - cc-compiler: clang++-9 + c-compiler: clang-13 + cc-compiler: clang++-13 debug: nodebug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-latest os-type: ubuntu build-type: none compiler-family: clang - c-compiler: clang-10 - cc-compiler: clang++-10 + c-compiler: clang-14 + cc-compiler: clang++-14 debug: nodebug coverage: nocoverage - test-group: extra @@ -186,8 +195,8 @@ jobs: os-type: ubuntu build-type: none compiler-family: clang - c-compiler: clang-11 - cc-compiler: clang++-11 + c-compiler: clang-15 + cc-compiler: clang++-15 debug: nodebug coverage: nocoverage - test-group: extra @@ -195,8 +204,8 @@ jobs: os-type: ubuntu build-type: none compiler-family: clang - c-compiler: clang-12 - cc-compiler: clang++-12 + c-compiler: clang-16 + cc-compiler: clang++-16 debug: nodebug coverage: nocoverage - test-group: extra @@ -204,8 +213,8 @@ jobs: os-type: ubuntu build-type: none compiler-family: clang - c-compiler: clang-13 - cc-compiler: clang++-13 + c-compiler: clang-17 + cc-compiler: clang++-17 debug: nodebug coverage: nocoverage - test-group: extra @@ -218,12 +227,12 @@ jobs: debug: nodebug coverage: nocoverage - test-group: extra - os: ubuntu-20.04 + os: ubuntu-latest os-type: ubuntu build-type: iwyu compiler-family: clang - c-compiler: clang-9 - cc-compiler: clang++-9 + c-compiler: clang-18 + cc-compiler: clang++-18 debug: nodebug coverage: nocoverage - test-group: performance @@ -303,11 +312,7 @@ jobs: - name: Install IWYU dependencies if needed run: | - # Use same deps used by iwyu in their setup for travis - sudo apt-get install llvm-9-dev llvm-9-tools libclang-9-dev ; - # Use same CMAKE used by iwyu in their setup for travis - wget -O cmake.sh https://cmake.org/files/v3.10/cmake-3.10.0-Linux-x86_64.sh ; - sudo sh cmake.sh --skip-license --exclude-subdir --prefix=/usr/local ; + sudo apt-get install llvm-18-dev libclang-18-dev clang-18 ; if: ${{ matrix.build-type == 'iwyu' && matrix.os-type == 'ubuntu' }} - name: IWYU from cache (for testing) @@ -321,11 +326,11 @@ jobs: # Installing iwyu manually because clang and iwyu paths won't match on Ubuntu otherwise. - name: Build IWYU if requested run: | - CLANG_ROOT_PATH=`llvm-config-9 --prefix` ; - CLANG_BIN_PATH=`llvm-config-9 --bindir` ; - curl "https://libhttpserver.s3.amazonaws.com/travis_stuff/include-what-you-use-clang-9.tgz" -o "include-what-you-use-clang-9.tgz" ; - tar -xzf "include-what-you-use-clang-9.tgz" ; + CLANG_ROOT_PATH=`llvm-config-18 --prefix` ; + CLANG_BIN_PATH=`llvm-config-18 --bindir` ; + git clone https://github.com/include-what-you-use/include-what-you-use.git ; cd include-what-you-use ; + git checkout clang_18 ; mkdir build_iwyu ; cd build_iwyu ; cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=$CLANG_ROOT_PATH -DCMAKE_C_COMPILER=$CLANG_BIN_PATH/clang -DCMAKE_CXX_COMPILER=$CLANG_BIN_PATH/clang++ ../ ; diff --git a/examples/allowing_disallowing_methods.cpp b/examples/allowing_disallowing_methods.cpp index 73389142..50efa4fd 100644 --- a/examples/allowing_disallowing_methods.cpp +++ b/examples/allowing_disallowing_methods.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/examples/basic_authentication.cpp b/examples/basic_authentication.cpp index 7fb82340..661bbb3c 100644 --- a/examples/basic_authentication.cpp +++ b/examples/basic_authentication.cpp @@ -18,6 +18,9 @@ USA */ +#include +#include + #include class user_pass_resource : public httpserver::http_resource { diff --git a/examples/custom_access_log.cpp b/examples/custom_access_log.cpp index f1a59d53..8f596c90 100644 --- a/examples/custom_access_log.cpp +++ b/examples/custom_access_log.cpp @@ -19,6 +19,8 @@ */ #include +#include +#include #include diff --git a/examples/custom_error.cpp b/examples/custom_error.cpp index a82d5972..c38fb169 100644 --- a/examples/custom_error.cpp +++ b/examples/custom_error.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include std::shared_ptr not_found_custom(const httpserver::http_request&) { diff --git a/examples/deferred_with_accumulator.cpp b/examples/deferred_with_accumulator.cpp index 3d3a4e69..a4367773 100644 --- a/examples/deferred_with_accumulator.cpp +++ b/examples/deferred_with_accumulator.cpp @@ -18,11 +18,14 @@ USA */ +#include #include #include // cpplint errors on chrono and thread because they are replaced (in Chromium) by other google libraries. // This is not an issue here. #include // NOLINT [build/c++11] +#include +#include #include // NOLINT [build/c++11] #include diff --git a/examples/digest_authentication.cpp b/examples/digest_authentication.cpp index 40767dc2..fb87cd4b 100644 --- a/examples/digest_authentication.cpp +++ b/examples/digest_authentication.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include #define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4" diff --git a/examples/file_upload.cpp b/examples/file_upload.cpp index 7e1afd5a..0916a4fc 100644 --- a/examples/file_upload.cpp +++ b/examples/file_upload.cpp @@ -19,6 +19,9 @@ */ #include +#include +#include + #include class file_upload_resource : public httpserver::http_resource { diff --git a/examples/handlers.cpp b/examples/handlers.cpp index 10778aaf..4fc70303 100644 --- a/examples/handlers.cpp +++ b/examples/handlers.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/examples/hello_with_get_arg.cpp b/examples/hello_with_get_arg.cpp index 268d00c3..41829a4d 100644 --- a/examples/hello_with_get_arg.cpp +++ b/examples/hello_with_get_arg.cpp @@ -18,6 +18,9 @@ USA */ +#include +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/examples/hello_world.cpp b/examples/hello_world.cpp index 391a600f..9c06f87a 100755 --- a/examples/hello_world.cpp +++ b/examples/hello_world.cpp @@ -19,6 +19,8 @@ */ #include +#include +#include #include diff --git a/examples/minimal_deferred.cpp b/examples/minimal_deferred.cpp index e7c77f50..d7a61d90 100644 --- a/examples/minimal_deferred.cpp +++ b/examples/minimal_deferred.cpp @@ -18,7 +18,11 @@ USA */ +#include #include +#include +#include + #include static int counter = 0; diff --git a/examples/minimal_file_response.cpp b/examples/minimal_file_response.cpp index a5dc8106..34776993 100644 --- a/examples/minimal_file_response.cpp +++ b/examples/minimal_file_response.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include class file_response_resource : public httpserver::http_resource { diff --git a/examples/minimal_hello_world.cpp b/examples/minimal_hello_world.cpp index f8fb27f0..fc166535 100644 --- a/examples/minimal_hello_world.cpp +++ b/examples/minimal_hello_world.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/examples/minimal_https.cpp b/examples/minimal_https.cpp index d5b8d443..79cd710c 100644 --- a/examples/minimal_https.cpp +++ b/examples/minimal_https.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/examples/minimal_ip_ban.cpp b/examples/minimal_ip_ban.cpp index 7be3cd17..4b95b5f0 100644 --- a/examples/minimal_ip_ban.cpp +++ b/examples/minimal_ip_ban.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/examples/service.cpp b/examples/service.cpp index 2bc9d4ad..309628bc 100644 --- a/examples/service.cpp +++ b/examples/service.cpp @@ -22,6 +22,7 @@ #include #include +#include #include diff --git a/examples/setting_headers.cpp b/examples/setting_headers.cpp index ea678b92..f92b76c1 100644 --- a/examples/setting_headers.cpp +++ b/examples/setting_headers.cpp @@ -18,6 +18,8 @@ USA */ +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/examples/url_registration.cpp b/examples/url_registration.cpp index be6d1ce3..e6eef458 100644 --- a/examples/url_registration.cpp +++ b/examples/url_registration.cpp @@ -18,6 +18,9 @@ USA */ +#include +#include + #include class hello_world_resource : public httpserver::http_resource { diff --git a/src/file_info.cpp b/src/file_info.cpp index 88a21583..d37e7aeb 100644 --- a/src/file_info.cpp +++ b/src/file_info.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "httpserver/file_info.hpp" namespace httpserver { diff --git a/src/http_request.cpp b/src/http_request.cpp index c49c3b8e..68ced762 100644 --- a/src/http_request.cpp +++ b/src/http_request.cpp @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include "httpserver/http_utils.hpp" #include "httpserver/string_utilities.hpp" diff --git a/src/http_resource.cpp b/src/http_resource.cpp index 88688484..430c4e65 100644 --- a/src/http_resource.cpp +++ b/src/http_resource.cpp @@ -21,7 +21,9 @@ #include "httpserver/http_resource.hpp" #include #include +#include #include +#include #include "httpserver/string_response.hpp" namespace httpserver { class http_response; } diff --git a/src/http_response.cpp b/src/http_response.cpp index cb357b24..f12589f7 100644 --- a/src/http_response.cpp +++ b/src/http_response.cpp @@ -21,6 +21,8 @@ #include "httpserver/http_response.hpp" #include #include +#include +#include #include #include "httpserver/http_utils.hpp" diff --git a/src/http_utils.cpp b/src/http_utils.cpp index 975f1a8f..138c44ef 100644 --- a/src/http_utils.cpp +++ b/src/http_utils.cpp @@ -44,7 +44,9 @@ #include #include #include +#include #include +#include #include "httpserver/string_utilities.hpp" @@ -206,9 +208,9 @@ const char* http_utils::text_plain = "text/plain"; const char* http_utils::upload_filename_template = "libhttpserver.XXXXXX"; #if defined(_WIN32) - const char http_utils::path_separator = '\\'; +const char http_utils::path_separator = '\\'; #else // _WIN32 - const char http_utils::path_separator = '/'; +const char http_utils::path_separator = '/'; #endif // _WIN32 std::vector http_utils::tokenize_url(const std::string& str, const char separator) { diff --git a/src/httpserver/deferred_response.hpp b/src/httpserver/deferred_response.hpp index 85f8791f..76a2127a 100644 --- a/src/httpserver/deferred_response.hpp +++ b/src/httpserver/deferred_response.hpp @@ -38,8 +38,8 @@ struct MHD_Response; namespace httpserver { namespace details { - MHD_Response* get_raw_response_helper(void* cls, ssize_t (*cb)(void*, uint64_t, char*, size_t)); -} +MHD_Response* get_raw_response_helper(void* cls, ssize_t (*cb)(void*, uint64_t, char*, size_t)); +} // namespace details template class deferred_response : public string_response { diff --git a/src/webserver.cpp b/src/webserver.cpp index c7fc9c9b..749efea1 100644 --- a/src/webserver.cpp +++ b/src/webserver.cpp @@ -40,10 +40,13 @@ #include #include #include -#include #include +#include +#include #include +#include #include +#include #include #include From e78b6cc48a47d0d33185e87db1a08fb6a393dbbd Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 17:31:34 -0800 Subject: [PATCH 05/12] Fix valgrind CI job for Ubuntu 24.04 - Remove valgrind-dbg package (debug symbols now included in main package) - Update valgrind job to use GCC 14 instead of GCC 10 Co-Authored-By: Claude Opus 4.5 --- .github/workflows/verify-build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index e5a75e1e..7db40c25 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -222,8 +222,8 @@ jobs: os-type: ubuntu build-type: valgrind compiler-family: gcc - c-compiler: gcc-10 - cc-compiler: g++-10 + c-compiler: gcc-14 + cc-compiler: g++-14 debug: nodebug coverage: nocoverage - test-group: extra @@ -303,7 +303,7 @@ jobs: if: ${{ matrix.compiler-family == 'gcc' && matrix.os-type == 'ubuntu' }} - name: Install valgrind if needed - run: sudo apt-get install valgrind valgrind-dbg + run: sudo apt-get install valgrind if: ${{ matrix.build-type == 'valgrind' && matrix.os-type == 'ubuntu' }} - name: Install cpplint if needed From 6e6bc9f8ada0c89dade5b2792862482f76b8d2c0 Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 18:58:37 -0800 Subject: [PATCH 06/12] Use GCC 13 for valgrind job to avoid -Woverloaded-virtual error GCC 14 with -Werror catches a latent warning in littletest.hpp test framework that older compilers don't flag. Use GCC 13 for now. Co-Authored-By: Claude Opus 4.5 --- .github/workflows/verify-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index 7db40c25..b18544bc 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -222,8 +222,8 @@ jobs: os-type: ubuntu build-type: valgrind compiler-family: gcc - c-compiler: gcc-14 - cc-compiler: g++-14 + c-compiler: gcc-13 + cc-compiler: g++-13 debug: nodebug coverage: nocoverage - test-group: extra From b1807942717765d241e264eae222d93e6c3c277f Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 20:41:27 -0800 Subject: [PATCH 07/12] Fix issues with valgrind running on g++-14 --- .github/workflows/verify-build.yml | 4 ++-- test/littletest.hpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index b18544bc..7db40c25 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -222,8 +222,8 @@ jobs: os-type: ubuntu build-type: valgrind compiler-family: gcc - c-compiler: gcc-13 - cc-compiler: g++-13 + c-compiler: gcc-14 + cc-compiler: g++-14 debug: nodebug coverage: nocoverage - test-group: extra diff --git a/test/littletest.hpp b/test/littletest.hpp index c26f6125..93b0e256 100644 --- a/test/littletest.hpp +++ b/test/littletest.hpp @@ -70,6 +70,7 @@ #define LT_BEGIN_TEST(__lt_suite_name__, __lt_test_name__) \ struct __lt_test_name__ ## _class: public __lt_suite_name__, littletest::test<__lt_test_name__ ## _class> \ { \ + using littletest::test_base::operator(); \ __lt_test_name__ ## _class() \ { \ __lt_name__ = #__lt_test_name__; \ From d8ec8ed2b24408eca0bda4f0ed249153d6750f77 Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 22:00:26 -0800 Subject: [PATCH 08/12] FIx issue with overloads in tests --- .github/workflows/verify-build.yml | 18 +++++++++--------- test/Makefile.am | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index 7db40c25..e4842605 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -357,7 +357,7 @@ jobs: curl https://libhttpserver.s3.amazonaws.com/travis_stuff/curl-7.75.0.tar.gz -o curl-7.75.0.tar.gz ; tar -xzf curl-7.75.0.tar.gz ; cd curl-7.75.0 ; - if [ "$matrix.os-type" = "ubuntu" ]; then ./configure ; else ./configure --with-darwinssl ; fi + ./configure --with-darwinssl ; make ; if: ${{ matrix.os == 'macos-latest' && steps.cache-CURL.outputs.cache-hit != 'true' }} @@ -393,20 +393,20 @@ jobs: id: cache-libmicrohttpd uses: actions/cache@v4 with: - path: libmicrohttpd-0.9.64 - key: ${{ matrix.os }}-${{ matrix.c-compiler }}-libmicrohttpd-pre-built + path: libmicrohttpd-0.9.77 + key: ${{ matrix.os }}-${{ matrix.c-compiler }}-libmicrohttpd-0.9.77-pre-built - name: Build libmicrohttpd dependency (if not cached) run: | - curl https://s3.amazonaws.com/libhttpserver/libmicrohttpd_releases/libmicrohttpd-0.9.64.tar.gz -o libmicrohttpd-0.9.64.tar.gz ; - tar -xzf libmicrohttpd-0.9.64.tar.gz ; - cd libmicrohttpd-0.9.64 ; + curl https://s3.amazonaws.com/libhttpserver/libmicrohttpd_releases/libmicrohttpd-0.9.77.tar.gz -o libmicrohttpd-0.9.77.tar.gz ; + tar -xzf libmicrohttpd-0.9.77.tar.gz ; + cd libmicrohttpd-0.9.77 ; ./configure --disable-examples ; make ; if: steps.cache-libmicrohttpd.outputs.cache-hit != 'true' - + - name: Install libmicrohttpd - run: cd libmicrohttpd-0.9.64 ; sudo make install ; + run: cd libmicrohttpd-0.9.77 ; sudo make install ; - name: Refresh links to shared libs run: sudo ldconfig ; @@ -426,7 +426,7 @@ jobs: if [ "$BUILD_TYPE" = "ubsan" ]; then export export CFLAGS='-fsanitize=undefined'; export CXXLAGS='-fsanitize=undefined'; export LDFLAGS='-fsanitize=undefined'; fi # Additional flags on mac. They need to stay in step as env variables don't propagate across steps. - if [ "$matrix.os" = "macos-latest" ]; then + if [ "${{ matrix.os }}" = "macos-latest" ]; then export CFLAGS='-mtune=generic' ; export IPV6_TESTS_ENABLED="true" ; fi diff --git a/test/Makefile.am b/test/Makefile.am index 58fd4c84..60b41351 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -37,7 +37,7 @@ nodelay_SOURCES = integ/nodelay.cpp http_resource_SOURCES = unit/http_resource_test.cpp noinst_HEADERS = littletest.hpp -AM_CXXFLAGS += -lcurl -Wall -fPIC +AM_CXXFLAGS += -lcurl -Wall -fPIC -Wno-overloaded-virtual if HAVE_GNUTLS AM_CXXFLAGS += -lgnutls From 198a20187983d32f312a32587b3631a1f8b95c28 Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 22:29:11 -0800 Subject: [PATCH 09/12] Fix issue with gnutls --- test/Makefile.am | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 60b41351..eb07a25a 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -17,6 +17,13 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA LDADD = $(top_builddir)/src/libhttpserver.la + +if HAVE_GNUTLS +LDADD += -lgnutls +endif + +LDADD += -lcurl + AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/httpserver/ METASOURCES = AUTO check_PROGRAMS = basic file_upload http_utils threaded nodelay string_utilities http_endpoint ban_system ws_start_stop authentication deferred http_resource @@ -37,11 +44,7 @@ nodelay_SOURCES = integ/nodelay.cpp http_resource_SOURCES = unit/http_resource_test.cpp noinst_HEADERS = littletest.hpp -AM_CXXFLAGS += -lcurl -Wall -fPIC -Wno-overloaded-virtual - -if HAVE_GNUTLS -AM_CXXFLAGS += -lgnutls -endif +AM_CXXFLAGS += -Wall -fPIC -Wno-overloaded-virtual if COND_GCOV AM_CFLAGS += -O0 --coverage --no-inline From b50b8040686395ff915736a0aabb03cb3b48cb6c Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 22:37:06 -0800 Subject: [PATCH 10/12] Fix all cpplint issues --- test/integ/authentication.cpp | 1 + test/integ/basic.cpp | 4 ++++ test/integ/deferred.cpp | 2 ++ test/integ/file_upload.cpp | 5 ++++- test/integ/ws_start_stop.cpp | 7 ++++++- test/unit/http_endpoint_test.cpp | 4 ++++ test/unit/http_utils_test.cpp | 4 ++++ test/unit/string_utilities_test.cpp | 2 ++ 8 files changed, 27 insertions(+), 2 deletions(-) diff --git a/test/integ/authentication.cpp b/test/integ/authentication.cpp index bcc1c55b..4f4096d3 100644 --- a/test/integ/authentication.cpp +++ b/test/integ/authentication.cpp @@ -32,6 +32,7 @@ #include #include +#include #include "./httpserver.hpp" #include "./littletest.hpp" diff --git a/test/integ/basic.cpp b/test/integ/basic.cpp index 3e680cb6..177797d1 100644 --- a/test/integ/basic.cpp +++ b/test/integ/basic.cpp @@ -19,12 +19,16 @@ */ #include +#include #include +#include #include #include #include #include #include +#include +#include #include "./httpserver.hpp" #include "httpserver/string_utilities.hpp" diff --git a/test/integ/deferred.cpp b/test/integ/deferred.cpp index 6bece022..bc5e33f6 100644 --- a/test/integ/deferred.cpp +++ b/test/integ/deferred.cpp @@ -34,8 +34,10 @@ #include #include +#include #include #include +#include #include "./httpserver.hpp" #include "./littletest.hpp" diff --git a/test/integ/file_upload.cpp b/test/integ/file_upload.cpp index 57b6942b..81ab4de8 100644 --- a/test/integ/file_upload.cpp +++ b/test/integ/file_upload.cpp @@ -22,13 +22,16 @@ #include #include #include +#include #include -#include #include +#include #include #include #include #include +#include +#include #include "./httpserver.hpp" #include "httpserver/string_utilities.hpp" diff --git a/test/integ/ws_start_stop.cpp b/test/integ/ws_start_stop.cpp index cb77dc59..6e717196 100644 --- a/test/integ/ws_start_stop.cpp +++ b/test/integ/ws_start_stop.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "./httpserver.hpp" #include "./littletest.hpp" @@ -509,7 +510,11 @@ void* start_ws_blocking(void* par) { httpserver::webserver* ws = (httpserver::webserver*) par; ok_resource ok; if (!ws->register_resource("base", &ok)) return PTHREAD_CANCELED; - try { ws->start(true); } catch (...) { return PTHREAD_CANCELED; } + try { + ws->start(true); + } catch (...) { + return PTHREAD_CANCELED; + } return nullptr; } diff --git a/test/unit/http_endpoint_test.cpp b/test/unit/http_endpoint_test.cpp index 1cce2bcd..a22aa050 100644 --- a/test/unit/http_endpoint_test.cpp +++ b/test/unit/http_endpoint_test.cpp @@ -20,6 +20,10 @@ #include "httpserver/details/http_endpoint.hpp" +#include +#include +#include + #include "./littletest.hpp" using httpserver::details::http_endpoint; diff --git a/test/unit/http_utils_test.cpp b/test/unit/http_utils_test.cpp index 0bf5e6ea..5fd3b97b 100644 --- a/test/unit/http_utils_test.cpp +++ b/test/unit/http_utils_test.cpp @@ -32,6 +32,10 @@ #include #include +#include +#include +#include +#include #include "./littletest.hpp" diff --git a/test/unit/string_utilities_test.cpp b/test/unit/string_utilities_test.cpp index 0bc7a213..f0b57e80 100644 --- a/test/unit/string_utilities_test.cpp +++ b/test/unit/string_utilities_test.cpp @@ -21,6 +21,8 @@ #include "httpserver/string_utilities.hpp" #include +#include +#include #include "./littletest.hpp" From c1baab16415ca6945d0d485b43b557de83bca8a2 Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 22:51:00 -0800 Subject: [PATCH 11/12] Added codacy suppressions --- .codacy.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .codacy.yml diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 00000000..9a98e485 --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,6 @@ +--- +engines: + cppcheck: + options: + suppress: + - missingIncludeSystem From 9c5a5916882ab0ef16dd7f1be976e304ee4424c9 Mon Sep 17 00:00:00 2001 From: Sebastiano Merlino Date: Mon, 26 Jan 2026 23:38:11 -0800 Subject: [PATCH 12/12] No need for codacy yaml. It is configured via UI --- .codacy.yml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .codacy.yml diff --git a/.codacy.yml b/.codacy.yml deleted file mode 100644 index 9a98e485..00000000 --- a/.codacy.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -engines: - cppcheck: - options: - suppress: - - missingIncludeSystem