无法从 Go 中的 r.PostFormValue 中提取值?

问题描述

我正在尝试使用 net/http PostFormValue 从 HTTP POST 请求正文(在我的简单 Go HTTP 服务器中)中提取一个值,当我正在寻找 any 时,我的输出一个空字符串键一般,但在我的情况下试图获取 hub.secret 用于 HMAC 检查。我使用 Postman 使用 Gorilla/mux 路由器将请求发送到我的 localhost:8080 实例,并设置了标头 Content-Type: application/x-www-form-urlencoded

我的处理程序看起来像这样:

func rootPostHandler(w http.ResponseWriter,r *http.Request) {

    var expectedMac []byte

    body,err := IoUtil.ReadAll(r.Body)
    if err != nil {
        http.Error(w,err.Error(),http.StatusInternalServerError)
        return
    }
    log.Println("r.Body is:",string(body)) // debug: print the request POST body

    message := body // debug: set message just for extra clarity

    errParse := r.ParseForm()
    if errParse != nil {
        // handle err
    }
    secret := []byte(r.PostFormValue("hub.secret"))
    log.Println("secret is: ",string(secret))
    
    
    mac := hmac.New(sha256.New,secret)
    mac.Write(message)
    expectedMac = mac.Sum(nil)
    fmt.Println("Is HMAC equal? ",hmac.Equal(message,expectedMac))

    w.Header().Add("X-Hub-Signature","sha256="+string(message))
}

r.Body:

hub.callback=http%253A%252F%252Fweb-sub-client%253A8080%252FbRxvcmOcNk&hub.mode=subscribe&hub.secret=xTgSGLOtPNrBLLgYcKnL&hub.topic=%252Fa%252Ftopic

print secret etc 的输出是空字符串,意味着它找不到hub.secret,对吗?我在这里错过了什么?

解决方法

应用程序在这一行读取请求正文到 EOF:

body,err := ioutil.ReadAll(r.Body)

ParseForm 返回一个空表单,因为正文在这一行的 EOF 处:

errParse := r.ParseForm()

请求正文是从网络连接中读取的。无法再次读取请求正文。

删除对 ioutil.ReadAll 的调用或使用从 ioutil.ReadAll 返回的数据创建一个新的正文阅读器:

r.Body = io.NopCloser(bytes.NewReader(body))