From cd4338b4d8a1276230bb907ebec1b8fea3701160 Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 4 May 2018 11:33:02 +0800 Subject: [PATCH 1/7] fix --- gorequest.go | 8 ++++++-- gorequest_test.go | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gorequest.go b/gorequest.go index 8edb0fc..c2e8c96 100644 --- a/gorequest.go +++ b/gorequest.go @@ -454,10 +454,14 @@ func (s *SuperAgent) queryStruct(content interface{}) *SuperAgent { } func (s *SuperAgent) queryString(content string) *SuperAgent { - var val map[string]string + var val map[string]interface{} if err := json.Unmarshal([]byte(content), &val); err == nil { for k, v := range val { - s.QueryData.Add(k, v) + if v == nil { + s.QueryData.Add(k, "null") + } else { + s.QueryData.Add(k, fmt.Sprintf("%v", v)) + } } } else { if queryData, err := url.ParseQuery(content); err == nil { diff --git a/gorequest_test.go b/gorequest_test.go index 728083e..12e82e4 100644 --- a/gorequest_test.go +++ b/gorequest_test.go @@ -1361,6 +1361,7 @@ func TestQueryFunc(t *testing.T) { const case2_send_struct = "/send_struct" const case3_send_string_with_duplicates = "/send_string_with_duplicates" const case4_send_map = "/send_map" + const case5_send_string_like_mutil_type_map = "/string_like_mutil_type_map" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != POST { t.Errorf("Expected method %q; got %q", POST, r.Method) @@ -1391,6 +1392,11 @@ func TestQueryFunc(t *testing.T) { checkQuery(t, v, "query2", "test2") checkQuery(t, v, "query3", "3.1415926") checkQuery(t, v, "query4", "true") + case case5_send_string_like_mutil_type_map: + checkQuery(t, v, "query1", "test1") + checkQuery(t, v, "query2", "test2") + checkQuery(t, v, "query3", "3.1415926") + checkQuery(t, v, "query4", "true") } })) defer ts.Close() @@ -1427,6 +1433,10 @@ func TestQueryFunc(t *testing.T) { "query4": true, }). End() + + New().Post(ts.URL + case5_send_string_like_mutil_type_map). + Query(`{"query1": "test1", "query2": "test2", "query3": "3.1415926", "query4":true}`). + End() } // TODO: more tests on redirect From d4774fe9f82cbe2ad62629492b56db3a4bd98689 Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 4 May 2018 11:45:16 +0800 Subject: [PATCH 2/7] fix --- gorequest_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gorequest_test.go b/gorequest_test.go index 12e82e4..4344870 100644 --- a/gorequest_test.go +++ b/gorequest_test.go @@ -1361,7 +1361,7 @@ func TestQueryFunc(t *testing.T) { const case2_send_struct = "/send_struct" const case3_send_string_with_duplicates = "/send_string_with_duplicates" const case4_send_map = "/send_map" - const case5_send_string_like_mutil_type_map = "/string_like_mutil_type_map" + const case5_send_string_like_map_with_multi_type_vaule = "/string_like_map_with_multi_type_vaule" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != POST { t.Errorf("Expected method %q; got %q", POST, r.Method) @@ -1392,7 +1392,7 @@ func TestQueryFunc(t *testing.T) { checkQuery(t, v, "query2", "test2") checkQuery(t, v, "query3", "3.1415926") checkQuery(t, v, "query4", "true") - case case5_send_string_like_mutil_type_map: + case case5_send_string_like_map_with_multi_type_vaule: checkQuery(t, v, "query1", "test1") checkQuery(t, v, "query2", "test2") checkQuery(t, v, "query3", "3.1415926") From dc6c5970b0b28f9ac9738756b139de83f3d78b9d Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 4 May 2018 13:20:57 +0800 Subject: [PATCH 3/7] fix --- gorequest.go | 3 ++- gorequest_test.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gorequest.go b/gorequest.go index c2e8c96..1182230 100644 --- a/gorequest.go +++ b/gorequest.go @@ -31,6 +31,7 @@ import ( "github.com/moul/http2curl" "golang.org/x/net/publicsuffix" + "context" ) type Request *http.Request @@ -491,7 +492,7 @@ func (s *SuperAgent) Param(key string, value string) *SuperAgent { } func (s *SuperAgent) Timeout(timeout time.Duration) *SuperAgent { - s.Transport.Dial = func(network, addr string) (net.Conn, error) { + s.Transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { conn, err := net.DialTimeout(network, addr, timeout) if err != nil { s.Errors = append(s.Errors, err) diff --git a/gorequest_test.go b/gorequest_test.go index 4344870..545f001 100644 --- a/gorequest_test.go +++ b/gorequest_test.go @@ -1434,7 +1434,7 @@ func TestQueryFunc(t *testing.T) { }). End() - New().Post(ts.URL + case5_send_string_like_mutil_type_map). + New().Post(ts.URL + case5_send_string_like_map_with_multi_type_vaule). Query(`{"query1": "test1", "query2": "test2", "query3": "3.1415926", "query4":true}`). End() } From 0e750b1faa5906db966178435d3f565b50fb8d80 Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 4 May 2018 14:15:48 +0800 Subject: [PATCH 4/7] add getKind func to simplify golang Kind --- gorequest.go | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/gorequest.go b/gorequest.go index 1182230..531a562 100644 --- a/gorequest.go +++ b/gorequest.go @@ -608,17 +608,17 @@ func (s *SuperAgent) RedirectPolicy(policy func(req Request, via []Request) erro // func (s *SuperAgent) Send(content interface{}) *SuperAgent { // TODO: add normal text mode or other mode to Send func - switch v := reflect.ValueOf(content); v.Kind() { + v := reflect.ValueOf(content) + vKind := getKind(v) + switch vKind { case reflect.String: s.SendString(v.String()) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: // includes rune + case reflect.Int: // includes rune s.SendString(strconv.FormatInt(v.Int(), 10)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: // includes byte + case reflect.Uint: // includes byte s.SendString(strconv.FormatUint(v.Uint(), 10)) - case reflect.Float64: - s.SendString(strconv.FormatFloat(v.Float(), 'f', -1, 64)) case reflect.Float32: - s.SendString(strconv.FormatFloat(v.Float(), 'f', -1, 32)) + s.SendString(strconv.FormatFloat(v.Float(), 'f', -1, 64)) case reflect.Bool: s.SendString(strconv.FormatBool(v.Bool())) case reflect.Struct: @@ -1315,3 +1315,18 @@ func (s *SuperAgent) AsCurlCommand() (string, error) { } return cmd.String(), nil } + +func getKind(val reflect.Value) reflect.Kind { + kind := val.Kind() + + switch { + case kind >= reflect.Int && kind <= reflect.Int64: + return reflect.Int + case kind >= reflect.Uint && kind <= reflect.Uint64: + return reflect.Uint + case kind >= reflect.Float32 && kind <= reflect.Float64: + return reflect.Float32 + default: + return kind + } +} From f3c7f958bbc7d64abadf56b0d28b97e2aaf90435 Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 4 May 2018 15:29:51 +0800 Subject: [PATCH 5/7] rewrite changeMapToURLValues function --- gorequest.go | 95 ++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 63 deletions(-) diff --git a/gorequest.go b/gorequest.go index 531a562..ef8fe11 100644 --- a/gorequest.go +++ b/gorequest.go @@ -871,72 +871,41 @@ func (s *SuperAgent) SendFile(file interface{}, args ...string) *SuperAgent { return s } +func changeMapToURLValuesLoop(urlValues *url.Values, k string, data interface{}) { + dataVal := reflect.ValueOf(data) + dataKind := getKind(dataVal) + switch dataKind { + case reflect.Bool: + urlValues.Add(k, strconv.FormatBool(dataVal.Bool())) + case reflect.String: + urlValues.Add(k, dataVal.String()) + case reflect.Int: + urlValues.Add(k, strconv.FormatInt(dataVal.Int(), 10)) + case reflect.Uint: + urlValues.Add(k, strconv.FormatUint(dataVal.Uint(), 10)) + case reflect.Float32: + urlValues.Add(k, strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) + case reflect.Ptr: + changeMapToURLValuesLoop(urlValues, k, dataVal.Elem().Interface()) + case reflect.Slice: + for i := 0; i < dataVal.Len(); i++ { + changeMapToURLValuesLoop(urlValues, k, dataVal.Index(i).Interface()) + } + case reflect.Map: // exist this case? to check & test ??? TODO + for _, mk := range dataVal.MapKeys() { + changeMapToURLValuesLoop(urlValues, k, dataVal.MapIndex(mk).Interface()) + //changeMapToURLValuesLoop(urlValues, mk.String(), dataVal.MapIndex(mk).Interface()) + } + case reflect.Struct: // exist this case? to check & test ??? TODO consider how to use fieldName tag etc. + case reflect.Invalid: // TODO + default: // TODO + } +} + func changeMapToURLValues(data map[string]interface{}) url.Values { var newUrlValues = url.Values{} for k, v := range data { - switch val := v.(type) { - case string: - newUrlValues.Add(k, val) - case bool: - newUrlValues.Add(k, strconv.FormatBool(val)) - // if a number, change to string - // json.Number used to protect against a wrong (for GoRequest) default conversion - // which always converts number to float64. - // This type is caused by using Decoder.UseNumber() - case json.Number: - newUrlValues.Add(k, string(val)) - case int: - newUrlValues.Add(k, strconv.FormatInt(int64(val), 10)) - // TODO add all other int-Types (int8, int16, ...) - case float64: - newUrlValues.Add(k, strconv.FormatFloat(float64(val), 'f', -1, 64)) - case float32: - newUrlValues.Add(k, strconv.FormatFloat(float64(val), 'f', -1, 64)) - // following slices are mostly needed for tests - case []string: - for _, element := range val { - newUrlValues.Add(k, element) - } - case []int: - for _, element := range val { - newUrlValues.Add(k, strconv.FormatInt(int64(element), 10)) - } - case []bool: - for _, element := range val { - newUrlValues.Add(k, strconv.FormatBool(element)) - } - case []float64: - for _, element := range val { - newUrlValues.Add(k, strconv.FormatFloat(float64(element), 'f', -1, 64)) - } - case []float32: - for _, element := range val { - newUrlValues.Add(k, strconv.FormatFloat(float64(element), 'f', -1, 64)) - } - // these slices are used in practice like sending a struct - case []interface{}: - - if len(val) <= 0 { - continue - } - - switch val[0].(type) { - case string: - for _, element := range val { - newUrlValues.Add(k, element.(string)) - } - case bool: - for _, element := range val { - newUrlValues.Add(k, strconv.FormatBool(element.(bool))) - } - case json.Number: - for _, element := range val { - newUrlValues.Add(k, string(element.(json.Number))) - } - } - default: - // TODO add ptr, arrays, ... - } + changeMapToURLValuesLoop(&newUrlValues, k, v) } return newUrlValues } From 09c3802d56375ac333c01bc9e96643e9abbf256f Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 4 May 2018 15:40:58 +0800 Subject: [PATCH 6/7] rewrite changeMapToURLValues function --- gorequest.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gorequest.go b/gorequest.go index ef8fe11..0074562 100644 --- a/gorequest.go +++ b/gorequest.go @@ -891,14 +891,14 @@ func changeMapToURLValuesLoop(urlValues *url.Values, k string, data interface{}) for i := 0; i < dataVal.Len(); i++ { changeMapToURLValuesLoop(urlValues, k, dataVal.Index(i).Interface()) } - case reflect.Map: // exist this case? to check & test ??? TODO + case reflect.Map: // exist this case? to check & test ??? for _, mk := range dataVal.MapKeys() { changeMapToURLValuesLoop(urlValues, k, dataVal.MapIndex(mk).Interface()) //changeMapToURLValuesLoop(urlValues, mk.String(), dataVal.MapIndex(mk).Interface()) } - case reflect.Struct: // exist this case? to check & test ??? TODO consider how to use fieldName tag etc. - case reflect.Invalid: // TODO - default: // TODO + case reflect.Struct: // exist this case? to check & test ??? + case reflect.Invalid: // + default: // } } From f4976ebd25f376bea0b2b0845ce408fb44141ca9 Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 4 May 2018 16:24:09 +0800 Subject: [PATCH 7/7] rewrite changeMapToURLValues function --- gorequest.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/gorequest.go b/gorequest.go index 0074562..eb06cfc 100644 --- a/gorequest.go +++ b/gorequest.go @@ -31,7 +31,7 @@ import ( "github.com/moul/http2curl" "golang.org/x/net/publicsuffix" - "context" + //"context" ) type Request *http.Request @@ -492,7 +492,17 @@ func (s *SuperAgent) Param(key string, value string) *SuperAgent { } func (s *SuperAgent) Timeout(timeout time.Duration) *SuperAgent { - s.Transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + //s.Transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + // conn, err := net.DialTimeout(network, addr, timeout) + // if err != nil { + // s.Errors = append(s.Errors, err) + // return nil, err + // } + // conn.SetDeadline(time.Now().Add(timeout)) + // return conn, nil + //} + + s.Transport.Dial = func(network, addr string) (net.Conn, error) { conn, err := net.DialTimeout(network, addr, timeout) if err != nil { s.Errors = append(s.Errors, err) @@ -891,14 +901,14 @@ func changeMapToURLValuesLoop(urlValues *url.Values, k string, data interface{}) for i := 0; i < dataVal.Len(); i++ { changeMapToURLValuesLoop(urlValues, k, dataVal.Index(i).Interface()) } - case reflect.Map: // exist this case? to check & test ??? + case reflect.Map: // exist this case? to check & test ??? TODO for _, mk := range dataVal.MapKeys() { changeMapToURLValuesLoop(urlValues, k, dataVal.MapIndex(mk).Interface()) //changeMapToURLValuesLoop(urlValues, mk.String(), dataVal.MapIndex(mk).Interface()) } - case reflect.Struct: // exist this case? to check & test ??? - case reflect.Invalid: // - default: // + case reflect.Struct: // exist this case? to check & test ??? TODO consider how to use fieldName tag etc. + case reflect.Invalid: // TODO + default: // TODO } }