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

Send http get request.

+

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

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

Send http post request.

+

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

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

Send http put request.

+

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

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

Send http delete request.

+

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

Signature: @@ -800,9 +798,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 dda5a29..7b7a869 100644 --- a/docs/netutil_zh-CN.md +++ b/docs/netutil_zh-CN.md @@ -622,9 +622,9 @@ func main() { } ``` -### HttpGet (Deprecated: use SendRequest for replacement) +### HttpGet -

发送http get请求

+

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

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

发送http post请求

+

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

函数签名: @@ -694,28 +694,26 @@ import ( func main() { url := "https://jsonplaceholder.typicode.com/todos" header := map[string]string{ - "Content-Type": "application/json", + "Content-Type": "application/x-www-form-urlencoded", } - type Todo struct { - UserId int `json:"userId"` - Title string `json:"title"` - } - todo := Todo{1, "TestAddToDo"} - bodyParams, _ := json.Marshal(todo) + + postData := url.Values{} + postData.Add("userId", "1") + postData.Add("title", "TestToDo") - resp, err := netutil.HttpPost(url, header, nil, bodyParams) - if err != nil { - log.Fatal(err) - } + resp, err := netutil.HttpPost(apiUrl, header, nil, postData) + if err != nil { + log.Fatal(err) + } body, _ := ioutil.ReadAll(resp.Body) fmt.Println(body) } ``` -### HttpPut (Deprecated: use SendRequest for replacement) +### HttpPut -

发送http put请求

+

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

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

发送http delete请求

+

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

函数签名: @@ -802,9 +800,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 757e76e..d1b786d 100644 --- a/netutil/http_test.go +++ b/netutil/http_test.go @@ -49,8 +49,8 @@ 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", + "Content-Type": "application/x-www-form-urlencoded", + // "Content-Type": "multipart/form-data", } postData := url.Values{} @@ -61,7 +61,7 @@ func TestHttpPostFormData(t *testing.T) { // postData["userId"] = "1" // postData["title"] = "title" - resp, err := HttpPost(apiUrl, header, postData, nil) + resp, err := HttpPost(apiUrl, header, nil, postData) if err != nil { log.Fatal(err) } diff --git a/netutil/net_internal.go b/netutil/net_internal.go index 9a1f4b7..512a9c8 100644 --- a/netutil/net_internal.go +++ b/netutil/net_internal.go @@ -3,7 +3,9 @@ package netutil import ( "bytes" "errors" + "fmt" "io" + "io/ioutil" "net/http" "net/url" "strings" @@ -72,52 +74,34 @@ func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam } func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body any) error { - err := setHeader(req, header) - if err != nil { + if err := setHeader(req, header); err != nil { + return err + } else if err = setQueryParam(req, reqUrl, queryParam); err != nil { + return err + } else if err = setBodyByte(req, body); err != nil { return err } - err = setQueryParam(req, reqUrl, queryParam) - if 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 { - return err - } - return nil } func setHeader(req *http.Request, header any) 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 != "" { @@ -137,19 +121,21 @@ func setUrl(req *http.Request, reqUrl string) error { } func setQueryParam(req *http.Request, reqUrl string, queryParam any) error { + if queryParam == nil { + return nil + } + var values url.Values - if queryParam != nil { - switch v := queryParam.(type) { - case map[string]string: - values = url.Values{} - for k := range v { - values.Set(k, v[k]) - } - case url.Values: - values = v - default: - return errors.New("query string params type should be url.Values or map[string]string") + switch v := queryParam.(type) { + case map[string]string: + values = url.Values{} + for k := range v { + values.Set(k, v[k]) } + case url.Values: + values = v + default: + return errors.New("query string params type should be url.Values or map[string]string") } // set url @@ -170,14 +156,36 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam any) error { } func setBodyByte(req *http.Request, body any) error { - if body != nil { - switch b := body.(type) { - case []byte: - req.Body = io.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 }