Разобрать тело запроса с помощью пользовательского глагола Golang - PullRequest
0 голосов
/ 22 декабря 2019

Я новичок в Golang и хочу создать API с использованием пакета http. Поэтому я попробовал приведенный ниже фрагмент кода:

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 ]

3 голосов
/ 22 декабря 2019

Ответ находится в источнике ParseForm в net/http/request.go

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

Он будет анализировать тело POST, только если метод POST, PUT или PATCH.

Youможет вызвать это, добавив r.Method = "POST" перед вызовом r.ParseForm:

    r.Method = "POST"
    r.ParseForm()
2 голосов
/ 22 декабря 2019

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

Форма содержит проанализированные данные формы, включая как параметры запроса поля URL, так и данные формы PATCH, POST или PUT. Это поле доступно только после вызова ParseForm. HTTP-клиент игнорирует Form и вместо него использует Body.

И если мы посмотрим на код для ParseForm, то увидим:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...