response.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package http
  2. import (
  3. "context"
  4. "encoding/json"
  5. "encoding/xml"
  6. "io/ioutil"
  7. "net/http"
  8. "net/url"
  9. "strings"
  10. "git.chuangxin1.com/csacred/toolkit"
  11. )
  12. // DecodeRequestFunc extracts a user-domain request object from an HTTP
  13. // request object. It's designed to be used in HTTP servers, for server-side
  14. // endpoints. One straightforward DecodeRequestFunc could be something that
  15. // JSON decodes from the request body to the concrete response type.
  16. type DecodeRequestFunc func(context.Context, *http.Request) (request interface{}, err error)
  17. func header(w http.ResponseWriter, contentType string) {
  18. w.Header().Set(`Content-Type`, contentType)
  19. w.Header().Set(`X-Power`, toolkit.LibName+`/`+toolkit.LibVersion)
  20. w.WriteHeader(http.StatusOK)
  21. }
  22. // WriteJSON response JSON data.
  23. func WriteJSON(w http.ResponseWriter, response interface{}) error {
  24. header(w, `application/json; charset=utf-8`)
  25. return json.NewEncoder(w).Encode(response)
  26. }
  27. // WriteXML response XML data.
  28. func WriteXML(w http.ResponseWriter, response interface{}) error {
  29. header(w, `application/xml; charset=utf-8`)
  30. return xml.NewEncoder(w).Encode(response)
  31. }
  32. // WriteBytes response bytes
  33. func WriteBytes(w http.ResponseWriter, response interface{}) error {
  34. header(w, `text/html; charset=utf-8`)
  35. w.Write(response.([]byte))
  36. return nil
  37. }
  38. // WriteCtxJSON response JSON data.
  39. func WriteCtxJSON(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  40. return WriteJSON(w, response)
  41. }
  42. // WriteCtxXML response XML data.
  43. func WriteCtxXML(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  44. return WriteXML(w, response)
  45. }
  46. // WriteCtxBytes response text data.
  47. func WriteCtxBytes(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  48. return WriteBytes(w, response)
  49. }
  50. // EncodeError request encode error response
  51. func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
  52. WriteJSON(w, toolkit.ErrReplyData(toolkit.ErrParamsError, err.Error()))
  53. }
  54. // EncodeXMLError request encode error response
  55. func EncodeXMLError(_ context.Context, err error, w http.ResponseWriter) {
  56. WriteXML(w, toolkit.ErrReplyData(toolkit.ErrParamsError, err.Error()))
  57. }
  58. // DecodeJSONResponse decode client
  59. func DecodeJSONResponse(ctx context.Context, r *http.Response) (interface{}, error) {
  60. var res toolkit.ReplyData
  61. if err := json.NewDecoder(r.Body).Decode(&res); err != nil {
  62. return toolkit.ErrReplyData(toolkit.ErrException, `data format error`), err
  63. }
  64. return res, nil
  65. }
  66. // DecodeXMLResponse decode client
  67. func DecodeXMLResponse(ctx context.Context, r *http.Response) (interface{}, error) {
  68. var res toolkit.ReplyData
  69. if err := xml.NewDecoder(r.Body).Decode(&res); err != nil {
  70. return toolkit.ErrReplyData(toolkit.ErrException, `data format error`), err
  71. }
  72. return res, nil
  73. }
  74. // DecodeBytesResponse decode client
  75. func DecodeBytesResponse(ctx context.Context, r *http.Response) (interface{}, error) {
  76. return ioutil.ReadAll(r.Body)
  77. }
  78. // PopulateRequestContext is a RequestFunc that populates several values into
  79. // the context from the HTTP request. Those values may be extracted using the
  80. // corresponding ContextKey type in this package.
  81. func PopulateRequestContext(ctx context.Context, r *http.Request) context.Context {
  82. var accessToken string
  83. accessToken = r.URL.Query().Get(toolkit.VarUserAuthorization)
  84. if accessToken == "" {
  85. if cookie, err := r.Cookie(toolkit.VarUserAuthorization); err == nil {
  86. accessToken, _ = url.QueryUnescape(cookie.Value)
  87. }
  88. }
  89. token := r.Header.Get(toolkit.HTTPHeaderAuthorization)
  90. if accessToken == "" {
  91. if len(token) > 6 && strings.ToUpper(token[0:7]) == "BEARER " {
  92. accessToken = token[7:]
  93. }
  94. }
  95. for k, v := range map[toolkit.ContextKey]string{
  96. toolkit.ContextKeyRequestMethod: r.Method,
  97. toolkit.ContextKeyRequestURI: r.RequestURI,
  98. toolkit.ContextKeyRequestPath: r.URL.Path,
  99. toolkit.ContextKeyRequestProto: r.Proto,
  100. toolkit.ContextKeyRequestHost: r.Host,
  101. toolkit.ContextKeyRequestRemoteAddr: r.RemoteAddr,
  102. toolkit.ContextKeyRequestXForwardedFor: r.Header.Get("X-Forwarded-For"),
  103. toolkit.ContextKeyRequestXForwardedProto: r.Header.Get("X-Forwarded-Proto"),
  104. toolkit.ContextKeyRequestAuthorization: token,
  105. toolkit.ContextKeyRequestReferer: r.Header.Get("Referer"),
  106. toolkit.ContextKeyRequestUserAgent: r.Header.Get("User-Agent"),
  107. toolkit.ContextKeyRequestXRequestID: r.Header.Get("X-Request-Id"),
  108. toolkit.ContextKeyRequestAccept: r.Header.Get("Accept"),
  109. toolkit.ContextKeyAccessToken: accessToken,
  110. } {
  111. //fmt.Println(k, v)
  112. ctx = context.WithValue(ctx, k, v)
  113. }
  114. return ctx
  115. }