From ea450e971c256eb49e44f522c58cbda1eb335010 Mon Sep 17 00:00:00 2001 From: Inhere Date: Thu, 23 Mar 2023 00:58:03 +0800 Subject: [PATCH] :sparkles: feat(net/hreq): add more util func and simple basic-auth build --- netutil/httpreq/client.go | 4 +++- netutil/httpreq/util.go | 37 +++++++++++++++++++++++++++++++++++- netutil/httpreq/util_test.go | 16 ++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/netutil/httpreq/client.go b/netutil/httpreq/client.go index d5a0657ce..0b77ded60 100644 --- a/netutil/httpreq/client.go +++ b/netutil/httpreq/client.go @@ -91,7 +91,9 @@ func (h *ReqClient) BaseURL(baseURL string) *ReqClient { // Method with custom method func (h *ReqClient) Method(method string) *ReqClient { - h.method = method + if method != "" { + h.method = method + } return h } diff --git a/netutil/httpreq/util.go b/netutil/httpreq/util.go index 24e33c583..ecea77fe2 100644 --- a/netutil/httpreq/util.go +++ b/netutil/httpreq/util.go @@ -12,6 +12,27 @@ import ( "github.com/gookit/goutil/strutil" ) +// BasicAuthConf struct +type BasicAuthConf struct { + Username string `json:"username"` + Password string `json:"password"` +} + +// IsValid value +func (ba *BasicAuthConf) IsValid() bool { + return ba.Password != "" && ba.Username != "" +} + +// Value build to auth header "Authorization". +func (ba *BasicAuthConf) Value() string { + return BuildBasicAuth(ba.Username, ba.Password) +} + +// String build to auth header "Authorization". +func (ba *BasicAuthConf) String() string { + return ba.Username + ":" + ba.Password +} + // IsOK check response status code is 200 func IsOK(statusCode int) bool { return statusCode == http.StatusOK @@ -51,6 +72,8 @@ func IsServerError(statusCode int) bool { } // BuildBasicAuth returns the base64 encoded username:password for basic auth. +// Then set to header "Authorization". +// // copied from net/http. func BuildBasicAuth(username, password string) string { auth := username + ":" + password @@ -87,7 +110,7 @@ func HeaderToStringMap(rh http.Header) map[string]string { return mp } -// ToQueryValues convert string-map to url.Values +// ToQueryValues convert string-map or any-map to url.Values func ToQueryValues(data any) url.Values { // use url.Values directly if we have it if uv, ok := data.(url.Values); ok { @@ -108,6 +131,18 @@ func ToQueryValues(data any) url.Values { return uv } +// AppendQueryToURL appends the given query data to the given url. +func AppendQueryToURL(urlStr string, query url.Values) string { + if len(query) == 0 { + return urlStr + } + + if strings.ContainsRune(urlStr, '?') { + return urlStr + "&" + query.Encode() + } + return urlStr + "?" + query.Encode() +} + // IsNoBodyMethod check func IsNoBodyMethod(method string) bool { return method != "POST" && method != "PUT" && method != "PATCH" diff --git a/netutil/httpreq/util_test.go b/netutil/httpreq/util_test.go index e5bf6a8ed..4871a5de9 100644 --- a/netutil/httpreq/util_test.go +++ b/netutil/httpreq/util_test.go @@ -14,9 +14,20 @@ import ( func TestBuildBasicAuth(t *testing.T) { val := httpreq.BuildBasicAuth("inhere", "abcd&123") + assert.Eq(t, "Basic aW5oZXJlOmFiY2QmMTIz", val) assert.Contains(t, val, "Basic ") } +func TestBasicAuthConf_Value(t *testing.T) { + bac := httpreq.BasicAuthConf{ + Username: "user", + Password: "pass", + } + assert.Eq(t, "user:pass", bac.String()) + assert.Eq(t, "Basic dXNlcjpwYXNz", bac.Value()) + assert.True(t, bac.IsValid()) +} + func TestAddHeaders(t *testing.T) { req, err := http.NewRequest("GET", "inhere.xyz", nil) assert.NoErr(t, err) @@ -44,6 +55,11 @@ func TestToQueryValues(t *testing.T) { vs = httpreq.ToQueryValues(map[string]any{"field1": 234, "field2": "value2"}) assert.StrContains(t, vs.Encode(), "field1=234") + assert.Eq(t, "field1=234&field2=value2", vs.Encode()) + assert.StrContains(t, "abc.com?field1=234&field2=value2", httpreq.AppendQueryToURL("abc.com", vs)) + + vs = httpreq.ToQueryValues(vs) + assert.Eq(t, "field1=234&field2=value2", vs.Encode()) } func TestRequestToString(t *testing.T) {