mochengqian opened a new issue, #144:
URL: https://github.com/apache/dubbo-go-pixiu-samples/issues/144
**问题描述**:
在 `http/simple` 样例中,`server/app/server.go` 的 `/user/` handler 对异常请求处理不完整:
1. `POST /user/` 请求体是非法 JSON 时,handler 只写入 `json.Unmarshal` 错误信息,但没有设置 `400
Bad Request`,也没有 `return`。请求会继续向下执行,最终把零值 `User{Name:""}` 写入内存 cache,并返回 `200
OK`。
2. `DELETE` / `PUT` 等未支持的 HTTP method 没有 `default` 分支。请求会从 `switch r.Method`
落空,Go `httptest.ResponseRecorder` / HTTP server 默认表现为 `200 OK` 空响应。
3. 现有 `http/simple/test` 对负向场景覆盖不足,无法严格挡住 “2xx + parse error body” 或 “2xx +
empty body” 这类错误行为。
这是 sample 行为错误。用户复制该样例后,会把坏请求误判为成功请求。
**预期行为**:
`http/simple` 应明确拒绝坏请求:
- 非法 JSON 的 `POST /user/` 应返回 `400 Bad Request`,并停止处理,不能写入空用户名用户。
- 未支持的 HTTP method 应返回 `405 Method Not Allowed`,并带上 `Allow: GET, POST`。
- 负向测试应明确断言非成功状态,不能再接受 2xx 空响应或 2xx parse-error body。
**复现步骤**:
```bash
cd dubbo-go-pixiu-samples
workdir=$(mktemp -d /private/tmp/http-simple-repro-test.XXXXXX)
cat > "$workdir/go.mod" <<'EOF'
module http-simple-repro-test
go 1.25.0
require github.com/apache/dubbo-go-pixiu v1.1.0
EOF
git show HEAD:http/simple/server/app/server.go > "$workdir/server.go"
git show HEAD:http/simple/server/app/user.go > "$workdir/user.go"
cat > "$workdir/server_repro_test.go" <<'EOF'
package main
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestReproInvalidJSONReturns200AndWritesEmptyUser(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/user/",
strings.NewReader("{"))
rec := httptest.NewRecorder()
user(rec, req)
_, emptyUserWritten := cache.Get("")
t.Logf("invalid_json status=%d body=%q empty_user_written=%t",
rec.Code, rec.Body.String(), emptyUserWritten)
if rec.Code != http.StatusOK || !emptyUserWritten {
t.Fatalf("bug not reproduced")
}
}
func TestReproUnsupportedMethodReturns200EmptyBody(t *testing.T) {
req := httptest.NewRequest(http.MethodDelete, "/user/tc", nil)
rec := httptest.NewRecorder()
user(rec, req)
t.Logf("unsupported_method status=%d body=%q", rec.Code,
rec.Body.String())
if rec.Code != http.StatusOK || rec.Body.Len() != 0 {
t.Fatalf("bug not reproduced")
}
}
EOF
cd "$workdir"
go test -v .
```
**环境信息**:
- dubbo-go-pixiu-samples:当前基线 `HEAD`
- Go:1.25.0
- 操作系统:macOS
- 复现方式:使用 `httptest` 直接验证 `http/simple/server/app` handler 行为
**关键日志**:
```text
=== RUN TestReproInvalidJSONReturns200AndWritesEmptyUser
server_repro_test.go:17: invalid_json status=200 body="unexpected end of
JSON
input{\"id\":\"srCFB\",\"name\":\"\",\"age\":0,\"time\":\"0001-01-01T00:00:00Z\"}"
empty_user_written=true
--- PASS: TestReproInvalidJSONReturns200AndWritesEmptyUser (0.00s)
=== RUN TestReproUnsupportedMethodReturns200EmptyBody
server_repro_test.go:29: unsupported_method status=200 body=""
--- PASS: TestReproUnsupportedMethodReturns200EmptyBody (0.00s)
PASS
ok http-simple-repro-test 1.639s
```
`invalid_json` 已经证明两件事:返回 `200`,并且写入了 `name=""` 的零值用户。`unsupported_method`
证明 `DELETE /user/tc` 返回 `200` 空 body。
**初步分析**:
源码定位 `http/simple/server/app/server.go`:
```go
err = json.Unmarshal(byts, &user)
if err != nil {
w.Write([]byte(err.Error()))
}
_, ok := cache.Get(user.Name)
...
user.ID = randSeq(5)
if cache.Add(&user) {
b, _ := json.Marshal(&user)
w.Write(b)
return
}
```
`json.Unmarshal` 出错后没有 `return`,所以 `user` 保持零值并继续执行,最终 `cache.Add(&user)`
写入空用户名用户。
同时,method 分发没有 `default`:
```go
switch r.Method {
case constant.Post:
...
case constant.Get:
...
}
```
未支持的 method 会直接落空,导致 `200 OK` 空响应。
初步分析:
简单来说,invalid JSON 分支只写入错误 body,但没有终止当前请求处理,后续逻辑继续使用零值 User 写入
cache。unsupported method 缺少显式处理分支,因此会落空成 200 空响应。
--
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]