| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package http
- import (
- "net/http"
- "strings"
- "github.com/go-kratos/kratos/v2/errors"
- "github.com/go-kratos/kratos/v2/encoding/json"
- "google.golang.org/grpc/encoding"
- )
- func ErrHandle(w http.ResponseWriter, r *http.Request, err error) {
- se, ok := errors.FromError(err)
- if !ok {
- se = &errors.StatusError{
- Code: 2,
- Message: err.Error(),
- }
- }
- codec := codecForRequest(r)
- data, _ := codec.Marshal(se)
- w.Header().Set(ContentTypeHeader, contentType(codec.Name()))
- w.WriteHeader(200)
- _, _ = 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 ""
- }
- }
|