| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- package http
- import (
- "net/http"
- "strings"
- "github.com/go-kratos/kratos/v2/encoding"
- "github.com/go-kratos/kratos/v2/encoding/json"
- "github.com/go-kratos/kratos/v2/errors"
- _ "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] {
- if codec = encoding.GetCodec(contentSubtype(accept)); 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 ""
- }
- }
|