1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-17 11:12:28 +08:00

fix: fix body param bug when send post request

This commit is contained in:
dudaodong
2023-05-30 11:01:39 +08:00
parent 40ab5e8f7b
commit 3b1597d6f7
4 changed files with 125 additions and 111 deletions

View File

@@ -586,9 +586,9 @@ func main() {
} }
``` ```
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpGet">HttpGet</span>
<p>Send http get request.</p> <p>Send http get request. (Deprecated: use SendRequest for replacement)</p>
<b>Signature:</b> <b>Signature:</b>
@@ -628,9 +628,9 @@ func main() {
} }
``` ```
### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpPost">HttpPost</span>
<p>Send http post request.</p> <p>Send http post request. (Deprecated: use SendRequest for replacement)</p>
<b>Signature:</b> <b>Signature:</b>
@@ -658,28 +658,30 @@ import (
func main() { func main() {
url := "https://jsonplaceholder.typicode.com/todos" url := "https://jsonplaceholder.typicode.com/todos"
header := map[string]string{ header := map[string]string{
"Content-Type": "application/json", "Content-Type": "application/x-www-form-urlencoded",
} // "Content-Type": "multipart/form-data",
type Todo struct { }
UserId int `json:"userId"`
Title string `json:"title"`
}
todo := Todo{1, "TestAddToDo"}
bodyParams, _ := json.Marshal(todo)
resp, err := netutil.HttpPost(url, header, nil, bodyParams) postData := url.Values{}
if err != nil { postData.Add("userId", "1")
log.Fatal(err) postData.Add("title", "TestToDo")
}
body, _ := ioutil.ReadAll(resp.Body) // postData := make(map[string]string)
fmt.Println(body) // postData["userId"] = "1"
// postData["title"] = "title"
resp, err := netutil.HttpPost(apiUrl, header, nil, postData)
if err != nil {
log.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
t.Log("response: ", resp.StatusCode, string(body))
} }
``` ```
### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpPut">HttpPut</span>
<p>Send http put request.</p> <p>Send http put request. (Deprecated: use SendRequest for replacement)</p>
<b>Signature:</b> <b>Signature:</b>
@@ -727,9 +729,9 @@ func main() {
} }
``` ```
### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpDelete">HttpDelete</span>
<p>Send http delete request.</p> <p>Send http delete request. (Deprecated: use SendRequest for replacement)</p>
<b>Signature:</b> <b>Signature:</b>
@@ -766,9 +768,9 @@ func main() {
} }
``` ```
### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpPatch">HttpPatch</span>
<p>Send http patch request.</p> <p>Send http patch request. (Deprecated: use SendRequest for replacement)</p>
<b>Signature:</b> <b>Signature:</b>

View File

@@ -585,9 +585,9 @@ func main() {
} }
``` ```
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpGet">HttpGet</span>
<p>发送http get请求</p> <p>发送http get请求。(已废弃: 使用SendRequest)</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -627,9 +627,9 @@ func main() {
} }
``` ```
### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpPost">HttpPost</span>
<p>发送http post请求</p> <p>发送http post请求。(已废弃: 使用SendRequest)</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -657,28 +657,30 @@ import (
func main() { func main() {
url := "https://jsonplaceholder.typicode.com/todos" url := "https://jsonplaceholder.typicode.com/todos"
header := map[string]string{ header := map[string]string{
"Content-Type": "application/json", "Content-Type": "application/x-www-form-urlencoded",
} // "Content-Type": "multipart/form-data",
type Todo struct { }
UserId int `json:"userId"`
Title string `json:"title"`
}
todo := Todo{1, "TestAddToDo"}
bodyParams, _ := json.Marshal(todo)
resp, err := netutil.HttpPost(url, header, nil, bodyParams) postData := url.Values{}
if err != nil { postData.Add("userId", "1")
log.Fatal(err) postData.Add("title", "TestToDo")
}
body, _ := ioutil.ReadAll(resp.Body) // postData := make(map[string]string)
// postData["userId"] = "1"
// postData["title"] = "title"
resp, err := netutil.HttpPost(apiUrl, header, nil, postData)
if err != nil {
log.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
fmt.Println(body) fmt.Println(body)
} }
``` ```
### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpPut">HttpPut</span>
<p>发送http put请求</p> <p>发送http put请求。(已废弃: 使用SendRequest)</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -726,9 +728,9 @@ func main() {
} }
``` ```
### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpDelete">HttpDelete</span>
<p>发送http delete请求</p> <p>发送http delete请求。(已废弃: 使用SendRequest)</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -765,9 +767,9 @@ func main() {
} }
``` ```
### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span> ### <span id="HttpPatch">HttpPatch</span>
<p>发送http patch请求</p> <p>发送http patch请求。(已废弃: 使用SendRequest)</p>
<b>函数签名:</b> <b>函数签名:</b>

View File

@@ -2,6 +2,7 @@ package netutil
import ( import (
"encoding/json" "encoding/json"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
@@ -51,23 +52,23 @@ func TestHttpPost(t *testing.T) {
func TestHttpPostFormData(t *testing.T) { func TestHttpPostFormData(t *testing.T) {
apiUrl := "https://jsonplaceholder.typicode.com/todos" apiUrl := "https://jsonplaceholder.typicode.com/todos"
header := map[string]string{ header := map[string]string{
// "Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded",
"Content-Type": "multipart/form-data", // "Content-Type": "multipart/form-data",
}
type Todo struct {
UserId int `json:"userId"`
Title string `json:"title"`
} }
postData := url.Values{} postData := url.Values{}
postData.Add("userId", "1") postData.Add("userId", "1")
postData.Add("title", "TestAddToDo") postData.Add("title", "TestToDo")
resp, err := HttpPost(apiUrl, header, postData, nil) // postData := make(map[string]string)
// postData["userId"] = "1"
// postData["title"] = "title"
resp, err := HttpPost(apiUrl, header, nil, postData)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
t.FailNow()
} }
body, _ := ioutil.ReadAll(resp.Body) body, _ := io.ReadAll(resp.Body)
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response: ", resp.StatusCode, string(body))
} }

View File

@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
@@ -74,51 +75,34 @@ func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam
} }
func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body interface{}) error { func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body interface{}) error {
err := setHeader(req, header) if err := setHeader(req, header); err != nil {
if err != nil {
return err return err
} } else if err = setQueryParam(req, reqUrl, queryParam); err != nil {
err = setQueryParam(req, reqUrl, queryParam)
if err != nil {
return err return err
} } else if err = setBodyByte(req, body); err != nil {
if strings.Contains(req.Header.Get("Content-Type"), "multipart/form-data") || req.Header.Get("Content-Type") == "application/x-www-form-urlencoded" {
if formData, ok := queryParam.(url.Values); ok {
err = setBodyByte(req, []byte(formData.Encode()))
}
if formData, ok := queryParam.(map[string]string); ok {
postData := url.Values{}
for k, v := range formData {
postData.Set(k, v)
}
err = setBodyByte(req, []byte(postData.Encode()))
}
} else {
err = setBodyByte(req, body)
}
if err != nil {
return err return err
} }
return nil return nil
} }
func setHeader(req *http.Request, header interface{}) error { func setHeader(req *http.Request, header interface{}) error {
if header != nil { if header == nil {
switch v := header.(type) { return nil
case map[string]string: }
for k := range v {
req.Header.Add(k, v[k]) switch v := header.(type) {
} case map[string]string:
case http.Header: for k := range v {
for k, vv := range v { req.Header.Add(k, v[k])
for _, vvv := range vv {
req.Header.Add(k, vvv)
}
}
default:
return errors.New("header params type should be http.Header or map[string]string")
} }
case http.Header:
for k, vv := range v {
for _, vvv := range vv {
req.Header.Add(k, vvv)
}
}
default:
return errors.New("header params type should be http.Header or map[string]string")
} }
if host := req.Header.Get("Host"); host != "" { if host := req.Header.Get("Host"); host != "" {
@@ -138,19 +122,22 @@ func setUrl(req *http.Request, reqUrl string) error {
} }
func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error { func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error {
if queryParam == nil {
return nil
}
var values url.Values var values url.Values
if queryParam != nil {
switch v := queryParam.(type) { switch v := queryParam.(type) {
case map[string]interface{}: case map[string]interface{}:
values = url.Values{} values = url.Values{}
for k := range v { for k := range v {
values.Set(k, fmt.Sprintf("%v", v[k])) values.Set(k, fmt.Sprintf("%v", v[k]))
}
case url.Values:
values = v
default:
return errors.New("query params type should be url.Values or map[string]interface{}")
} }
case url.Values:
values = v
default:
return errors.New("query params type should be url.Values or map[string]interface{}")
} }
// set url // set url
@@ -171,14 +158,36 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err
} }
func setBodyByte(req *http.Request, body interface{}) error { func setBodyByte(req *http.Request, body interface{}) error {
if body != nil { if body == nil {
switch b := body.(type) { return nil
case []byte: }
req.Body = ioutil.NopCloser(bytes.NewReader(b)) var bodyReader *bytes.Reader
req.ContentLength = int64(len(b)) switch b := body.(type) {
default: case io.Reader:
return errors.New("body type should be []byte") buf := bytes.NewBuffer(nil)
if _, err := io.Copy(buf, b); err != nil {
return err
} }
req.Body = ioutil.NopCloser(buf)
req.ContentLength = int64(buf.Len())
case []byte:
bodyReader = bytes.NewReader(b)
req.Body = ioutil.NopCloser(bodyReader)
req.ContentLength = int64(bodyReader.Len())
case map[string]interface{}:
values := url.Values{}
for k := range b {
values.Set(k, fmt.Sprintf("%v", b[k]))
}
bodyReader = bytes.NewReader([]byte(values.Encode()))
req.Body = ioutil.NopCloser(bodyReader)
req.ContentLength = int64(bodyReader.Len())
case url.Values:
bodyReader = bytes.NewReader([]byte(b.Encode()))
req.Body = ioutil.NopCloser(bodyReader)
req.ContentLength = int64(bodyReader.Len())
default:
return fmt.Errorf("invalid body type: %T", b)
} }
return nil return nil
} }