| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package http
- import (
- "net/http"
- "strings"
- "github.com/go-kratos/kratos/v2/encoding"
- "github.com/go-kratos/kratos/v2/errors"
- "git.ikuban.com/server/kratos-utils/http/encoding/jsonpb"
- _ "github.com/go-kratos/kratos/v2/transport"
- )
- 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 < 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(jsonpb.Name)
- break
- }
- if codec = encoding.GetCodec(codeName); codec != nil {
- break
- }
- }
- if codec == nil {
- codec = encoding.GetCodec(jsonpb.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 ""
- }
- }
|