diff --git a/docs/netutil.md b/docs/netutil.md index 8e2dbd9..d818765 100644 --- a/docs/netutil.md +++ b/docs/netutil.md @@ -586,9 +586,9 @@ func main() { } ``` -### HttpGet (Deprecated: use SendRequest for replacement) +### HttpGet -

Send http get request.

+

Send http get request. (Deprecated: use SendRequest for replacement)

Signature: @@ -628,9 +628,9 @@ func main() { } ``` -### HttpPost (Deprecated: use SendRequest for replacement) +### HttpPost -

Send http post request.

+

Send http post request. (Deprecated: use SendRequest for replacement)

Signature: @@ -658,28 +658,30 @@ import ( func main() { url := "https://jsonplaceholder.typicode.com/todos" header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, "TestAddToDo"} - bodyParams, _ := json.Marshal(todo) + "Content-Type": "application/x-www-form-urlencoded", + // "Content-Type": "multipart/form-data", + } - resp, err := netutil.HttpPost(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } + postData := url.Values{} + postData.Add("userId", "1") + postData.Add("title", "TestToDo") - body, _ := ioutil.ReadAll(resp.Body) - fmt.Println(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) + t.Log("response: ", resp.StatusCode, string(body)) } ``` -### HttpPut (Deprecated: use SendRequest for replacement) +### HttpPut -

Send http put request.

+

Send http put request. (Deprecated: use SendRequest for replacement)

Signature: @@ -727,9 +729,9 @@ func main() { } ``` -### HttpDelete (Deprecated: use SendRequest for replacement) +### HttpDelete -

Send http delete request.

+

Send http delete request. (Deprecated: use SendRequest for replacement)

Signature: @@ -766,9 +768,9 @@ func main() { } ``` -### HttpPatch (Deprecated: use SendRequest for replacement) +### HttpPatch -

Send http patch request.

+

Send http patch request. (Deprecated: use SendRequest for replacement)

Signature: diff --git a/docs/netutil_zh-CN.md b/docs/netutil_zh-CN.md index 38b87ff..9d2e996 100644 --- a/docs/netutil_zh-CN.md +++ b/docs/netutil_zh-CN.md @@ -585,9 +585,9 @@ func main() { } ``` -### HttpGet (Deprecated: use SendRequest for replacement) +### HttpGet -

发送http get请求

+

发送http get请求。(已废弃: 使用SendRequest)

函数签名: @@ -627,9 +627,9 @@ func main() { } ``` -### HttpPost (Deprecated: use SendRequest for replacement) +### HttpPost -

发送http post请求

+

发送http post请求。(已废弃: 使用SendRequest)

函数签名: @@ -657,28 +657,30 @@ import ( func main() { url := "https://jsonplaceholder.typicode.com/todos" header := map[string]string{ - "Content-Type": "application/json", - } - type Todo struct { - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, "TestAddToDo"} - bodyParams, _ := json.Marshal(todo) + "Content-Type": "application/x-www-form-urlencoded", + // "Content-Type": "multipart/form-data", + } - resp, err := netutil.HttpPost(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } + postData := url.Values{} + postData.Add("userId", "1") + 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) } ``` -### HttpPut (Deprecated: use SendRequest for replacement) +### HttpPut -

发送http put请求

+

发送http put请求。(已废弃: 使用SendRequest)

函数签名: @@ -726,9 +728,9 @@ func main() { } ``` -### HttpDelete (Deprecated: use SendRequest for replacement) +### HttpDelete -

发送http delete请求

+

发送http delete请求。(已废弃: 使用SendRequest)

函数签名: @@ -765,9 +767,9 @@ func main() { } ``` -### HttpPatch (Deprecated: use SendRequest for replacement) +### HttpPatch -

发送http patch请求

+

发送http patch请求。(已废弃: 使用SendRequest)

函数签名: diff --git a/netutil/http_test.go b/netutil/http_test.go index ebcfa24..2b8fc87 100644 --- a/netutil/http_test.go +++ b/netutil/http_test.go @@ -2,6 +2,7 @@ package netutil import ( "encoding/json" + "io" "io/ioutil" "log" "net/http" @@ -51,23 +52,23 @@ func TestHttpPost(t *testing.T) { func TestHttpPostFormData(t *testing.T) { apiUrl := "https://jsonplaceholder.typicode.com/todos" header := map[string]string{ - // "Content-Type": "application/x-www-form-urlencoded", - "Content-Type": "multipart/form-data", - } - type Todo struct { - UserId int `json:"userId"` - Title string `json:"title"` + "Content-Type": "application/x-www-form-urlencoded", + // "Content-Type": "multipart/form-data", } + postData := url.Values{} 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 { log.Fatal(err) - t.FailNow() } - body, _ := ioutil.ReadAll(resp.Body) + body, _ := io.ReadAll(resp.Body) t.Log("response: ", resp.StatusCode, string(body)) } diff --git a/netutil/net_internal.go b/netutil/net_internal.go index 4aeb869..3eea3cf 100644 --- a/netutil/net_internal.go +++ b/netutil/net_internal.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "io" "io/ioutil" "net/http" "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 { - err := setHeader(req, header) - if err != nil { + if err := setHeader(req, header); err != nil { return err - } - err = setQueryParam(req, reqUrl, queryParam) - if err != nil { + } else if err = setQueryParam(req, reqUrl, queryParam); err != nil { return err - } - 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 { + } else if err = setBodyByte(req, body); err != nil { return err } return nil } func setHeader(req *http.Request, header interface{}) error { - if header != nil { - switch v := header.(type) { - case map[string]string: - for k := range v { - req.Header.Add(k, v[k]) - } - 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 header == nil { + return nil + } + + switch v := header.(type) { + case map[string]string: + for k := range v { + req.Header.Add(k, v[k]) } + 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 != "" { @@ -138,19 +122,22 @@ func setUrl(req *http.Request, reqUrl string) error { } func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error { + if queryParam == nil { + return nil + } + var values url.Values - if queryParam != nil { - switch v := queryParam.(type) { - case map[string]interface{}: - values = url.Values{} - for k := range v { - 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{}") + + switch v := queryParam.(type) { + case map[string]interface{}: + values = url.Values{} + for k := range v { + 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{}") } // set url @@ -171,14 +158,36 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err } func setBodyByte(req *http.Request, body interface{}) error { - if body != nil { - switch b := body.(type) { - case []byte: - req.Body = ioutil.NopCloser(bytes.NewReader(b)) - req.ContentLength = int64(len(b)) - default: - return errors.New("body type should be []byte") + if body == nil { + return nil + } + var bodyReader *bytes.Reader + switch b := body.(type) { + case io.Reader: + 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 }