Skip to content

Commit

Permalink
👔 up(net/httpreq): update some client method logic
Browse files Browse the repository at this point in the history
- add IsNoBodyMethod, ToRequestBody
  • Loading branch information
inhere committed Mar 18, 2023
1 parent 411ef1f commit 9454259
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 42 deletions.
61 changes: 19 additions & 42 deletions netutil/httpreq/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package httpreq

import (
"bytes"
"encoding/json"
"io"
"net/http"
"net/url"
"strings"
"time"

Expand Down Expand Up @@ -57,6 +55,9 @@ func ConfigStd(fn func(hc *http.Client)) {
fn(std.client.(*http.Client))
}

// Std instance
func Std() *ReqClient { return std }

// Get quick send a GET request by default client
func Get(url string, opt *ReqOption) (*http.Response, error) {
return std.Method(http.MethodGet).SendWithOpt(url, opt)
Expand Down Expand Up @@ -155,36 +156,7 @@ func (h *ReqClient) StringBody(s string) *ReqClient {
// Allow type:
// - string, []byte, map[string][]string/url.Values, io.Reader(eg: bytes.Buffer, strings.Reader)
func (h *ReqClient) AnyBody(data any) *ReqClient {
var reqBody io.Reader
switch typBody := data.(type) {
case io.Reader:
reqBody = typBody
case map[string][]string:
reqBody = bytes.NewBufferString(url.Values(typBody).Encode())
case url.Values:
reqBody = bytes.NewBufferString(typBody.Encode())
case string:
reqBody = bytes.NewBufferString(typBody)
case []byte:
reqBody = bytes.NewBuffer(typBody)
default:
// auto encode body data to json
if data != nil {
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
// close escape &, <, > TO \u0026, \u003c, \u003e
enc.SetEscapeHTML(false)
if err := enc.Encode(data); err != nil {
panic("auto encode data error=" + err.Error())
}

reqBody = buf
}

// nobody
}

h.body = reqBody
h.body = ToRequestBody(data)
return h
}

Expand All @@ -211,17 +183,7 @@ func (h *ReqClient) Send(url string) (*http.Response, error) {

// SendWithOpt request and return http response
func (h *ReqClient) SendWithOpt(url string, opt *ReqOption) (*http.Response, error) {
if opt == nil {
opt = emptyOpt
}

cli := h
if opt.Timeout > 0 {
cli = New().Client(&http.Client{
Timeout: time.Duration(opt.Timeout) * time.Millisecond,
})
}

if len(cli.baseURL) > 0 {
if !strings.HasPrefix(url, "http") {
url = cli.baseURL + url
Expand All @@ -235,6 +197,21 @@ func (h *ReqClient) SendWithOpt(url string, opt *ReqOption) (*http.Response, err
if err != nil {
return nil, err
}
return h.SendRequest(req, opt)
}

// SendRequest request and return http response
func (h *ReqClient) SendRequest(req *http.Request, opt *ReqOption) (*http.Response, error) {
if opt == nil {
opt = emptyOpt
}

cli := h
if opt.Timeout > 0 {
cli = New().Client(&http.Client{
Timeout: time.Duration(opt.Timeout) * time.Millisecond,
})
}

if len(cli.headerMap) > 0 {
for k, v := range cli.headerMap {
Expand Down
57 changes: 57 additions & 0 deletions netutil/httpreq/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package httpreq
import (
"bytes"
"encoding/base64"
"encoding/json"
"io"
"net/http"
"net/url"
"strings"
Expand Down Expand Up @@ -65,6 +67,13 @@ func AddHeaders(req *http.Request, header http.Header) {
}
}

// AddHeaderMap to reqeust instance.
func AddHeaderMap(req *http.Request, headerMap map[string]string) {
for k, v := range headerMap {
req.Header.Set(k, v)
}
}

// HeaderToStringMap convert
func HeaderToStringMap(rh http.Header) map[string]string {
if len(rh) == 0 {
Expand Down Expand Up @@ -99,6 +108,54 @@ func ToQueryValues(data any) url.Values {
return uv
}

// IsNoBodyMethod check
func IsNoBodyMethod(method string) bool {
return method != "POST" && method != "PUT" && method != "PATCH"
}

// ToRequestBody convert handle
//
// Allow type for data:
// - string
// - []byte
// - map[string]string
// - map[string][]string/url.Values
// - io.Reader(eg: bytes.Buffer, strings.Reader)
func ToRequestBody(data any) io.Reader {
var reqBody io.Reader
switch typVal := data.(type) {
case io.Reader:
reqBody = typVal
case map[string]string:
reqBody = bytes.NewBufferString(ToQueryValues(typVal).Encode())
case map[string][]string:
reqBody = bytes.NewBufferString(url.Values(typVal).Encode())
case url.Values:
reqBody = bytes.NewBufferString(typVal.Encode())
case string:
reqBody = bytes.NewBufferString(typVal)
case []byte:
reqBody = bytes.NewBuffer(typVal)
default:
// auto encode body data to json
if data != nil {
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
// close escape &, <, > TO \u0026, \u003c, \u003e
enc.SetEscapeHTML(false)
if err := enc.Encode(data); err != nil {
panic("auto encode data error=" + err.Error())
}

reqBody = buf
}

// nobody
}

return reqBody
}

// RequestToString convert http Request to string
func RequestToString(r *http.Request) string {
buf := &bytes.Buffer{}
Expand Down

0 comments on commit 9454259

Please sign in to comment.