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

标签 http go

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

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

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

上下文:

我正在使用 https://github.com/RangelReale/osin 编写一个简单的服务器端身份验证这是默认示例,但无法理解为什么前端(使用 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) 包装在此类闭包中。不过,这本身就是一个话题。

关于http - 在 go 中,如何检查写入 http.ResponseWriter 的 http 响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27983893/

相关文章:

java.lang.NoSuchMethodError : okhttp3.internal.Platform.log 和线程 "Okhttp Dispatcher"java.lang.NoSuchFieldError:实例中的异常

python - 在 django/python 上访问请求 header

rest - 'Query String Parameters' 是 header 的一部分吗?

go - 如何将响应编写器和 http 请求传递给 Go 中的可执行文件?

mysql - 如何从 GO 中的数组将数据输入到 mysql 模型中?

apache - 自制软件网站的自定义禁止页面

php - 如何使用 file_get_contents 和 expedia XML API 修复 411 Length Required 错误?

go - 使用 Go http 客户端时出现 404

go - 如何修复'(1 << 100)* 0.1和(1 << 100)/10'

适用于 Windows 的 Go 编译器