marshal.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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.Struct {
  55. return false
  56. } else if rv.Kind() == reflect.String && rv.Len() == 0 {
  57. return true
  58. } else if !isValueKind(rv.Kind()) && rv.IsNil() {
  59. return true
  60. } else if tag := f.Tag.Get("json"); strings.Contains(tag, "omitempty") {
  61. if !rv.IsValid() || rv.IsZero() {
  62. return true
  63. }
  64. }
  65. return false
  66. }
  67. func toJsonName(f reflect.StructField) string {
  68. if tags := f.Tag.Get("protobuf"); len(tags) > 0 {
  69. for _, tag := range strings.Split(tags, ",") {
  70. if before, after, ok := strings.Cut(tag, "="); ok && before == "json" {
  71. return after
  72. }
  73. }
  74. }
  75. if tag := f.Tag.Get("json"); len(tag) > 0 {
  76. if before, _, ok := strings.Cut(tag, ","); ok {
  77. return before
  78. } else {
  79. return tag
  80. }
  81. }
  82. return f.Name
  83. }
  84. func marshalStruct(v reflect.Value, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  85. r := make(map[string]interface{})
  86. t := v.Type()
  87. for i := 0; i < v.NumField(); i++ {
  88. rv := v.Field(i)
  89. if rv.CanInterface() {
  90. ft := t.Field(i)
  91. if !ignoreNullValue || !isNullValue(ft, rv) {
  92. name := toJsonName(ft)
  93. value := rv.Interface()
  94. tv := marshalInterface(value, ignoreNullValue, insertTypeInfo)
  95. r[name] = tv
  96. }
  97. }
  98. }
  99. return r
  100. }
  101. func marshalMap(v reflect.Value, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  102. // policy.level is map[uint32] *struct
  103. kt := v.Type().Key()
  104. vt := reflect.TypeOf((*interface{})(nil))
  105. mt := reflect.MapOf(kt, vt)
  106. r := reflect.MakeMap(mt)
  107. for _, key := range v.MapKeys() {
  108. rv := v.MapIndex(key)
  109. if rv.CanInterface() {
  110. iv := rv.Interface()
  111. tv := marshalInterface(iv, ignoreNullValue, insertTypeInfo)
  112. if tv != nil || !ignoreNullValue {
  113. r.SetMapIndex(key, reflect.ValueOf(&tv))
  114. }
  115. }
  116. }
  117. return r.Interface()
  118. }
  119. func marshalIString(v interface{}) (r string, ok bool) {
  120. defer func() {
  121. if err := recover(); err != nil {
  122. r = ""
  123. ok = false
  124. }
  125. }()
  126. if iStringFn, ok := v.(interface{ String() string }); ok {
  127. return iStringFn.String(), true
  128. }
  129. return "", false
  130. }
  131. func serializePortList(portList *cnet.PortList) (interface{}, bool) {
  132. if portList == nil {
  133. return nil, false
  134. }
  135. n := len(portList.Range)
  136. if n == 1 {
  137. if first := portList.Range[0]; first.From == first.To {
  138. return first.From, true
  139. }
  140. }
  141. r := make([]string, 0, n)
  142. for _, pr := range portList.Range {
  143. if pr.From == pr.To {
  144. r = append(r, pr.FromPort().String())
  145. } else {
  146. r = append(r, fmt.Sprintf("%d-%d", pr.From, pr.To))
  147. }
  148. }
  149. return strings.Join(r, ","), true
  150. }
  151. func marshalKnownType(v interface{}, ignoreNullValue bool, insertTypeInfo bool) (interface{}, bool) {
  152. switch ty := v.(type) {
  153. case cserial.TypedMessage:
  154. return marshalTypedMessage(&ty, ignoreNullValue, insertTypeInfo), true
  155. case *cserial.TypedMessage:
  156. return marshalTypedMessage(ty, ignoreNullValue, insertTypeInfo), true
  157. case map[string]json.RawMessage:
  158. return ty, true
  159. case []json.RawMessage:
  160. return ty, true
  161. case *json.RawMessage, json.RawMessage:
  162. return ty, true
  163. case *cnet.IPOrDomain:
  164. if domain := v.(*cnet.IPOrDomain); domain != nil {
  165. return domain.AsAddress().String(), true
  166. }
  167. return nil, false
  168. case *cnet.PortList:
  169. npl := v.(*cnet.PortList)
  170. return serializePortList(npl)
  171. case *conf.PortList:
  172. cpl := v.(*conf.PortList)
  173. return serializePortList(cpl.Build())
  174. case conf.Int32Range:
  175. i32rng := v.(conf.Int32Range)
  176. if i32rng.Left == i32rng.Right {
  177. return i32rng.Left, true
  178. }
  179. return i32rng.String(), true
  180. case cnet.Address:
  181. if addr := v.(cnet.Address); addr != nil {
  182. return addr.String(), true
  183. }
  184. return nil, false
  185. default:
  186. return nil, false
  187. }
  188. }
  189. func isValueKind(kind reflect.Kind) bool {
  190. switch kind {
  191. case reflect.Bool,
  192. reflect.Int,
  193. reflect.Int8,
  194. reflect.Int16,
  195. reflect.Int32,
  196. reflect.Int64,
  197. reflect.Uint,
  198. reflect.Uint8,
  199. reflect.Uint16,
  200. reflect.Uint32,
  201. reflect.Uint64,
  202. reflect.Uintptr,
  203. reflect.Float32,
  204. reflect.Float64,
  205. reflect.Complex64,
  206. reflect.Complex128,
  207. reflect.String:
  208. return true
  209. default:
  210. return false
  211. }
  212. }
  213. func marshalInterface(v interface{}, ignoreNullValue bool, insertTypeInfo bool) interface{} {
  214. if r, ok := marshalKnownType(v, ignoreNullValue, insertTypeInfo); ok {
  215. return r
  216. }
  217. rv := reflect.ValueOf(v)
  218. if rv.Kind() == reflect.Ptr {
  219. rv = rv.Elem()
  220. }
  221. k := rv.Kind()
  222. if k == reflect.Invalid {
  223. return nil
  224. }
  225. if ty := rv.Type().Name(); isValueKind(k) {
  226. if k.String() != ty {
  227. if s, ok := marshalIString(v); ok {
  228. return s
  229. }
  230. }
  231. return v
  232. }
  233. // fmt.Println("kind:", k, "type:", rv.Type().Name())
  234. switch k {
  235. case reflect.Struct:
  236. return marshalStruct(rv, ignoreNullValue, insertTypeInfo)
  237. case reflect.Slice:
  238. return marshalSlice(rv, ignoreNullValue, insertTypeInfo)
  239. case reflect.Array:
  240. return marshalSlice(rv, ignoreNullValue, insertTypeInfo)
  241. case reflect.Map:
  242. return marshalMap(rv, ignoreNullValue, insertTypeInfo)
  243. default:
  244. break
  245. }
  246. if str, ok := marshalIString(v); ok {
  247. return str
  248. }
  249. return nil
  250. }