在 go 中,如何检查写入 http.ResponseWriter 的 http 响应?

In go, how to inspect the http response that is written to http.ResponseWriter?

可能我遗漏了一些明显的东西,但我正在尝试调试由我的 go 服务器编写的 HTTP 响应。

我看到有 httputil.DumpResponse 可用,但它需要一个 http.Response 对象,而我可用的是 http.ResponseWriter

有没有办法从 http.ResponseWriter 中提取 http.Response 以便我可以检查对控制台或日志的响应内容?

上下文:

我正在编写一个简单的服务器端身份验证,使用 https://github.com/RangelReale/osin and it's default example, but could not understand why the front-end (using http://ember-simple-auth.com) 将身份验证失败(密码不正确)解释为成功。

这是片段:

r = mux.NewRouter()
r.HandleFunc("/token", func (w http.ResponseWriter, r *http.Request) {

    fmt.Printf("r.HandleFunc /token\n")

    resp := server.NewResponse()
    defer resp.Close()

    r.ParseForm()

    grantType := r.FormValue("grant_type")
    username := r.FormValue("username")
    password := r.FormValue("password")
    fmt.Printf("/token : grantType=%s  username=%s  password=%s\n", grantType, username, password)

    if ar := server.HandleAccessRequest(resp, r); ar != nil {
        if username == "user" && password == "correct-password" {
            ar.Authorized = true
        } else {
            ar.Authorized = false
        }
        server.FinishAccessRequest(resp, r, ar)
    }

    osin.OutputJSON(resp, w, r)

    // Debug - doesn't work yet
    dump, err := httputil.DumpResponse(w, true)
    if err != nil {
        fmt.Printf("%s\n", dump)
    }
});
http.Handle("/token", r)

写入 *httptest.ResponseRecorder(实现 http.ResponseWriter)并检查它。

包中的示例:

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httptest"
)

func main() {
    handler := func(w http.ResponseWriter, r *http.Request) {
        http.Error(w, "something failed", http.StatusInternalServerError)
    }

    req, err := http.NewRequest("GET", "http://example.com/foo", nil)
    if err != nil {
        log.Fatal(err)
    }

    w := httptest.NewRecorder()
    handler(w, req)

    fmt.Printf("%d - %s", w.Code, w.Body.String())
}

编辑以回答评论中的问题:

如果我对你的问题理解正确,那么是的,你可以为此使用闭包。

将以下人员视为您的处理程序:

func MyHandler(w http.ResponseWriter, r *http.Request) {
    // do useful stuff...
}

然后您可以在您的 servemux 中注册以下闭包以获得所需的效果:

http.HandleFunc("/my/url", func(w http.ResponseWriter, r *http.Request) {
    // first call MyHandler
    MyHandler(w, r)

    // then log whatever you need
    log.Printf("%#v\n", w)
})

如果这个模式证明对你有用,那么你可以编写一个高阶方法,将任何 func(http.ResponseWriter, *http.Request) 包装在这样的闭包中。不过,这本身就是一个话题。