Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jlmartinnc/libhttpserver
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: etr/libhttpserver
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 2 commits
  • 42 files changed
  • 2 contributors

Commits on Apr 8, 2026

  1. Fix std::terminate when uri_log receives null uri (etr#371) (etr#372)

    * Fix std::terminate when uri_log receives null uri pointer
    
    libmicrohttpd may invoke MHD_OPTION_URI_LOG_CALLBACK with a null uri
    pointer before the request line is parsed - for example on port scans,
    TLS clients hitting a plain HTTP port, or half-open connections. The
    previous code assigned the raw pointer directly into a std::string,
    which throws std::logic_error("basic_string::_M_construct null not
    valid"). Because the throw originates inside an MHD C callback with
    no enclosing handler, std::terminate() was called and the process
    aborted under load.
    
    Treat a null uri as an empty string so the assignment is well-defined.
    An empty URI fails to match any registered resource and surfaces as a
    404, which is the correct graceful behaviour.
    
    Resolves etr#371.
    
    * ci(codeql): bump bundled libmicrohttpd to 1.0.3
    
    The CodeQL workflow was still pulling libmicrohttpd-0.9.64 from S3,
    which is below the project's stated minimum of 1.0.0 and is no longer
    served by the bucket - the install step was failing with "gzip:
    stdin: not in gzip format" because curl received a 243-byte error
    response instead of the tarball. Bump to 1.0.3 from the same S3
    location so CodeQL can build the project again.
    
    * ci: bump bundled libmicrohttpd to 1.0.3 in release and verify-build
    
    Aligns release.yml and verify-build.yml with codeql-analysis.yml so all
    workflows pull the same libmicrohttpd-1.0.3.tar.gz from S3. This also
    brings CI in line with the project's documented minimum of >= 1.0.0
    (0.9.77 was below that threshold). Cache keys include the new version
    so existing 0.9.77 entries are not reused.
    
    * test: add unit test for uri_log null/empty/valid uri handling
    
    Adds test/unit/uri_log_test.cpp to lock in the fix for issue etr#371. The
    test calls uri_log() directly (re-declaring the symbol since it has no
    public header) and verifies three cases:
    
      - null uri does not throw and yields an empty complete_uri
      - valid uri is stored verbatim
      - empty uri is stored verbatim
    
    The first case is the regression check: against the unfixed code,
    running the test crashes the process (SIGSEGV from dereferencing the
    null pointer inside std::string's assignment operator on libstdc++ 13;
    on the older libstdc++ 10 from the bug report it threw std::logic_error
    and aborted via std::terminate). With the fix in place, all three sub-
    tests pass cleanly.
    
    The new test target needs an explicit -lmicrohttpd in its link line
    because it instantiates ~modded_request() directly, which references
    MHD_destroy_post_processor; the default LDADD only pulls libmicrohttpd
    in transitively via libhttpserver.la, and modern ld enforces
    --no-copy-dt-needed-entries.
    
    * test(uri_log): satisfy cpplint build/include_subdir for httpserver.hpp
    
    cpplint flags bare "httpserver.hpp" with build/include_subdir [4].
    Match the convention used by every other test file in the repo and
    prefix the include with "./" so cpplint considers the directory
    explicit.
    etr authored Apr 8, 2026
    Configuration menu
    Copy the full SHA
    a752404 View commit details
    Browse the repository at this point in the history

Commits on Apr 21, 2026

  1. Migrate to libmicrohttpd 1.0.0 API with new features (etr#370)

    * Migrate to libmicrohttpd 1.0.0 API with new features
    
    Raise minimum libmicrohttpd requirement to 1.0.0 and migrate all
    deprecated APIs to their v3 replacements:
    
    - Basic Auth: MHD_basic_auth_get_username_password3,
      MHD_queue_basic_auth_required_response3 with UTF-8 support
    - Digest Auth: MHD_digest_auth_check3, MHD_digest_auth_check_digest3,
      MHD_queue_auth_required_response3 with SHA-512/256, userhash,
      nonce binding, and structured digest_auth_result enum
    
    Add new response types: empty_response, pipe_response, iovec_response.
    
    Add external event loop integration (run, run_wait, get_fdset,
    get_timeout, add_connection), daemon management (quiesce, get_listen_fd,
    get_active_connections, get_bound_port), and numerous new daemon options
    (listen_backlog, address_reuse, tcp_fastopen_queue_size, turbo, etc.).
    
    Add conditional WebSocket support via libmicrohttpd_ws.
    
    Add utility functions: reason_phrase, is_feature_supported, get_mhd_version.
    
    * Update README with all new MHD 1.0 features and options
    
    Document WebSocket support, new response types (empty, iovec, pipe),
    external event loop integration, daemon introspection methods, new
    server configuration options (turbo, no_listen_socket, suppress_date_header,
    etc.), enhanced TLS options, updated digest authentication API with
    SHA-256/SHA-512/256 and fine-grained result codes, and new http_utils
    utility methods.
    
    * Add examples for new MHD 1.0 features and document them in README
    
    New example files:
    - empty_response_example: 204 No Content and HEAD-only responses
    - iovec_response_example: scatter-gather response from multiple buffers
    - pipe_response_example: streaming response from a pipe fd
    - websocket_echo: WebSocket echo server with on_open/on_message/on_close
    - daemon_info: daemon introspection (bound port, listen fd, http_utils)
    - external_event_loop: driving the server with run_wait() and quiesce()
    - turbo_mode: high-performance config with turbo, suppressed date header,
      TCP Fast Open, and listen backlog
    
    All examples are added to the Other Examples section of the README with
    inline code, test commands, and links to the source files.
    
    * Cleaned-up validation issues
    
    * fix codacy warnings
    
    * Add documentation and example for serving binary data from memory
    
    The existing string_response already supports binary content (std::string
    can hold arbitrary bytes), but this was not documented or demonstrated
    anywhere. This gap caused users to believe a new response type was needed
    (see PR etr#368).
    
    - Add a note to the README's string_response description clarifying
      binary data support
    - Add a new "Serving binary data from memory" section with inline example
    - Add examples/binary_buffer_response.cpp as a complete, buildable example
      that serves a PNG image from an in-memory buffer
    - Register the new example in examples/Makefile.am
    
    https://claude.ai/code/session_01S3BvBrSoNvUhpYTyhPYCjJ
    
    * Fix CI: add ChangeLog entry and missing include <utility>
    
    Add ChangeLog entry for the binary buffer example to satisfy the
    ChangeLog Check workflow. Add missing #include <utility> for
    std::move to fix cpplint warning.
    
    https://claude.ai/code/session_01S3BvBrSoNvUhpYTyhPYCjJ
    
    * Migrate to libmicrohttpd 1.0.0 API with new features
    
    Raise minimum libmicrohttpd requirement to 1.0.0 and migrate all
    deprecated APIs to their v3 replacements:
    
    - Basic Auth: MHD_basic_auth_get_username_password3,
      MHD_queue_basic_auth_required_response3 with UTF-8 support
    - Digest Auth: MHD_digest_auth_check3, MHD_digest_auth_check_digest3,
      MHD_queue_auth_required_response3 with SHA-512/256, userhash,
      nonce binding, and structured digest_auth_result enum
    
    Add new response types: empty_response, pipe_response, iovec_response.
    
    Add external event loop integration (run, run_wait, get_fdset,
    get_timeout, add_connection), daemon management (quiesce, get_listen_fd,
    get_active_connections, get_bound_port), and numerous new daemon options
    (listen_backlog, address_reuse, tcp_fastopen_queue_size, turbo, etc.).
    
    Add conditional WebSocket support via libmicrohttpd_ws.
    
    Add utility functions: reason_phrase, is_feature_supported, get_mhd_version.
    
    * Fix Codacy CWE-126: replace strlen with std::char_traits::length
    
    Replace strlen(s) with std::char_traits<char>::length(s) in
    unescaper_func to silence Codacy static analysis warning about
    potential over-read on non-null-terminated strings. The MHD API
    guarantees s is null-terminated, but using the C++ equivalent
    avoids false positives from C-focused analyzers.
    
    * libmicro to v1.0.3
    
    * libmicrohttpd to 1.0.3 in codeql checks
    
    * Fix CI: cpplint errors, external event loop test, and Windows pipe build
    
    - Add missing #include <utility> and <string> in headers and examples
    - Reorder includes in webserver.cpp to satisfy cpplint include order
    - Add NOLINT(runtime/int) for curl API's long parameters
    - Add EXTERNAL_SELECT start method (MHD_USE_AUTO without internal
      threading) for proper external event loop support
    - Fix daemon_info test and external_event_loop example to use
      EXTERNAL_SELECT instead of INTERNAL_SELECT with run_wait()
    - Fix pipe_response_example to compile on Windows (_pipe + <io.h>)
    
    * Fix Windows build for new_response_types test
    
    Test file was missed in d4808b4 which fixed the same pattern in
    pipe_response_example.cpp. MinGW64 has _pipe, not pipe.
    
    * Silence cpplint readability/braces on Windows-guarded class
    
    cpplint's brace check gets confused by the #if/#else/#endif inside
    pipe_resource::render_GET, matching the existing NOLINT in
    examples/pipe_response_example.cpp.
    
    * Fix Windows external_event_loop test: drop no_thread_safety()
    
    On Windows/MSYS2, MHD_start_daemon rejects the combination of
    MHD_USE_AUTO (EXTERNAL_SELECT) and MHD_USE_NO_THREAD_SAFETY,
    causing daemon_info.exe test etr#6 to fail with
    "Unable to connect daemon to port: 8080". Drop no_thread_safety()
    from both the test and the matching example; the default
    thread-safe daemon is still drivable from a single thread via
    MHD_run_wait.
    
    * Fix Windows port leak in quiesce_does_not_crash test
    
    MHD_quiesce_daemon transfers the listen socket to the caller. On
    Windows, MHD sockets are Winsock SOCKETs and POSIX close() from
    <unistd.h> does not close them, so the prior version leaked the
    socket and left port 8080 bound. The next test in the same binary
    (external_event_loop) then failed MHD_start_daemon with
    "Unable to connect daemon to port: 8080".
    
    Use closesocket() on Windows and close() elsewhere.
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
    etr and claude authored Apr 21, 2026
    Configuration menu
    Copy the full SHA
    d8b055e View commit details
    Browse the repository at this point in the history
Loading