使用自定义动词Golang解析请求正文

时间:2019-12-22 19:30:36

标签: http go

我刚接触Golang,并想使用http包创建API。因此,我尝试了以下代码段:

package main

import (
    "fmt"
    "net/http"
)

type server struct{}


func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)

    r.ParseForm()
    fmt.Println(r.Header["Content-Type"][0])
    fmt.Printf("The URL is: %s\n", r.Form)
}

func main() {
    s := &server{}

    http.Handle("/", s)
    http.ListenAndServe(":8080", nil)
}

请求为:

curl localhost:8080 -d url=google.com -i

输出:

application/x-www-form-urlencoded
The URL is: map[url:[google.com]]

一切正常,直到使用自定义动词,如:

curl localhost:8080 -d url=google.com -i -X CREATE

输出:

application/x-www-form-urlencoded
The URL is: map[]

http软件包和HTTP自定义动词有问题吗?

我的代码有问题吗?

2 个答案:

答案 0 :(得分:3)

答案在ParseForm的{​​{1}}来源中

net/http/request.go

仅当方法为POST,PUT或PATCH时,它才会解析POST正文。

您可以通过在致电 if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" { r.PostForm, err = parsePostForm(r) } 之前添加r.Method = "POST"来强制执行此操作:

r.ParseForm

答案 1 :(得分:2)

https://golang.org/pkg/net/http/#Request

  

Form包含已解析的表单数据,包括URL字段的查询参数和PATCH,POST或PUT表单数据。   该字段仅在调用ParseForm之后可用。   HTTP客户端会忽略Form,而使用Body。

如果我们在ParseForm中查看the code,则会看到:

if r.PostForm == nil {
    if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
        r.PostForm, err = parsePostForm(r)
    }
    if r.PostForm == nil {
        r.PostForm = make(url.Values)
    }
}

最简单的方法是让它认为这是一个POST请求(然后在以后重新设置它,以防以后需要真正的方法):

  method := r.Method
  r.PostForm == nil // this line may necessary
  r.Method = http.MethodPost
  r.ParseForm()
  r.Method = method