123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- package server
- import (
- "bytes"
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "net/url"
- "os"
- "reflect"
- "strconv"
- "strings"
- httptransport "github.com/go-kit/kit/transport/http"
- )
- func (err Response) Error() string {
- b, _ := json.Marshal(err)
- return string(b)
- }
- func validateAPIToken(r *http.Request, clientid string) (interface{}, error) {
- //验证token是否有效
- headerAuth := r.Header.Get("Authorization")
- authArr := strings.Split(headerAuth, " ")
- if len(authArr) != 2 {
- return nil, Response{
- Errno: 1003,
- Errmsg: "auth failed",
- }
- }
- if authArr[0] != "Bearer" {
- return nil, Response{
- Errno: 1004,
- Errmsg: "wrong auth method",
- }
- }
- if err := ValidateToken(authArr[1], clientid); err != nil {
- return nil, Response{
- Errno: 1005,
- Errmsg: err.Error(),
- }
- }
- return nil, nil
- }
- func touchSessionToken(r *http.Request) {
- sessionId := r.Header.Get("SESSIONID")
- if sessionId != "" {
- go func() {
- _, err := TouchSessionToken(sessionId)
- if err != nil {
- log.Println(err)
- }
- }()
- }
- }
- // DecodeRequest decodes the request from the provided HTTP request, simply
- // by JSON decoding from the request body. It's designed to be used in
- // transport/http.Server.
- func DecodeRequest(r *http.Request, ptype reflect.Type, shouldLogin ...bool) (interface{}, error) {
- var pl interface{}
- if ptype == nil {
- pl = make(map[string]interface{})
- } else {
- pl = reflect.New(ptype).Interface()
- }
- var reqItem = Request{
- Payload: pl,
- }
- //TODO 优化reader sync.Pool
- buf, _ := ioutil.ReadAll(r.Body)
- log.Println(r.RequestURI, string(buf))
- err := json.NewDecoder(bytes.NewReader(buf)).Decode(&reqItem)
- if err != nil {
- return nil, Response{
- Errno: 101,
- Errmsg: err.Error(), //"wrong json fromat",
- }
- }
- //attach defualt wx_type
- if reqItem.Extra == nil {
- reqItem.Extra = map[string]interface{}{}
- }
- if _, ok := reqItem.Extra["wx_type"]; !ok {
- reqItem.Extra["wx_type"] = ""
- }
- if reqItem.ClientId == "" {
- return nil, Response{
- Errno: 100,
- Errmsg: "param clientid required",
- }
- }
- //验证token是否有效
- _, err = validateAPIToken(r, reqItem.ClientId)
- if err != nil {
- return nil, err
- }
- /*headerAuth := r.Header.Get("Authorization")
- authArr := strings.Split(headerAuth, " ")
- if len(authArr) != 2 {
- return nil, Response{
- Errno: 1003,
- Errmsg: "auth failed",
- }
- }
- if authArr[0] != "Bearer" {
- return nil, Response{
- Errno: 1004,
- Errmsg: "wrong auth method",
- }
- }
- if err := ValidateToken(authArr[1]); err != nil {
- return nil, Response{
- Errno: 1005,
- Errmsg: err.Error(),
- }
- }*/
- //根据sessionid 判断若用户已经登录,则刷新登录token
- //touchSessionToken(r)
- //判断是否需要登录
- if len(shouldLogin) > 0 && shouldLogin[0] {
- //验证是否已经登录
- sessionId := r.Header.Get("SESSIONID")
- if sessionId == "" {
- return nil, Response{
- Errno: 1006,
- Errmsg: "miss session param",
- }
- }
- stoken, err := GetLoginSession(sessionId)
- if err != nil {
- return nil, Response{
- Errno: 1007,
- Errmsg: "user should login",
- }
- }
- udata := stoken.Data.(string)
- udatas := strings.Split(udata, "-")
- if len(udatas) >= 2 {
- uid, _ := strconv.ParseInt(udatas[0], 10, 0)
- reqItem.UserId = int(uid)
- fmt.Println(udata, reqItem.UserId)
- reqItem.Mobile = udatas[1]
- }
- }
- return reqItem, err
- }
- // EncodeResponse encodes the response to the provided HTTP response
- // writer, simply by JSON encoding to the writer. It's designed to be used in
- // transport/http.Server.
- func EncodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
- w.Header().Set("Content-Type", "application/json; charset=utf-8")
- wr := io.MultiWriter(w, os.Stdout)
- jencoder := json.NewEncoder(wr)
- jencoder.SetEscapeHTML(false)
- return jencoder.Encode(response)
- }
- // 20220719 不打印日志,部分信息并没有太大意义。免得日志文件增长过快
- func EncodeResponseNoLog(ctx context.Context, w http.ResponseWriter, response interface{}) error {
- w.Header().Set("Content-Type", "application/json; charset=utf-8")
- //wr := io.MultiWriter(w, os.Stdout)
- jencoder := json.NewEncoder(w)
- jencoder.SetEscapeHTML(false)
- return jencoder.Encode(response)
- }
- func MakeDecodeRequest(ptype reflect.Type, shouldLogin ...bool) httptransport.DecodeRequestFunc {
- return func(ctx context.Context, r *http.Request) (interface{}, error) {
- return DecodeRequest(r, ptype, shouldLogin...)
- }
- }
- // EncodeRequest encodes the request to the provided HTTP request, simply
- // by JSON encoding to the request body. It's designed to be used in
- // transport/http.Client.
- func EncodeRequest(r *http.Request, request interface{}) error {
- var buf bytes.Buffer
- if err := json.NewEncoder(&buf).Encode(request); err != nil {
- return err
- }
- r.Body = ioutil.NopCloser(&buf)
- return nil
- }
- // DecodeResponse decodes the response from the provided HTTP response,
- // simply by JSON decoding from the response body. It's designed to be used in
- // transport/http.Client.
- func DecodeResponse(resp *http.Response, payload interface{}) (interface{}, error) {
- return nil, nil
- }
- func DecodeAuthRequest(ctx context.Context, req *http.Request) (interface{}, error) {
- rbytes, err := ioutil.ReadAll(req.Body)
- if err != nil {
- return nil, err
- }
- strReqData := string(rbytes)
- kv, err := url.ParseQuery(strReqData)
- if err != nil {
- return nil, err
- }
- tokenStr := kv.Get("assertion")
- if tokenStr == "" {
- return nil, errors.New("request auth data not found")
- }
- return tokenStr, nil
- }
- func DecodeFileRequest(ctx context.Context, req *http.Request) (interface{}, error) {
- touchSessionToken(req)
- clientId := req.Header.Get("clientid")
- if clientId == "" {
- return nil, Response{
- Errno: 100,
- Errmsg: "param clientid required",
- }
- }
- _, err := validateAPIToken(req, clientId)
- if err != nil {
- return nil, err
- }
- req.ParseForm()
- file, _, _ := req.FormFile("file")
- return file, nil
- }
|