encode_decode.go 5.8 KB

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