Skip to content

fix(gateway): keep httplib out of plugin-facing headers + add build-farm purity gate#411

Merged
bburda merged 5 commits into
mainfrom
fix/plugin-httplib-leak-buildfarm-gate
Jun 8, 2026
Merged

fix(gateway): keep httplib out of plugin-facing headers + add build-farm purity gate#411
bburda merged 5 commits into
mainfrom
fix/plugin-httplib-leak-buildfarm-gate

Conversation

@bburda

@bburda bburda commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Pull Request

Summary

Plugin libraries failed to build against the installed gateway with fatal error: httplib.h: No such file or directory. A provider-facing public header chain leaked <httplib.h>:

core/providers/operation_provider.hpp -> dto/operations.hpp -> http/alternate_status.hpp -> http/typed_router.hpp -> <httplib.h>

Plugins implement provider interfaces and exchange JSON / typed DTOs / tl::expected / the opaque PluginRequest/PluginResponse shim - they never use httplib types across the .so boundary, so cpp-httplib should stay a gateway-internal detail. Normal CI masked this (system libcpp-httplib-dev installed + single-overlay build); it only surfaced when a plugin was built against the installed gateway with cpp-httplib withheld (build-farm / Docker topology).

http/typed_router.hpp mixed httplib-free handler-result markers (Result, NoContent, Forwarded, ValidatorResult, ResponseAttachments) with the only httplib-dependent type (TypedRequest). This PR:

  • extracts the httplib-free markers into a new leaf header http/handler_result.hpp; typed_router.hpp re-exports them and keeps only TypedRequest; alternate_status.hpp includes the leaf. The provider/DTO chain is now httplib-free. No ABI, wire, or behaviour change (markers moved verbatim).
  • adds a g++ -M -MG header-purity scan (gateway_plugin_header_purity linter ctest + pre-push hook) that fails if any plugin-facing public header reaches <httplib.h>.
  • adds scripts/check_isolated_build.sh, which reproduces the build-farm topology locally (each plugin built against the installed gateway with cpp-httplib withheld via a poisoned -isystem shadow header).
  • documents the plugin-header purity contract.

Issue


Type

  • Bug fix
  • New feature or tests
  • Breaking change
  • Documentation only

Testing

  • Gateway builds and the existing unit suite passes (96 ctests).
  • Header-purity scan: red on the leaking tree, green after the fix; fails loud on preprocessor errors.
  • scripts/check_isolated_build.sh passes end-to-end on Jazzy: gateway installed, then ros2_medkit_graph_provider, ros2_medkit_sovd_service_interface, and ros2_medkit_opcua all build against the installed gateway with cpp-httplib withheld.
  • The change is a pure header relocation (standard C++17), so it is distro-independent across Jazzy / Humble / Rolling.

Reviewers can verify the contract with colcon test --packages-select ros2_medkit_gateway --ctest-args -L linter -R gateway_plugin_header_purity, or run scripts/check_isolated_build.sh.


Checklist

  • Breaking changes are clearly described (none - no ABI/wire/behaviour change)
  • Tests were added or updated if needed
  • Docs were updated if behavior or public API changed

Out of scope: the gateway still pins cpp-httplib < 0.20 for its own multipart handling (tracked in #409); that is orthogonal to this header leak and not required to make plugins build.

bburda added 5 commits June 8, 2026 09:50
The typed DTO contract made dto/operations.hpp pull http/alternate_status.hpp ->
http/typed_router.hpp -> <httplib.h>, leaking httplib into every plugin that includes a
provider interface (e.g. operation_provider.hpp). Plugins built against the installed
gateway (build-farm / Docker topology, where the vendored httplib is not on the include
path) then failed with 'httplib.h: No such file'.

Extract the httplib-free handler-result vocabulary (Result, NoContent, Forwarded,
ValidatorResult, ResponseAttachments) into a new leaf header http/handler_result.hpp;
typed_router.hpp re-exports it and keeps only TypedRequest (the sole httplib-dependent
type); alternate_status.hpp includes the leaf. Plugins are now httplib-free across the
.so boundary. No ABI, wire, or behaviour change.
g++ -M -MG dependency scan over the provider interfaces and plugin base headers;
fails if any reaches <httplib.h>. Registered as the gateway_plugin_header_purity linter
ctest. Fast and distro-independent.
Build the gateway into a throwaway prefix, then build each plugin library against the
installed gateway with httplib withheld (poisoned -isystem shadow header + -DBUILD_TESTING=OFF).
Plugins overlay into one isolated prefix so deps resolve; parallelism is capped (override
MEDKIT_ISO_JOBS) to avoid OOM on high-core hosts.
Copilot AI review requested due to automatic review settings June 8, 2026 07:59
@bburda bburda self-assigned this Jun 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a transitive public-header leak of #include <httplib.h> into plugin-facing interfaces by extracting the httplib-free handler result vocabulary into a new leaf header, and adds guardrails to prevent the regression in build-farm (“installed gateway”) topologies.

Changes:

  • Introduces http/handler_result.hpp and updates typed_router.hpp / alternate_status.hpp so provider/DTO headers no longer pull in cpp-httplib.
  • Adds a CTest linter (gateway_plugin_header_purity) plus a pre-push pre-commit hook to enforce “no <httplib.h> in plugin-facing public headers”.
  • Adds an end-to-end isolated build script to locally reproduce the build-farm scenario (plugins built against an installed gateway with httplib intentionally poisoned/withheld) and documents the contract.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/ros2_medkit_gateway/scripts/check_headers_httplib_free.sh Adds a preprocessor dependency scan to detect any transitive httplib.h dependency from plugin-facing public headers.
src/ros2_medkit_gateway/README.md Documents the new plugin header purity contract and how it’s enforced.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/typed_router.hpp Re-exports the handler-result markers from the new leaf header while keeping TypedRequest (and httplib) localized here.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/handler_result.hpp New httplib-free header defining Result, NoContent, Forwarded, ValidatorResult, and ResponseAttachments.
src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/alternate_status.hpp Switches include from typed_router.hpp to handler_result.hpp to avoid pulling httplib via DTO/provider chains.
src/ros2_medkit_gateway/design/dto_contract.rst Adds design/contract documentation for “no httplib across the plugin boundary” and the enforcement mechanisms.
src/ros2_medkit_gateway/CMakeLists.txt Registers the new gateway_plugin_header_purity linter CTest.
scripts/check_isolated_build.sh Adds an isolated “installed gateway + poisoned httplib” build reproducer for local verification.
.pre-commit-config.yaml Adds a pre-push hook to run the header purity check automatically.

@bburda bburda requested a review from mfaferek93 June 8, 2026 09:47

@mfaferek93 mfaferek93 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@bburda bburda merged commit b3159b0 into main Jun 8, 2026
20 of 23 checks passed
@bburda bburda deleted the fix/plugin-httplib-leak-buildfarm-gate branch June 8, 2026 10:00
bburda added a commit that referenced this pull request Jun 8, 2026
PRs #408 (gateway config_file launch argument), #411 (httplib-free
plugin-facing headers), and #405 (cpp-httplib <0.20 cap + ROS 2 Lyrical /
Ubuntu 26.04 support) merged after the 0.5.0 changelogs were finalized.
Add their entries to the gateway and cmake changelogs and credit
@evTessellate. Set the 0.5.0 release date to 2026-06-08 across all 15
package changelogs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Plugin libraries fail to build against the installed gateway: httplib.h not found

3 participants