Browse Source

修复调试RClone发现的问题

pull/44/head
Sydonian 1 year ago
parent
commit
c88de2ee10
4 changed files with 92 additions and 86 deletions
  1. +2
    -2
      sdks/storage/object.go
  2. +50
    -11
      utils/http/http.go
  3. +32
    -0
      utils/http/http_test.go
  4. +8
    -73
      utils/serder/serder.go

+ 2
- 2
sdks/storage/object.go View File

@@ -100,8 +100,8 @@ const ObjectDownloadPath = "/object/download"
type ObjectDownload struct {
UserID UserID `form:"userID" json:"userID" binding:"required"`
ObjectID ObjectID `form:"objectID" json:"objectID" binding:"required"`
Offset int64 `form:"offset" json:"offset"`
Length *int64 `form:"length" json:"length"`
Offset int64 `form:"offset" json:"offset,omitempty"`
Length *int64 `form:"length" json:"length,omitempty"`
}
type DownloadingObject struct {
Path string


+ 50
- 11
utils/http/http.go View File

@@ -9,8 +9,10 @@ import (
"net/http"
"net/textproto"
ul "net/url"
"reflect"
"strings"

"github.com/mitchellh/mapstructure"
"gitlink.org.cn/cloudream/common/pkgs/iterator"
"gitlink.org.cn/cloudream/common/utils/math2"
"gitlink.org.cn/cloudream/common/utils/serder"
@@ -285,13 +287,13 @@ func PostMultiPart(url string, param MultiPartRequestParam) (*http.Response, err
defer muWriter.Close()

if param.Form != nil {
mp, err := serder.ObjectToMap(param.Form)
mp, err := objectToStringMap(param.Form)
if err != nil {
return fmt.Errorf("formValues object to map failed, err: %w", err)
}

for k, v := range mp {
err := muWriter.WriteField(k, fmt.Sprintf("%v", v))
err := muWriter.WriteField(k, v)
if err != nil {
return fmt.Errorf("write form field failed, err: %w", err)
}
@@ -351,17 +353,17 @@ func prepareQuery(req *http.Request, query any) error {
return nil
}

mp, ok := query.(map[string]any)
mp, ok := query.(map[string]string)
if !ok {
var err error
if mp, err = serder.ObjectToMap(query); err != nil {
if mp, err = objectToStringMap(query); err != nil {
return fmt.Errorf("query object to map: %w", err)
}
}

values := make(ul.Values)
for k, v := range mp {
values.Add(k, fmt.Sprintf("%v", v))
values.Add(k, v)
}

req.URL.RawQuery = values.Encode()
@@ -373,17 +375,17 @@ func prepareHeader(req *http.Request, header any) error {
return nil
}

mp, ok := header.(map[string]any)
mp, ok := header.(map[string]string)
if !ok {
var err error
if mp, err = serder.ObjectToMap(header); err != nil {
if mp, err = objectToStringMap(header); err != nil {
return fmt.Errorf("header object to map: %w", err)
}
}

req.Header = make(http.Header)
for k, v := range mp {
req.Header.Set(k, fmt.Sprintf("%v", v))
req.Header.Set(k, v)
}
return nil
}
@@ -412,17 +414,17 @@ func prepareFormBody(req *http.Request, body any) error {
return nil
}

mp, ok := body.(map[string]any)
mp, ok := body.(map[string]string)
if !ok {
var err error
if mp, err = serder.ObjectToMap(body); err != nil {
if mp, err = objectToStringMap(body); err != nil {
return fmt.Errorf("body object to map: %w", err)
}
}

values := make(ul.Values)
for k, v := range mp {
values.Add(k, fmt.Sprintf("%v", v))
values.Add(k, v)
}

data := values.Encode()
@@ -448,3 +450,40 @@ func setValue(values ul.Values, key, value string) ul.Values {
values.Add(key, value)
return values
}

func objectToStringMap(obj any) (map[string]string, error) {
anyMap := make(map[string]any)
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
TagName: "json",
Result: &anyMap,
WeaklyTypedInput: true,
})
if err != nil {
return nil, err
}

err = dec.Decode(obj)
if err != nil {
return nil, err
}

ret := make(map[string]string)
for k, v := range anyMap {
val := reflect.ValueOf(v)
for val.Kind() == reflect.Ptr {
if val.IsNil() {
break
} else {
val = val.Elem()
}
}

if val.Kind() == reflect.Pointer {
ret[k] = ""
} else {
ret[k] = fmt.Sprintf("%v", val)
}
}

return ret, nil
}

+ 32
- 0
utils/http/http_test.go View File

@@ -0,0 +1,32 @@
package http

import (
"testing"

. "github.com/smartystreets/goconvey/convey"
)

func Test_objectToStringMap(t *testing.T) {
Convey("包含指针", t, func() {
type A struct {
Val *int `json:"Val,omitempty"`
Nil *int `json:"Nil,omitempty"`
Omit *int `json:"Omit"`
}

v := 10
a := A{
Val: &v,
Nil: nil,
Omit: nil,
}

mp, err := objectToStringMap(a)
So(err, ShouldBeNil)

So(mp, ShouldResemble, map[string]string{
"Val": "10",
"Omit": "",
})
})
}

+ 8
- 73
utils/serder/serder.go View File

@@ -6,9 +6,9 @@ import (
"fmt"
"io"
"reflect"
"strings"

jsoniter "github.com/json-iterator/go"
"github.com/mitchellh/mapstructure"
)

var unionHandler = UnionHandler{
@@ -163,78 +163,13 @@ func MapToObject(m map[string]any, obj any, opt ...MapToObjectOption) error {
}

func ObjectToMap(obj any) (map[string]any, error) {
ctx := WalkValue(obj, func(ctx *WalkContext, event WalkEvent) WalkingOp {
switch e := event.(type) {
case StructBeginEvent:
mp := make(map[string]any)
ctx.StackPush(mp)

case StructArriveFieldEvent:
if !WillWalkInto(e.Value) {
ctx.StackPush(e.Value.Interface())
}
case StructLeaveFieldEvent:
val := ctx.StackPop()
mp := ctx.StackPeek().(map[string]any)
jsonTag := e.Info.Tag.Get("json")
if jsonTag == "-" {
break
}

opts := strings.Split(jsonTag, ",")
keyName := opts[0]
if keyName == "" {
keyName = e.Info.Name
}

if contains(opts, "string", 1) {
val = fmt.Sprintf("%v", val)
}

mp[keyName] = val

case StructEndEvent:

case MapBeginEvent:
ctx.StackPush(make(map[string]any))
case MapArriveEntryEvent:
if !WillWalkInto(e.Value) {
ctx.StackPush(e.Value.Interface())
}
case MapLeaveEntryEvent:
val := ctx.StackPop()
mp := ctx.StackPeek().(map[string]any)
mp[fmt.Sprintf("%v", e.Key)] = val
case MapEndEvent:

case ArrayBeginEvent:
ctx.StackPush(make([]any, e.Value.Len()))
case ArrayArriveElementEvent:
if !WillWalkInto(e.Value) {
ctx.StackPush(e.Value.Interface())
}
case ArrayLeaveElementEvent:
val := ctx.StackPop()
arr := ctx.StackPeek().([]any)
arr[e.Index] = val
case ArrayEndEvent:
}

return Next

}, WalkOption{
StackValues: []any{make(map[string]any)},
mp := make(map[string]any)
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
TagName: "json",
Result: &mp,
})

return ctx.StackPop().(map[string]any), nil
}

func contains(arr []string, ele string, startIndex int) bool {
for i := startIndex; i < len(arr); i++ {
if arr[i] == ele {
return true
}
if err != nil {
return nil, err
}

return false
return mp, dec.Decode(obj)
}

Loading…
Cancel
Save