Bind llhttp symbols inside shared library
Issue
On Linux, the SDK shared library could accidentally bind its internal llhttp calls to llhttp symbols exported by the host process instead of the symbols linked into the SDK library.
This matters for Node.js integrations because Node also exports llhttp symbols. If the dynamic loader interposes Node's llhttp implementation into libgopher-mcp, the SDK HTTP parser can call ABI-incompatible parser functions. That can corrupt callback arguments such as body pointers and lengths, leading to malformed HTTP parser callbacks, oversized length values, or crashes in HTTP/SSE transport code.
How to reproduce
- Build the SDK as a shared library on Linux.
- Load the SDK shared library into a Node.js process or another host process that exports its own
llhttp symbols.
- Use an MCP HTTP or HTTP+SSE client path that parses incoming HTTP responses.
- Send normal HTTP/SSE traffic through the SDK parser.
Before the fix, the dynamic linker could resolve the SDK's internal llhttp function references to the host process symbols. When the host llhttp ABI did not match the SDK's expected ABI, parser callback data could be corrupted. Symptoms included invalid body callback pointers, impossible body lengths, parser errors, or process crashes during HTTP/SSE MCP traffic.
A useful diagnostic is to inspect dynamic symbols and runtime binding behavior with tools such as:
nm -D <host-or-node-binary> | grep llhttp
nm -D libgopher-mcp.so | grep llhttp
LD_DEBUG=bindings <node-or-host-command>
Expected fixed behavior
When building shared libraries on ELF platforms, the SDK links libgopher-mcp with:
This binds function references inside the shared object to definitions inside the same shared object where possible. The SDK's HTTP parser uses the llhttp implementation it was built with, instead of being interposed by the host process.
Regression check
A regression check should load the shared SDK library into a process that also exports llhttp symbols, then exercise HTTP/SSE parsing. The parser should receive valid callback arguments and should not crash or report corrupted body chunk lengths because of host symbol interposition.
Bind llhttp symbols inside shared library
Issue
On Linux, the SDK shared library could accidentally bind its internal
llhttpcalls tollhttpsymbols exported by the host process instead of the symbols linked into the SDK library.This matters for Node.js integrations because Node also exports
llhttpsymbols. If the dynamic loader interposes Node'sllhttpimplementation intolibgopher-mcp, the SDK HTTP parser can call ABI-incompatible parser functions. That can corrupt callback arguments such as body pointers and lengths, leading to malformed HTTP parser callbacks, oversized length values, or crashes in HTTP/SSE transport code.How to reproduce
llhttpsymbols.Before the fix, the dynamic linker could resolve the SDK's internal
llhttpfunction references to the host process symbols. When the hostllhttpABI did not match the SDK's expected ABI, parser callback data could be corrupted. Symptoms included invalid body callback pointers, impossible body lengths, parser errors, or process crashes during HTTP/SSE MCP traffic.A useful diagnostic is to inspect dynamic symbols and runtime binding behavior with tools such as:
Expected fixed behavior
When building shared libraries on ELF platforms, the SDK links
libgopher-mcpwith:This binds function references inside the shared object to definitions inside the same shared object where possible. The SDK's HTTP parser uses the
llhttpimplementation it was built with, instead of being interposed by the host process.Regression check
A regression check should load the shared SDK library into a process that also exports
llhttpsymbols, then exercise HTTP/SSE parsing. The parser should receive valid callback arguments and should not crash or report corrupted body chunk lengths because of host symbol interposition.