| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- package http
- import (
- "net/http"
- "strings"
- "github.com/go-kratos/kratos/v2/encoding"
- "github.com/go-kratos/kratos/v2/errors"
- "github.com/go-kratos/kratos/v2/encoding/json"
- _ "github.com/go-kratos/kratos/v2/encoding/proto"
- )
- // decodeRequest decodes the request body to object.
- //func DecodeRequest(req *http.Request, v interface{}) error {
- // method := strings.ToUpper(req.Method)
- // if method == "POST" || method == "PUT" || method == "DELETE" {
- // if _, ok := v.(*emptypb.Empty); ok {
- // return binding.BindForm(req, v)
- // }
- // subtype := contentSubtype(req.Header.Get(ContentTypeHeader))
- // if codec := encoding.GetCodec(subtype); codec != nil {
- // data, err := ioutil.ReadAll(req.Body)
- // if err != nil {
- // return err
- // }
- // return codec.Unmarshal(data, v)
- // }
- // }
- // return binding.BindForm(req, v)
- //}
- func ErrHandle(w http.ResponseWriter, r *http.Request, err error) {
- se, ok := errors.FromError(err)
- if !ok {
- se = &errors.StatusError{
- Code: 10500,
- Message: err.Error(),
- }
- }
- if se.Code == -1 {
- return
- }
- codec := codecForRequest(r)
- w.Header().Set(ContentTypeHeader, contentType(codec.Name()))
- if se.Code == 0 {
- w.WriteHeader(200)
- } else if se.Code >= 302 && se.Code <= 303 {
- w.WriteHeader(int(se.Code))
- http.Redirect(w, r, se.Message, int(se.Code))
- return
- } else {
- if se.Code < 10000 {
- se.Code = 10000 + se.Code
- }
- if se.Code < 10100 && se.Message == "" {
- se.Message = "系统错误"
- }
- w.WriteHeader(400)
- }
- data, _ := codec.Marshal(se)
- _, _ = w.Write(data)
- }
- const baseContentType = "application"
- var (
- acceptHeader = http.CanonicalHeaderKey("Accept")
- ContentTypeHeader = http.CanonicalHeaderKey("Content-Type")
- )
- func contentType(subtype string) string {
- return strings.Join([]string{baseContentType, subtype}, "/")
- }
- // codecForRequest get encoding.Codec via http.Request
- func codecForRequest(r *http.Request) encoding.Codec {
- var codec encoding.Codec
- for _, accept := range r.Header[acceptHeader] {
- codeName := contentSubtype(accept)
- if codeName == "json" {
- codec = encoding.GetCodec(json.Name)
- break
- }
- if codec = encoding.GetCodec(codeName); codec != nil {
- break
- }
- }
- if codec == nil {
- codec = encoding.GetCodec(json.Name)
- }
- return codec
- }
- func contentSubtype(contentType string) string {
- if contentType == baseContentType {
- return ""
- }
- if !strings.HasPrefix(contentType, baseContentType) {
- return ""
- }
- switch contentType[len(baseContentType)] {
- case '/', ';':
- if i := strings.Index(contentType, ";"); i != -1 {
- return contentType[len(baseContentType)+1 : i]
- }
- return contentType[len(baseContentType)+1:]
- default:
- return ""
- }
- }
|