marshal.go 6.1 KB

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