encode_decode.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package server
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "log"
  11. "net/http"
  12. "net/url"
  13. "os"
  14. "reflect"
  15. "strconv"
  16. "strings"
  17. httptransport "github.com/go-kit/kit/transport/http"
  18. )
  19. func (err Response) Error() string {
  20. b, _ := json.Marshal(err)
  21. return string(b)
  22. }
  23. func validateAPIToken(r *http.Request, clientid string) (interface{}, error) {
  24. //验证token是否有效
  25. headerAuth := r.Header.Get("Authorization")
  26. authArr := strings.Split(headerAuth, " ")
  27. if len(authArr) != 2 {
  28. return nil, Response{
  29. Errno: 1003,
  30. Errmsg: "auth failed",
  31. }
  32. }
  33. if authArr[0] != "Bearer" {
  34. return nil, Response{
  35. Errno: 1004,
  36. Errmsg: "wrong auth method",
  37. }
  38. }
  39. if err := ValidateToken(authArr[1], clientid); err != nil {
  40. return nil, Response{
  41. Errno: 1005,
  42. Errmsg: err.Error(),
  43. }
  44. }
  45. return nil, nil
  46. }
  47. func touchSessionToken(r *http.Request) {
  48. sessionId := r.Header.Get("SESSIONID")
  49. if sessionId != "" {
  50. go func() {
  51. _, err := TouchSessionToken(sessionId)
  52. if err != nil {
  53. log.Println(err)
  54. }
  55. }()
  56. }
  57. }
  58. // DecodeRequest decodes the request from the provided HTTP request, simply
  59. // by JSON decoding from the request body. It's designed to be used in
  60. // transport/http.Server.
  61. func DecodeRequest(r *http.Request, ptype reflect.Type, shouldLogin ...bool) (interface{}, error) {
  62. if len(shouldLogin) > 0 {
  63. shouldLogin[0] = false
  64. }
  65. var pl interface{}
  66. if ptype == nil {
  67. pl = make(map[string]interface{})
  68. } else {
  69. pl = reflect.New(ptype).Interface()
  70. }
  71. var reqItem = Request{
  72. Payload: pl,
  73. }
  74. //TODO 优化reader sync.Pool
  75. buf, _ := ioutil.ReadAll(r.Body)
  76. log.Println(r.RequestURI, string(buf))
  77. err := json.NewDecoder(bytes.NewReader(buf)).Decode(&reqItem)
  78. if err != nil {
  79. return nil, Response{
  80. Errno: 101,
  81. Errmsg: err.Error(), //"wrong json fromat",
  82. }
  83. }
  84. //attach defualt wx_type
  85. if reqItem.Extra == nil {
  86. reqItem.Extra = map[string]interface{}{}
  87. }
  88. if _, ok := reqItem.Extra["wx_type"]; !ok {
  89. reqItem.Extra["wx_type"] = ""
  90. }
  91. if reqItem.ClientId == "" {
  92. return nil, Response{
  93. Errno: 100,
  94. Errmsg: "param clientid required",
  95. }
  96. }
  97. //验证token是否有效
  98. //_, err = validateAPIToken(r, reqItem.ClientId)
  99. if err != nil {
  100. return nil, err
  101. }
  102. /*headerAuth := r.Header.Get("Authorization")
  103. authArr := strings.Split(headerAuth, " ")
  104. if len(authArr) != 2 {
  105. return nil, Response{
  106. Errno: 1003,
  107. Errmsg: "auth failed",
  108. }
  109. }
  110. if authArr[0] != "Bearer" {
  111. return nil, Response{
  112. Errno: 1004,
  113. Errmsg: "wrong auth method",
  114. }
  115. }
  116. if err := ValidateToken(authArr[1]); err != nil {
  117. return nil, Response{
  118. Errno: 1005,
  119. Errmsg: err.Error(),
  120. }
  121. }*/
  122. //根据sessionid 判断若用户已经登录,则刷新登录token
  123. //touchSessionToken(r)
  124. //判断是否需要登录
  125. if len(shouldLogin) > 0 && shouldLogin[0] {
  126. //验证是否已经登录
  127. sessionId := r.Header.Get("SESSIONID")
  128. if sessionId == "" {
  129. return nil, Response{
  130. Errno: 1006,
  131. Errmsg: "miss session param",
  132. }
  133. }
  134. stoken, err := GetLoginSession(sessionId)
  135. if err != nil {
  136. return nil, Response{
  137. Errno: 1007,
  138. Errmsg: "user should login",
  139. }
  140. }
  141. udata := stoken.Data.(string)
  142. udatas := strings.Split(udata, "-")
  143. if len(udatas) >= 2 {
  144. uid, _ := strconv.ParseInt(udatas[0], 10, 0)
  145. reqItem.UserId = int(uid)
  146. fmt.Println(udata, reqItem.UserId)
  147. reqItem.Mobile = udatas[1]
  148. }
  149. }
  150. reqItem.Mobile = "13141018539"
  151. return reqItem, err
  152. }
  153. // EncodeResponse encodes the response to the provided HTTP response
  154. // writer, simply by JSON encoding to the writer. It's designed to be used in
  155. // transport/http.Server.
  156. func EncodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  157. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  158. wr := io.MultiWriter(w, os.Stdout)
  159. jencoder := json.NewEncoder(wr)
  160. jencoder.SetEscapeHTML(false)
  161. return jencoder.Encode(response)
  162. }
  163. //20220719 不打印日志,部分信息并没有太大意义。免得日志文件增长过快
  164. func EncodeResponseNoLog(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  165. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  166. //wr := io.MultiWriter(w, os.Stdout)
  167. jencoder := json.NewEncoder(w)
  168. jencoder.SetEscapeHTML(false)
  169. return jencoder.Encode(response)
  170. }
  171. func MakeDecodeRequest(ptype reflect.Type, shouldLogin ...bool) httptransport.DecodeRequestFunc {
  172. return func(ctx context.Context, r *http.Request) (interface{}, error) {
  173. return DecodeRequest(r, ptype, shouldLogin...)
  174. }
  175. }
  176. // EncodeRequest encodes the request to the provided HTTP request, simply
  177. // by JSON encoding to the request body. It's designed to be used in
  178. // transport/http.Client.
  179. func EncodeRequest(r *http.Request, request interface{}) error {
  180. var buf bytes.Buffer
  181. if err := json.NewEncoder(&buf).Encode(request); err != nil {
  182. return err
  183. }
  184. r.Body = ioutil.NopCloser(&buf)
  185. return nil
  186. }
  187. // DecodeResponse decodes the response from the provided HTTP response,
  188. // simply by JSON decoding from the response body. It's designed to be used in
  189. // transport/http.Client.
  190. func DecodeResponse(resp *http.Response, payload interface{}) (interface{}, error) {
  191. return nil, nil
  192. }
  193. func DecodeAuthRequest(ctx context.Context, req *http.Request) (interface{}, error) {
  194. rbytes, err := ioutil.ReadAll(req.Body)
  195. if err != nil {
  196. return nil, err
  197. }
  198. strReqData := string(rbytes)
  199. kv, err := url.ParseQuery(strReqData)
  200. if err != nil {
  201. return nil, err
  202. }
  203. tokenStr := kv.Get("assertion")
  204. if tokenStr == "" {
  205. return nil, errors.New("request auth data not found")
  206. }
  207. return tokenStr, nil
  208. }
  209. func DecodeFileRequest(ctx context.Context, req *http.Request) (interface{}, error) {
  210. touchSessionToken(req)
  211. clientId := req.Header.Get("clientid")
  212. if clientId == "" {
  213. return nil, Response{
  214. Errno: 100,
  215. Errmsg: "param clientid required",
  216. }
  217. }
  218. _, err := validateAPIToken(req, clientId)
  219. if err != nil {
  220. return nil, err
  221. }
  222. req.ParseForm()
  223. file, _, _ := req.FormFile("file")
  224. return file, nil
  225. }