v2.0: Modernization (M1-M6, 44 tasks)#374
Draft
etr wants to merge 562 commits into
Draft
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #374 +/- ##
==========================================
+ Coverage 68.03% 68.72% +0.68%
==========================================
Files 34 64 +30
Lines 1730 4057 +2327
Branches 697 1489 +792
==========================================
+ Hits 1177 2788 +1611
- Misses 80 357 +277
- Partials 473 912 +439
... and 21 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
etr
added a commit
that referenced
this pull request
May 7, 2026
…rueFalse, exclude specs/ Codacy was reporting 2018 new issues on the v2.0 PR (#374). Resolve as follows: * Add .codacy.yaml excluding specs/** — the product spec, architecture notes, task records, and review notes are internal groundwork artifacts, not user-facing docs, and should not be subject to README markdownlint rules. Removes 2003 markdownlint findings. * src/webserver.cpp:499 — drop the redundant `blocking &&` from the wait loop condition. `blocking` is a function parameter never reassigned inside the loop body, so the conjunct was tautological (cppcheck knownConditionTrueFalse). * src/webserver.cpp:946 — replace the C-style `(struct detail::modded_request*)` cast on the MHD `cls` void* with `static_cast<detail::modded_request*>` (cppcheck cstyleCast). Mirrors the existing static_cast usage elsewhere in the file. * detail/webserver_impl.hpp, detail/http_request_impl.hpp, iovec_entry.hpp — add `// cppcheck-suppress-file unusedStructMember` with a one-line rationale comment. Every flagged member is in fact heavily used from the corresponding .cpp translation unit (registered_resources*, route_cache_*, bans, allowances, files_, path_pieces_public_, iovec_entry::base/len, etc.); cppcheck analyses each TU in isolation and cannot see those uses, so the warning is a known pimpl/POD false positive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
etr
added a commit
that referenced
this pull request
May 7, 2026
… clash Two unrelated CI regressions on PR #374, both falling out of TASK-020: 1. Lint job (gcc-14, ubuntu): cpplint flagged src/http_utils.cpp:30 with build/include_order, because the matching public header ("httpserver/http_utils.hpp") came AFTER a non-matching project header ("httpserver/constants.hpp"), and <microhttpd.h> (a C system header in cpplint's view) followed both. cpplint's expected order is: matching header, C system, C++ system, other. Reorder so the matching header comes first and the project headers ("constants.hpp" / "string_utilities.hpp") move to the bottom of the include block. 2. Windows MSYS2 build: src/httpserver/http_utils.hpp failed with error: expected identifier before numeric constant at the line `ERROR = 0,` inside the digest_auth_result enum. <wingdi.h> (pulled in via <windows.h> via <winsock2.h> via <microhttpd.h> on MinGW) unconditionally `#define`s ERROR to 0, and the preprocessor expands macros inside scoped-enum bodies just like anywhere else. Pre-TASK-020 the enum was inside `#ifdef HAVE_DAUTH`, so MSYS2 builds without digest auth never compiled it; PRD-FLG-REQ-001 then made the enum unconditional and exposed the latent collision. v2.0 is unreleased, so renaming is safe: ERROR -> GENERIC_ERROR (matches MHD_DAUTH_ERROR's "general error" docs). Static-assert pin in src/http_utils.cpp updated to match. Verified locally: - python3 -m cpplint on both touched files: exit 0. - `make check` on macOS: 32/32 PASS, all check-hygiene / check-headers gates PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
etr
added a commit
that referenced
this pull request
May 11, 2026
Codacy's "26 new issues (0 max.)" gate was failing on PR #374. Two classes of finding, addressed at root: - 21 markdownlint findings on test/REGRESSION.md (MD013 line-length, MD040 fenced-code language, MD043 heading structure). REGRESSION.md is an internal test-gate document (the v2.0 routing parity gate), conceptually peer to the already-excluded specs/ artifacts and not in the user-facing README/ChangeLog/CONTRIBUTING category. Extend .codacy.yaml exclude_paths with `test/**/*.md`. - 5 cppcheck findings that are all single-TU false positives: * iovec_entry.hpp: `cppcheck-suppress-file unusedStructMember` was not at the top of the file (preprocessorErrorDirective), so the file-level suppression was ignored and `base`/`len` were both flagged unused. Replaced with per-member inline suppressions. * route_cache.hpp: `cache_value::captured_params` is read in src/webserver.cpp at the cache-hit replay site; cppcheck does not follow the cross-TU read. Inline-suppress. * header_hygiene_test.cpp: cppcheck statically assumes none of the forbidden-header guard macros are defined and reports `leaks > 0` as always-false; the comparison is load-bearing at runtime under any actual leak. Inline-suppress. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
etr
added a commit
that referenced
this pull request
May 20, 2026
Three CI failures on feature/v2.0 PR #374 run 26183259463: 1. cpplint: examples/hello_world.cpp was missing the copyright line. Added single-line copyright header (the file is the deliberately minimal lambda-form example, so the full LGPL block would defeat its purpose). 2. tsan ws_start_stop: webserver::stop() and is_running() read impl_->running with no lock while start() writes it from the blocking-server thread. Made the field std::atomic<bool> — fixes the genuine race without changing the mutex/cond_var discipline that gates the blocking wait. 3. tsan route_table_concurrency + threadsafety_stress: libstdc++'s std::ctype<char>::narrow lazily fills a 256-byte cache; the guard flag is not atomic so concurrent std::regex compiles inside http_endpoint::http_endpoint look like a race even though every initialiser computes the same bytes. Added test/tsan.supp scoped to that one libstdc++ symbol pair, plumbed via TSAN_OPTIONS only on the tsan matrix lane, and shipped via test/Makefile.am EXTRA_DIST. Libhttpserver-internal races stay fatal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
etr
added a commit
that referenced
this pull request
May 21, 2026
Planning-only commit. No code yet; subsequent task-branch PRs implement TASK-045..052 in order against feature/v2.0. Adds a multi-subscriber lifecycle hook system to v2.0, replacing v1's patchwork of single-slot callbacks (log_access, not_found_handler, method_not_allowed_handler, internal_error_handler, auth_handler) with one uniform webserver::add_hook(phase, callable) surface plus a per-route http_resource::add_hook(...) variant. Existing v1 setters survive as documented aliases (PRD-HOOK-REQ-009). Eleven phases spanning the connection -> request -> routing -> handler -> response -> cleanup lifecycle: connection_opened, accept_decision, request_received, body_chunk, route_resolved, before_handler, handler_exception, after_handler, response_sent, request_completed, connection_closed. Short-circuit allowed at four pre-handler phases (request_received, body_chunk, before_handler, handler_exception) and at the after_handler post-handler phase. Throwing hooks route through DR-9 §5.2. Closes (once TASK-046, 047, 050 land): #332 banned-IP log entry (accept_decision hook) #281 response-aware access log (response_sent context) #69 Common Log Format w/ time-taken (response_sent context) #273 early 413 on oversize body (request_received short-circuit) Partially addresses #272 (body_chunk observation; the buffer-steal half remains a v2.1 candidate needing a streaming-body API). Files added: specs/architecture/11-decisions/DR-012.md specs/architecture/04-components/hooks.md (§4.10) specs/tasks/M5-routing-lifecycle/TASK-045.md .. TASK-052.md Files updated: specs/product_specs.md - new §3.8 with PRD-HOOK-REQ-001..009 - §4 traceability line for API-HOOK specs/architecture/05-cross-cutting.md - new §5.6 hook lifecycle contract - four new public headers added to §5.5 header tree specs/tasks/_index.md - M5 milestone row updated - 8 task-status rows (045..052) - dependency-graph branch - PRD-HOOK coverage rows - DR-012 coverage row Per-route hooks (TASK-051) are restricted to phases that fire after route resolution. v1 alias retention is covered in TASK-048 (404/405/auth), TASK-049 (internal_error_handler), TASK-050 (log_access), and re-documented in TASK-052. TASK-052 explicitly touches back into the already-Done TASK-040 (examples), TASK-041 (README), TASK-042 (RELEASE_NOTES), TASK-043 (Doxygen) — the planned M6 touch-back called out when this scope was approved for inclusion in PR #374. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fix all 6 major findings from the TASK-029 unworked review issues: - Findings 1/2/5/6 (code-quality, code-simplifier): restructure block_ip() in src/detail/webserver_setup.cpp to hoist the unconditional insert after the conditional erase, eliminating the duplicated impl_->bans.insert(t_ip) call. Add a block comment explaining the three cases (no entry, equal/higher weight no-op, lower weight erase-then-insert) to make the std::set semantics explicit. - Findings 3/4/22 (code-quality, security): add an inline comment to stop_and_wait() in src/webserver.cpp explaining that MHD_stop_daemon() is itself a blocking, draining call — the wait-for-in-flight guarantee is provided by MHD, not by additional synchronisation. Expand the header doc in src/httpserver/webserver.hpp to clarify the relationship between stop() and stop_and_wait() and document where future quiesce logic should be added. Minor items 7-15 and 17 were already resolved on feature/v2.0 (README terminology, register_resource example) or required no action per the recommendation. Items 18-21, 25-27 deferred as minor improvements. All changes compile cleanly (clang++ -std=c++20 -fsyntax-only). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
# Conflicts: # specs/architecture/04-components/http-response.md # src/detail/body.cpp # src/httpserver/iovec_entry.hpp
Address all 4 major and 36 of 37 minor findings from the TASK-043 unworked review issues file (2026-05-20_111711_task-043.md): Source doc improvements: - create_webserver.hpp: trim internal_error_handler setter doc to avoid duplicating the full DR-009 §5.2 contract from webserver class block; add @note/@see cross-reference. Add @note to internal_error_handler_t typedef promoting view lifetime to a dedicated Doxygen tag. Align basic_auth/digest_auth default doc to state concrete per-flag defaults. Add @warning to https_key_password (plaintext storage). Add @warning to file_upload_dir (/tmp world-readable) and expand generate_random_filename_on_upload doc. - feature_unavailable.hpp: clarify webserver::webserver throw site — throw happens at construction time consuming the builder, not at setter. - http_resource.hpp: expand class-level doc with threading note (DR-008 §5.1) and render dispatch pattern description. - http_utils.hpp: add @copydoc to three mixed-type arg_comparator overloads. - webserver.hpp: add @note/@see to run() and run_wait() documenting DR-009 exception contract. Add doc comments to four getter methods (get_access_logger, get_error_logger, get_request_validator, get_unescaper) with threading note. check-doxygen.sh hardening: - Add BUILD_DIR absolute-path guard before any file operations. - Change mktemp to use $BUILD_DIR (portable, avoids world-readable /tmp). - Add empty-log assertion after make doxygen-run to detect make skipping. - Add NOTE comment documenting tag-file path coupling to doxyconfig.in. - Add representative example comments for each filter arm (E1-E6). Spec updates: - specs/architecture/13-documentation.md: add CI gate note. - Mark all 41 items as [x] in the unworked review issues file. Deferred: item 17 (generateFilenameException rename — pre-existing API-breaking change, needs its own task). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
# Conflicts: # src/httpserver/create_webserver.hpp
# Conflicts: # src/detail/webserver_callbacks_lifecycle.cpp # src/hook_handle.cpp
…d from agent subdir patches)
Address all 48 minor findings from the 2026-05-26 review pass. Summary of changes by file: src/detail/webserver_aliases.cpp - Remove redundant `static` from `append_sanitized` (anon namespace already provides internal linkage; findings #6/#15/#16) - Trim verbose format-compatibility comment to single-line reference (#7) src/detail/webserver_finalize.cpp - Trim file-level comment block to two-sentence summary (#20) - Add clarifying comment to the `!mr->response` defensive guard (#21) - Rename `bytes` → `bytes_queued` to match the ctx field it populates (#22) - Add inline NOTE to elapsed ternary: alias must not read ctx.elapsed (#36) - Sentinel check for degenerate start_time: emit nanoseconds{-1} when answer_to_connection never ran, so hook authors can distinguish port-scan paths from real (but very slow) requests (#37) src/detail/webserver_request.cpp - Remove redundant `mr->ws = parent` from complete_request; add comment noting the field is pre-populated in answer_to_connection (#3) - Add NOTE comments at both before_handler and skip_handler short-circuit paths documenting that after_handler does not fire there (#38) - Collapse stale TASK-050 migration comment to one line (#25) src/httpserver/hook_context.hpp - Add @note to response_sent_ctx documenting elapsed==zero when only the log_access alias fires (no add_hook(response_sent, ...) registered) (#9) - Add @note to request_completed_ctx documenting the nanoseconds{-1} sentinel for degenerate start_time paths (#37) src/httpserver/create_webserver.hpp - Add @param note to log_access() setter documenting that the callable must be CopyConstructible (#35) examples/clf_access_log.cpp - Refactor emit_clf_line to use early null guard + unconditional extraction of method/path (idiomatic pattern matching webserver_aliases.cpp) (#12-14) - Add comment explaining intentional 'HTTP/1.1' hardcoding (#33) specs/architecture/04-components/hooks.md - Update after_handler, response_sent, request_completed rows with file:symbol fire-site references (#26, #27) - Fix stale webserver.cpp references for route_resolved, before_handler, and handler_exception rows (pre-existing staleness from TASK-048) (#27) - Update API surface comment: after_handler_ctx uses http_response* not http_response& (#4) - Add after_handler firing rules paragraph documenting which paths fire / skip after_handler (#1, #2) specs/tasks/M5-routing-lifecycle/TASK-050.md - Update three action items to reference correct TUs (webserver_finalize.cpp, webserver_callbacks.cpp) and correct field types (#28, #40) test/integ/hooks_no_firing.cpp - Add positive firing-count assertions for all wired phases on the happy-path GET (after_handler, response_sent, request_completed, route_resolved, before_handler, connection_opened, connection_closed, request_received) to give the test lasting regression value (#10, #42) test/integ/hooks_request_completed_fires_on_early_failure.cpp - Remove timing-dependent 50ms sleep; rely on ws.stop() as synchronisation barrier, consistent with other integ tests in this task (#11, #43) test/unit/hooks_log_access_alias_slot_test.cpp - Add assertion that '-' replacement appears at injection site in path sanitization test (not just absence of control chars) (#44) - Add assertion that 'GET' remains intact in method sanitization test (#46) - Add fourth test case pinning construction-time isolation between two webservers each with their own log_access callable; documents that runtime re-registration is deferred to a future task (#48) specs/unworked_review_issues/2026-05-26_123948_task-050.md - Mark all 48 items with [x] and disposition notes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… review Major items (all 5 addressed): - [1] register_ws_resource smart-ptr overloads: already done by TASK-035, verified - [2,7] HAVE_DAUTH constructor guard: already done (webserver.cpp:258-266), verified - [3,10,12] features() body: refactored to four constexpr bool k_* locals + flat return - [4] websocket_handler stub repetition: extracted [[noreturn]] throw_ws_unavailable() helper - [5] webserver_features_test branching: moved to k_expected_* constexpr consts outside test body Minor items fixed: - [6] httpserver.hpp: update C++ guard 201703L → 202002L (DR-001 / C++20 floor) - [8] 07-feature-availability.md: document HAVE_DAUTH construction-time throw - [9] create_webserver.cpp: trim digest_auth_default() comment to match basic_auth_default() - [14] webserver_dauth_unavailable_test: add explicit_digest_auth_false_does_not_throw test - [15,29] webserver_dauth_unavailable_test: add listen_socket(false) + remove ws.stop() - [17] http_request_auth.cpp: add sentinel comment to get_pass() #else branch - [18,19] http_request_auth.cpp: consolidate get_digested_user() null+empty guards - [31] create_webserver_test: add basic_auth_true_succeeds_when_bauth_available test Minor items deferred: 11, 13, 16, 20, 21, 22, 23, 24, 25, 28, 30, 32 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
# Conflicts: # src/websocket_handler.cpp
…eview-cleanup) Major findings (5 total): - #1 (adr-violation): implementation is correct per DR-012/DR-009 §5.2; deferred. - #2/#3/#28 (code-structure, triplicate): extracted append_impl<P,Sig> template helper in resource_hook_table.cpp anonymous namespace; each of the five append_* methods now delegates in one line (mirrors fire_short_circuit_impl / fire_void_impl pattern). - #4/#5 (test-structure, advisory): deferred — project prefers per-case explicit test bodies for independent failure reporting. Key minor fixes applied (cosmetic, no behavior change): - TOCTOU anti-pattern (#6/#35/#36/#45/#47/#48): removed expired()+lock() double-check from per_route_table() helper; fire_request_completed_gated now uses the helper consistently (was inline-expanded). - Shadow variable (#15/#38): renamed local var per_route_table → rtable in fire_before_handler_gated, consistent with other gated-fire helpers. - Lifetime comment (#12): added "res keeps the resource alive while rtable is in use" note in handle_dispatch_exception. - Memory-order comment (#50): documented acquire-chain at rtable fetch site in fire_before_handler_gated. - Sentinel assertions (#41/#61/#62): removed LT_CHECK_EQ(true, true) from hooks_per_route_resource_destroyed_first.cpp and hook_api_shape_test.cpp; replaced with descriptive comments. - resource_hook_table.hpp comments (#8): clarified named-vector vs std::array tradeoff and any_hooks_ unused slots. - http_resource.hpp (#24/#27): added copy-shares-hook-table note; added comment before HTTPSERVER_COMPILATION guard. - http-resource.md / DR-012.md (#9/#42/#43): documented per-route hook bus and PIMPL storage choice. All 62 items marked [x] in specs/unworked_review_issues/2026-05-26_230100_task-051.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Restores a MemorySanitizer lane to verify-build.yml (instrumented libc++ + libmicrohttpd, gnutls/curl excluded, unit-scoped tests), adds a local structural gate (scripts/check-msan-lane.sh + self-test) wired into the lint lane, and removes the retired ubuntu-18.04/clang-6.0 stale block. Validated by 9 reviewers over 2 iterations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Drop --disable-valgrind-helgrind/drd/sgcheck from the Valgrind lane so memcheck + both race detectors run on every PR. sgcheck (removed upstream in Valgrind 3.20) is made explicitly off via AX_VALGRIND_DFLT([sgcheck], [off]) in configure.ac. Add comments-only test/valgrind-helgrind.supp and test/valgrind-drd.supp (DR-008: libhttpserver races get fixed in source, only third-party benign races get narrow entries during CI triage), wired into VALGRIND_SUPPRESSIONS_FILES + EXTRA_DIST + AC_CONFIG_FILES. Results- print step now surfaces memcheck+helgrind+drd logs. New structural gate scripts/check-valgrind-lane.sh (+ self-test) guards the wiring on the lint lane; the real race-detector run and finding-triage happen CI-side on the PR's Linux lane (Valgrind is Linux-only). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…d, correct make target + housekeeping
- verify-build.yml: split valgrind lane into 3 parallel jobs (valgrind-memcheck/
-helgrind/-drd) so tools run concurrently not serially; add timeout-minutes: 90;
invoke the real AX_VALGRIND_CHECK target 'make check-valgrind-${TOOL}'
(was the non-existent 'make check-${TOOL}')
- check-valgrind-lane.sh: tighten target assertion to require the check-valgrind-
prefix; test_check_valgrind_lane.sh: add Test 7 (bare check-<tool> must fail)
- TASK-088.md: check completed action items; defer helgrind/drd triage to PR (CI-side)
- specs/architecture/09-testing.md: document the parallel memcheck+helgrind+drd lane
- persist 21 residual minor review findings
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Splits the valgrind CI lane into three parallel per-tool jobs (memcheck, helgrind, drd) running the real AX_VALGRIND_CHECK targets with a 90-min timeout guard; documents sgcheck's upstream removal; scaffolds narrow per-tool suppression files (populated during CI-side triage) wired via VALGRIND_SUPPRESSIONS_FILES/EXTRA_DIST/AC_CONFIG_FILES; adds a local structural gate (scripts/check-valgrind-lane.sh + self-test) to the lint lane. Validated by 9 reviewers over 2 iterations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…s fatal Wire the TASK-044 parallel-install acceptance gate into per-PR CI on a single baseline Linux gcc/libstdc++ lane and stop the five environment-quirk paths from degrading a SKIP into a pass. - scripts/lib/skip-or-fail.sh: new sourced helper defining skip_or_fail(), which emits SKIP and exits 1 unless HTTPSERVER_ALLOW_PARALLEL_INSTALL_SKIP=1. - scripts/check-parallel-install.sh: source the helper; convert the five environment-quirk skip calls (master ref missing, worktree add, v1 bootstrap/configure/make) to skip_or_fail; leave the two pre-flight developer guards as plain skip; refresh the header framing. - .github/workflows/verify-build.yml: opt one baseline gcc-14 none lane in via matrix key parallel-install: check; add a master-ref fetch step and a make check-parallel-install step (no skip authorization, so skips stay fatal); add the check-parallel-install-lane structural gate on the lint lane. - scripts/check-parallel-install-lane.sh + test: structural gate asserting the CI wiring stays in place. - scripts/test_check_parallel_install.sh: pin the skip_or_fail exit-code contract; wired into check-local via lint-parallel-install-skip-contract. - Makefile.am: EXTRA_DIST + two lint targets + .PHONY; RELEASE_NOTES.md: document the live gate and the escape hatch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…l non-blocking) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…ove SKIP-degrades-to-pass paths Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Both tasks were merged (e530ae3, 64a361f) with their task files marked Completed/Done, but the M7 index status table still showed Backlog. Sync the index rows to reality; no code change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
- Pin every action in codeql-analysis.yml to a full 40-hex commit SHA
(actions/checkout v4.2.2, github/codeql-action/{init,analyze} v3.36.3,
init+analyze sharing one SHA); add a rotation header comment.
- Delete the dead commented-out Autobuild scaffolding; keep an explicit
./configure + make build so CodeQL's C/C++ extractor traces the real
compile.
- verify-build.yml: flip the Codecov upload to fail_ci_if_error: true so an
upload failure breaks CI, with a comment distinguishing it from a
coverage-percentage drop (gated separately by codecov.yml).
- Document the Windows doxygen invariance exclusion durably under a labelled
'Invariance exclusion (doxygen)' rationale.
- Add two self-testing structural gates (check-codeql-workflow.sh,
check-workflow-pinning.sh) with fixture-driven unit tests, wired into the
CI lint lane and Makefile.am (EXTRA_DIST + lint-codeql-workflow /
lint-workflow-pinning targets), mirroring the parallel-install-lane idiom.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…s.yml Address security-reviewer-iter1-1, security-reviewer-iter1-2, cloud-infrastructure-reviewer-iter1-1, cloud-infrastructure-reviewer-iter1-2, and housekeeper-iter1-1. - codeql-analysis.yml: add top-level `permissions: actions: read / contents: read / security-events: write` block to enforce least-privilege on the GITHUB_TOKEN; required for the SARIF upload to succeed on repos with restrictive default token permissions. - codeql-analysis.yml: add sha256sum verification on the libmicrohttpd-1.0.3 download (matching the digest already used in all verify-build.yml steps), switch curl to -fsSL so HTTP errors are fatal, and add a rotation comment explaining how to update the digest. - check-codeql-workflow.sh: add assertions (g) and (h) to gate against silent regression of the permissions block and checksum verification. - test_check_codeql_workflow.sh: add tests 7 and 8 (TDD red-green) for the new gate assertions; update write_good fixture to include both features. - TASK-090.md: advance status from Backlog to In Progress. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…l non-blocking) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Remove silent gate degradations across the check-*.sh set: - check-soversion.sh: readelf/otool (SONAME/install-name, A5) and pkg-config (A6) are now hard prerequisites — an absent tool FAILS with a clear error instead of degrading to a filename-only check. Runs under set -euo pipefail; the tee-pipeline install brackets itself with set +e/-e so its PIPESTATUS check still emits A1. - check-parallel-install.sh: set -euo pipefail; guarded the audited library_names command substitution with || true. - lib/resolve-prefix.sh (sourced by both): guarded the prefix grep so a default prefix does not trip -e before the /usr/local fallback. - check-examples.sh: set -euo pipefail; client_cert_auth moved into the HAVE_GNUTLS conditional in examples/Makefile.am (root-cause fix — it builds and links there) and re-included in coverage (KNOWN_ARTIFACTS emptied). verify-installed-examples.sh should_skip() kept in sync. - check-readme.sh + check-release-notes.sh: markdownlint is strict by default; LIBHTTPSERVER_MARKDOWNLINT_ADVISORY=1 (or legacy MARKDOWNLINT_STRICT=no) downgrades. release-notes now surfaces findings (2>&1) instead of swallowing them. - Fence balance: extracted lib/check-fence-balance.sh, an ordered open/close state machine shared by both doc checks, replacing the count-parity heuristic that missed two consecutive openers. Pinned by the new test_check_fence_balance.sh unit test, wired as lint-fence-balance into check-local. - no_* setter enumeration: full v1 family committed to lib/v1-no-setters.txt (single source of truth), consumed by both release-notes (A2 presence) and readme (forbidden set) so removals are non-optional. The literal "[[deprecated]] scan" is infeasible (v2 removed the setters outright, no markers exist) — see TASK-091.md. RELEASE_NOTES.md "What's gone" expanded to all 17 names. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…cking) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Two thread-safety contract tests lived in check_PROGRAMS but were never run deliberately on the matrix: - route_table_concurrency (lock-order / radix stress) was TSan manual-only. - threadsafety_stress stop()-from-handler sub-test was env-gated and skipped by default in CI. Add two convenience targets to test/Makefile.am (check-route-table-concurrency loops the TSan binary RTC_ITERATIONS times; check-stop-from-handler sets HTTPSERVER_RUN_STOP_FROM_HANDLER=1) and two verify-build.yml steps: the first runs the concurrency stress on the tsan lane (time-boxed to 2 min, reusing tsan.supp); the second runs the stop-from-handler negative case on the single baseline Ubuntu gcc lane (timeout-minutes catches the documented hang). Correct the stale "manual-only" / "Skipped in CI" comments in test/Makefile.am and both source headers, and document both gates in test/PERFORMANCE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…cking) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…handler into per-PR CI Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
- per_route_auth.cpp: replace short-circuiting == credential compare with a constant-time equal helper (CWE-208); reframe the note as the production-ready form. - pipe_response_example.cpp: wrap writes in a write_all partial-write / EINTR loop; mark production-ready. - clf_access_log.cpp: emit the real advertised protocol version via ctx.request->get_version() (TASK-018), sanitized, instead of a hard-coded HTTP/1.1. - client_cert_auth.cpp, centralized_authentication.cpp, minimal_https_psk.cpp: reword inline caveats to the consistent 'for illustration; production must ...' framing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…entication, checkboxes, findings) Applied during the validate pass on top of the implementation commit: - examples/centralized_authentication.cpp: close CWE-208 timing side-channel by using a self-contained constant_time_equal helper (mirrors per_route_auth), replacing the short-circuiting != credential compare; comment corrected to describe the || reject path accurately. - specs/tasks/M7-v2-cleanup/TASK-093.md: tick the four completed action items. - specs/unworked_review_issues: persist 16 unworked minor findings (non-blocking). make check: examples build clean; library suite green on serial run (the 6 failures under `make check -j4` are pre-existing parallel port-contention flakes — all pass on serial re-run). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
…n flakiness)
The integration tests each started a webserver on a hardcoded port 8080
and built client URLs as compile-time literals ("localhost:" PORT_STRING
"/path"). Under `make check -j`, concurrent tests raced for :8080, one lost
the bind(), and that test FAILed — a shifting set of failures (6-11 per run)
that read as flakiness but was deterministic port contention.
Each test now binds port 0 (kernel picks a free port) and reads the actual
port back via webserver::get_bound_port() at runtime, building URLs with
std::to_string(port). This mirrors the pattern already used by
threadsafety_stress.cpp and daemon_info.cpp.
Files (12):
- 10 PORT_STRING tests migrated to runtime URLs: basic, authentication,
ws_start_stop, deferred, ban_system, file_upload, new_response_types,
digest_challenge_format_test, nodelay, threaded.
- connection_state_body_residue_test: raw-socket connect() now targets the
runtime bound port.
- route_table_concurrency: create_webserver(8080) -> (0) (no client URLs).
- ws_start_stop: PORT+20/PORT+21 were separate servers -> each binds 0 and
reads its own get_bound_port(); custom_socket path binds htons(0) and
recovers the port via getsockname().
- daemon_info left as-is: its get_bound_port()==PORT assertion requires an
explicit port, and it is now the sole user of 8080 (no collision).
Verified: full `make check -j4` 107/107 PASS; all 13 port-binding tests
launched concurrently for 6 rounds with 0 failures (previously 6-11 FAILs
under plain -j4). The only remaining `make check` red is the pre-existing
check-doxygen failure in unmodified src/ headers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015bNfjNMbo9J5WvrcA4ZQqY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Integration branch for the v2.0 modernization effort. Tasks land here individually (one merge commit per task) so the full v2.0 ships as a single reviewable PR.
This PR will remain draft until all milestones are complete.
Milestones
Specs live under
specs/(product_specs, architecture, tasks).Merged tasks
Test plan
Per-task validation runs through the groundwork validation loop on each task branch before merging here. Pre-merge of v2.0 to
master:./configure && makeclean on macOS (Apple Clang) and Linux (recent GCC)make checkgreen-std=c++(11|14|17)regressions in tree🤖 Generated with Claude Code