Qiao-yq opened a new issue, #142:
URL: https://github.com/apache/dubbo-go-pixiu-samples/issues/142

   **问题描述**:
   使用 dubbo-go-pixiu 作为 MCP(Model Context Protocol)Server 网关时,`streamable-http` 
传输模式下,只有 `tools/call` 请求(需要代理到后端 HTTP 服务的工具调用)会触发 `http: wrote more than the 
declared Content-Length` 错误(位于 `pkg/common/http/manager.go:139`)。该错误导致 HTTP 
连接被强制关闭,客户端收到 `unexpected EOF`。
   
   MCP 协议本身的操作(`initialize`、`tools/list`)工作正常。
   
   **预期行为**:
   `tools/call` 应成功代理到后端 mock server,并返回合法的 MCP JSON-RPC 响应,不应出现 HTTP 协议层错误。
   **复现步骤**:
   1. 克隆 `dubbo-go-pixiu-samples`,进入 `mcp/simple/` 目录
   2. 启动后端 mock server:
      ```markdown
      cd server/app && go run server.go  # 监听 :8081
      ```
   3. 启动 pixiu 网关:
      ```
      cd dubbo-go-pixiu
      go run cmd/pixiu/*.go gateway start -c 
~/dubbo-go-pixiu-samples/mcp/simple/pixiu/conf.yaml
      ```
   4. 运行测试:
   
      ```
      cd dubbo-go-pixiu-samples/mcp/simple/test
      go test -v
      ```
   
   5. 或用 MCP Inspector 连接:
   
      ```
      npx @modelcontextprotocol/inspector
      # 连接 http://localhost:8888/mcp,选择 streamable-http 传输方式
      ```
   
   **环境信息**:
   
   - dubbo-go-pixiu 版本:v1.0.1-rc1
   - dubbo-go-pixiu-samples 版本:main 分支最新代码
   - 操作系统:Ubuntu 22.04
   - Go 版本:1.25.0
   **关键日志**:
   
   **Pixiu 网关日志**(区分正常与异常):
   
   ```
   # ✅ MCP 协议操作正常
   11:03:10.295  INFO  mcp server received POST request: initialize (id: 
int64:0)
   11:03:10.295  INFO  mcp server initialize: client=inspector-client
   11:03:10.295  INFO  mcp server created new session: 
1fdb6cc0ef950789e49e00582b511511
   11:03:10.317  INFO  mcp server received POST request: 
notifications/initialized
   11:03:29.589  INFO  mcp server received POST request: tools/list (id: 
int64:1)
   11:03:29.590  INFO  mcp server response sent: tools/list (id: int64:1)
   
   # ❌ tools/call 全部失败
   11:03:29.592  INFO  mcp server forwarding tool call: get_user -> GET 
/api/users/1
   11:03:29.593  ERROR Write response failed: http: wrote more than the 
declared Content-Length
   
   11:03:29.595  INFO  mcp server forwarding tool call: search_users -> GET 
/api/users/search
   11:03:29.596  ERROR Write response failed: http: wrote more than the 
declared Content-Length
   
   11:03:29.600  INFO  mcp server forwarding tool call: create_user -> POST 
/api/users
   11:03:29.601  ERROR Write response failed: http: wrote more than the 
declared Content-Length
   11:03:29.602  ERROR Write response failed: http: wrote more than the 
declared Content-Length  ← 出现两次
   
   11:03:29.604  INFO  mcp server forwarding tool call: health_check -> GET 
/api/health
   11:03:29.604  ERROR Write response failed: http: wrote more than the 
declared Content-Length
   ```
   
   **Mock 后端日志**(证明后端**正常接收并处理**了请求):
   
   ```plain
   2026/05/08 11:03:29 GET /api/users/1 77.025µs
   2026/05/08 11:03:29 GET /api/users/search 43.923µs
   2026/05/08 11:03:29 POST /api/users 45.726µs
   2026/05/08 11:03:29 GET /api/health 5.931µs
   ```
   
   **Go 测试输出**:
   
   ```plain
   === RUN   TestServiceAvailability    --- PASS  (0.01s)
   === RUN   TestMCPInitialize          --- PASS  (0.00s)  ← MCP 初始化正常
   === RUN   TestToolsList              --- PASS  (0.00s)  ← 工具列表正常
   === RUN   TestGetUser                --- FAIL  (0.00s)  ← tools/call 失败
       mcp_test.go:90: Failed to read response: unexpected EOF
   === RUN   TestSearchUsers            --- FAIL  (0.00s)
       mcp_test.go:90: Failed to read response: unexpected EOF
   === RUN   TestCreateUser             --- FAIL  (0.01s)
       mcp_test.go:90: Failed to read response: unexpected EOF
   === RUN   TestHealthCheck            --- FAIL  (0.00s)
       mcp_test.go:90: Failed to read response: unexpected EOF
   FAIL
   ```
   
   **MCP Inspector 日志**:
   
   ```plain
   Error from MCP server: FetchError: request to http://localhost:8888/mcp 
failed, reason: socket hang up
   {
     type: 'system',
     errno: 'ECONNRESET',
     code: 'ECONNRESET'
   }
   ```
   
   **初步分析**:
   
   问题定位在 `pkg/common/http/manager.go` 第 139 行的 `writeResponse` 方法。
   
   错误 `http: wrote more than the declared Content-Length` 表明:HTTP 
响应体的实际写入字节数超过了 `Content-Length` 头部声明的长度。
   
   请求处理流程:
   
   1. MCP Server filter 收到 `tools/call` JSON-RPC 请求
   2. 通过 HTTP proxy 转发到后端 mock server
   3. 后端正常返回响应(后端日志确认)
   4. Pixiu 尝试将响应包装为 MCP JSON-RPC 格式并写回客户端
   5. **Bug**:`Content-Length` 与实际写入的字节数不匹配
   
   可能原因:
   
   - `Content-Length` 按上游原始响应长度计算,但最终返回给客户端的是包装后的 MCP JSON-RPC 响应,长度发生了变化却未更新头部
   - 响应体被重复写入
   - 缓冲区未正确重置
   
   **关键区别**:`tools/list` 和 `initialize` 不需要代理到后端 HTTP 服务,直接由 MCP filter 
处理并返回,因此不会触发 `HttpConnectionManager.handleHTTPRequest` → `writeResponse` 路径。


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to