handle.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package http
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. "github.com/go-kratos/kratos/v2/encoding"
  7. "github.com/go-kratos/kratos/v2/encoding/json"
  8. "github.com/go-kratos/kratos/v2/errors"
  9. _ "github.com/go-kratos/kratos/v2/transport"
  10. )
  11. func ErrHandle(w http.ResponseWriter, r *http.Request, err error) {
  12. se, ok := errors.FromError(err)
  13. if !ok {
  14. se = &errors.StatusError{
  15. Code: 2,
  16. Message: err.Error(),
  17. }
  18. }
  19. codec := codecForRequest(r)
  20. data, _ := codec.Marshal(se)
  21. w.Header().Set(ContentTypeHeader, contentType(codec.Name()))
  22. w.WriteHeader(200)
  23. _, _ = w.Write(data)
  24. }
  25. const baseContentType = "application"
  26. var (
  27. acceptHeader = http.CanonicalHeaderKey("Accept")
  28. ContentTypeHeader = http.CanonicalHeaderKey("Content-Type")
  29. )
  30. func contentType(subtype string) string {
  31. return strings.Join([]string{baseContentType, subtype}, "/")
  32. }
  33. // codecForRequest get encoding.Codec via http.Request
  34. func codecForRequest(r *http.Request) encoding.Codec {
  35. var codec encoding.Codec
  36. for _, accept := range r.Header[acceptHeader] {
  37. if codec = encoding.GetCodec(contentSubtype(accept)); codec != nil {
  38. break
  39. }
  40. }
  41. if codec == nil {
  42. codec = encoding.GetCodec(json.Name)
  43. fmt.Println(codec == nil)
  44. }
  45. fmt.Println(codec == nil)
  46. return codec
  47. }
  48. func contentSubtype(contentType string) string {
  49. if contentType == baseContentType {
  50. return ""
  51. }
  52. if !strings.HasPrefix(contentType, baseContentType) {
  53. return ""
  54. }
  55. switch contentType[len(baseContentType)] {
  56. case '/', ';':
  57. if i := strings.Index(contentType, ";"); i != -1 {
  58. return contentType[len(baseContentType)+1 : i]
  59. }
  60. return contentType[len(baseContentType)+1:]
  61. default:
  62. return ""
  63. }
  64. }