123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package http
- import (
- "context"
- "encoding/json"
- "encoding/xml"
- "io/ioutil"
- "net/http"
- "net/url"
- "strings"
- "git.chuangxin1.com/csacred/toolkit"
- )
- // DecodeRequestFunc extracts a user-domain request object from an HTTP
- // request object. It's designed to be used in HTTP servers, for server-side
- // endpoints. One straightforward DecodeRequestFunc could be something that
- // JSON decodes from the request body to the concrete response type.
- type DecodeRequestFunc func(context.Context, *http.Request) (request interface{}, err error)
- func header(w http.ResponseWriter, contentType string) {
- w.Header().Set(`Content-Type`, contentType)
- w.Header().Set(`X-Power`, toolkit.LibName+`/`+toolkit.LibVersion)
- w.WriteHeader(http.StatusOK)
- }
- // WriteJSON response JSON data.
- func WriteJSON(w http.ResponseWriter, response interface{}) error {
- header(w, `application/json; charset=utf-8`)
- return json.NewEncoder(w).Encode(response)
- }
- // WriteXML response XML data.
- func WriteXML(w http.ResponseWriter, response interface{}) error {
- header(w, `application/xml; charset=utf-8`)
- return xml.NewEncoder(w).Encode(response)
- }
- // WriteBytes response bytes
- func WriteBytes(w http.ResponseWriter, response interface{}) error {
- header(w, `text/html; charset=utf-8`)
- w.Write(response.([]byte))
- return nil
- }
- // WriteCtxJSON response JSON data.
- func WriteCtxJSON(ctx context.Context, w http.ResponseWriter, response interface{}) error {
- return WriteJSON(w, response)
- }
- // WriteCtxXML response XML data.
- func WriteCtxXML(ctx context.Context, w http.ResponseWriter, response interface{}) error {
- return WriteXML(w, response)
- }
- // WriteCtxBytes response text data.
- func WriteCtxBytes(ctx context.Context, w http.ResponseWriter, response interface{}) error {
- return WriteBytes(w, response)
- }
- // EncodeError request encode error response
- func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
- WriteJSON(w, toolkit.ErrReplyData(toolkit.ErrParamsError, err.Error()))
- }
- // EncodeXMLError request encode error response
- func EncodeXMLError(_ context.Context, err error, w http.ResponseWriter) {
- WriteXML(w, toolkit.ErrReplyData(toolkit.ErrParamsError, err.Error()))
- }
- // DecodeJSONResponse decode client
- func DecodeJSONResponse(ctx context.Context, r *http.Response) (interface{}, error) {
- var res toolkit.ReplyData
- if err := json.NewDecoder(r.Body).Decode(&res); err != nil {
- return toolkit.ErrReplyData(toolkit.ErrException, `data format error`), err
- }
- return res, nil
- }
- // DecodeXMLResponse decode client
- func DecodeXMLResponse(ctx context.Context, r *http.Response) (interface{}, error) {
- var res toolkit.ReplyData
- if err := xml.NewDecoder(r.Body).Decode(&res); err != nil {
- return toolkit.ErrReplyData(toolkit.ErrException, `data format error`), err
- }
- return res, nil
- }
- // DecodeBytesResponse decode client
- func DecodeBytesResponse(ctx context.Context, r *http.Response) (interface{}, error) {
- return ioutil.ReadAll(r.Body)
- }
- // PopulateRequestContext is a RequestFunc that populates several values into
- // the context from the HTTP request. Those values may be extracted using the
- // corresponding ContextKey type in this package.
- func PopulateRequestContext(ctx context.Context, r *http.Request) context.Context {
- var accessToken string
- accessToken = r.URL.Query().Get(toolkit.VarUserAuthorization)
- if accessToken == "" {
- if cookie, err := r.Cookie(toolkit.VarUserAuthorization); err == nil {
- accessToken, _ = url.QueryUnescape(cookie.Value)
- }
- }
- token := r.Header.Get(toolkit.HTTPHeaderAuthorization)
- if accessToken == "" {
- if len(token) > 6 && strings.ToUpper(token[0:7]) == "BEARER " {
- accessToken = token[7:]
- }
- }
- for k, v := range map[toolkit.ContextKey]string{
- toolkit.ContextKeyRequestMethod: r.Method,
- toolkit.ContextKeyRequestURI: r.RequestURI,
- toolkit.ContextKeyRequestPath: r.URL.Path,
- toolkit.ContextKeyRequestProto: r.Proto,
- toolkit.ContextKeyRequestHost: r.Host,
- toolkit.ContextKeyRequestRemoteAddr: r.RemoteAddr,
- toolkit.ContextKeyRequestXForwardedFor: r.Header.Get("X-Forwarded-For"),
- toolkit.ContextKeyRequestXForwardedProto: r.Header.Get("X-Forwarded-Proto"),
- toolkit.ContextKeyRequestAuthorization: token,
- toolkit.ContextKeyRequestReferer: r.Header.Get("Referer"),
- toolkit.ContextKeyRequestUserAgent: r.Header.Get("User-Agent"),
- toolkit.ContextKeyRequestXRequestID: r.Header.Get("X-Request-Id"),
- toolkit.ContextKeyRequestAccept: r.Header.Get("Accept"),
- toolkit.ContextKeyAccessToken: accessToken,
- } {
- //fmt.Println(k, v)
- ctx = context.WithValue(ctx, k, v)
- }
- return ctx
- }
|