marshal.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. package reflect
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "reflect"
  7. "strings"
  8. cnet "github.com/xtls/xray-core/common/net"
  9. cserial "github.com/xtls/xray-core/common/serial"
  10. "github.com/xtls/xray-core/infra/conf"
  11. )
  12. func MarshalToJson(v interface{}, insertTypeInfo bool) (string, bool) {
  13. if itf := marshalInterface(v, true, insertTypeInfo); itf != nil {
  14. if b, err := JSONMarshalWithoutEscape(itf); err == nil {
  15. return string(b[:]), true
  16. }
  17. }
  18. return "", false
  19. }
  20. func JSONMarshalWithoutEscape(t interface{}) ([]byte, error) {
  21. buffer := &bytes.Buffer{}
  22. encoder := json.NewEncoder(buffer)
  23. encoder.SetIndent("", " ")
  24. encoder.SetEscapeHTML(false)
  25. err := encoder.Encode(t)
  26. return buffer.Bytes(), err
  27. }
  28. func marshalTypedMessage(v *cserial.TypedMessage, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  29. if v == nil {
  30. return nil
  31. }
  32. tmsg, err := v.GetInstance()
  33. if err != nil {
  34. return nil
  35. }
  36. r := marshalInterface(tmsg, ignoreNullValue, insertTypeInfo)
  37. if msg, ok := r.(map[string]interface{}); ok && insertTypeInfo {
  38. msg["_TypedMessage_"] = v.Type
  39. }
  40. return r
  41. }
  42. func marshalSlice(v reflect.Value, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  43. r := make([]interface{}, 0)
  44. for i := 0; i < v.Len(); i++ {
  45. rv := v.Index(i)
  46. if rv.CanInterface() {
  47. value := rv.Interface()
  48. r = append(r, marshalInterface(value, ignoreNullValue, insertTypeInfo))
  49. }
  50. }
  51. return r
  52. }
  53. func isNullValue(f reflect.StructField, rv reflect.Value) bool {
  54. if rv.Kind() == reflect.String && rv.Len() == 0 {
  55. return true
  56. } else if !isValueKind(rv.Kind()) && rv.IsNil() {
  57. return true
  58. } else if tag := f.Tag.Get("json"); strings.Contains(tag, "omitempty") {
  59. if !rv.IsValid() || rv.IsZero() {
  60. return true
  61. }
  62. }
  63. return false
  64. }
  65. func toJsonName(f reflect.StructField) string {
  66. if tags := f.Tag.Get("protobuf"); len(tags) > 0 {
  67. for _, tag := range strings.Split(tags, ",") {
  68. if before, after, ok := strings.Cut(tag, "="); ok && before == "json" {
  69. return after
  70. }
  71. }
  72. }
  73. if tag := f.Tag.Get("json"); len(tag) > 0 {
  74. if before, _, ok := strings.Cut(tag, ","); ok {
  75. return before
  76. } else {
  77. return tag
  78. }
  79. }
  80. return f.Name
  81. }
  82. func marshalStruct(v reflect.Value, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  83. r := make(map[string]interface{})
  84. t := v.Type()
  85. for i := 0; i < v.NumField(); i++ {
  86. rv := v.Field(i)
  87. if rv.CanInterface() {
  88. ft := t.Field(i)
  89. if !ignoreNullValue || !isNullValue(ft, rv) {
  90. name := toJsonName(ft)
  91. value := rv.Interface()
  92. tv := marshalInterface(value, ignoreNullValue, insertTypeInfo)
  93. r[name] = tv
  94. }
  95. }
  96. }
  97. return r
  98. }
  99. func marshalMap(v reflect.Value, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  100. // policy.level is map[uint32] *struct
  101. kt := v.Type().Key()
  102. vt := reflect.TypeOf((*interface{})(nil))
  103. mt := reflect.MapOf(kt, vt)
  104. r := reflect.MakeMap(mt)
  105. for _, key := range v.MapKeys() {
  106. rv := v.MapIndex(key)
  107. if rv.CanInterface() {
  108. iv := rv.Interface()
  109. tv := marshalInterface(iv, ignoreNullValue, insertTypeInfo)
  110. if tv != nil || !ignoreNullValue {
  111. r.SetMapIndex(key, reflect.ValueOf(&tv))
  112. }
  113. }
  114. }
  115. return r.Interface()
  116. }
  117. func marshalIString(v interface{}) (r string, ok bool) {
  118. defer func() {
  119. if err := recover(); err != nil {
  120. r = ""
  121. ok = false
  122. }
  123. }()
  124. if iStringFn, ok := v.(interface{ String() string }); ok {
  125. return iStringFn.String(), true
  126. }
  127. return "", false
  128. }
  129. func serializePortList(portList *cnet.PortList) (interface{}, bool) {
  130. if portList == nil {
  131. return nil, false
  132. }
  133. n := len(portList.Range)
  134. if n == 1 {
  135. if first := portList.Range[0]; first.From == first.To {
  136. return first.From, true
  137. }
  138. }
  139. r := make([]string, 0, n)
  140. for _, pr := range portList.Range {
  141. if pr.From == pr.To {
  142. r = append(r, pr.FromPort().String())
  143. } else {
  144. r = append(r, fmt.Sprintf("%d-%d", pr.From, pr.To))
  145. }
  146. }
  147. return strings.Join(r, ","), true
  148. }
  149. func marshalKnownType(v interface{}, ignoreNullValue bool, insertTypeInfo bool) (interface{}, bool) {
  150. switch ty := v.(type) {
  151. case cserial.TypedMessage:
  152. return marshalTypedMessage(&ty, ignoreNullValue, insertTypeInfo), true
  153. case *cserial.TypedMessage:
  154. return marshalTypedMessage(ty, ignoreNullValue, insertTypeInfo), true
  155. case map[string]json.RawMessage:
  156. return ty, true
  157. case []json.RawMessage:
  158. return ty, true
  159. case *json.RawMessage, json.RawMessage:
  160. return ty, true
  161. case *cnet.IPOrDomain:
  162. if domain := v.(*cnet.IPOrDomain); domain != nil {
  163. return domain.AsAddress().String(), true
  164. }
  165. return nil, false
  166. case *cnet.PortList:
  167. npl := v.(*cnet.PortList)
  168. return serializePortList(npl)
  169. case *conf.PortList:
  170. cpl := v.(*conf.PortList)
  171. return serializePortList(cpl.Build())
  172. case cnet.Address:
  173. if addr := v.(cnet.Address); addr != nil {
  174. return addr.String(), true
  175. }
  176. return nil, false
  177. default:
  178. return nil, false
  179. }
  180. }
  181. func isValueKind(kind reflect.Kind) bool {
  182. switch kind {
  183. case reflect.Bool,
  184. reflect.Int,
  185. reflect.Int8,
  186. reflect.Int16,
  187. reflect.Int32,
  188. reflect.Int64,
  189. reflect.Uint,
  190. reflect.Uint8,
  191. reflect.Uint16,
  192. reflect.Uint32,
  193. reflect.Uint64,
  194. reflect.Uintptr,
  195. reflect.Float32,
  196. reflect.Float64,
  197. reflect.Complex64,
  198. reflect.Complex128,
  199. reflect.String:
  200. return true
  201. default:
  202. return false
  203. }
  204. }
  205. func marshalInterface(v interface{}, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  206. if r, ok := marshalKnownType(v, ignoreNullValue, insertTypeInfo); ok {
  207. return r
  208. }
  209. rv := reflect.ValueOf(v)
  210. if rv.Kind() == reflect.Ptr {
  211. rv = rv.Elem()
  212. }
  213. k := rv.Kind()
  214. if k == reflect.Invalid {
  215. return nil
  216. }
  217. if ty := rv.Type().Name(); isValueKind(k) {
  218. if k.String() != ty {
  219. if s, ok := marshalIString(v); ok {
  220. return s
  221. }
  222. }
  223. return v
  224. }
  225. // fmt.Println("kind:", k, "type:", rv.Type().Name())
  226. switch k {
  227. case reflect.Struct:
  228. return marshalStruct(rv, ignoreNullValue, insertTypeInfo)
  229. case reflect.Slice:
  230. return marshalSlice(rv, ignoreNullValue, insertTypeInfo)
  231. case reflect.Array:
  232. return marshalSlice(rv, ignoreNullValue, insertTypeInfo)
  233. case reflect.Map:
  234. return marshalMap(rv, ignoreNullValue, insertTypeInfo)
  235. default:
  236. break
  237. }
  238. if str, ok := marshalIString(v); ok {
  239. return str
  240. }
  241. return nil
  242. }