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]

Reply via email to