request.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package utils
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "strings"
  8. "github.com/beego/beego/v2/server/web"
  9. )
  10. const jsonBodyCacheKey = "__request_json_body_map"
  11. func parseRequestJSONBody(c *web.Controller) (map[string]interface{}, error) {
  12. if cached := c.Ctx.Input.GetData(jsonBodyCacheKey); cached != nil {
  13. if m, ok := cached.(map[string]interface{}); ok {
  14. return m, nil
  15. }
  16. }
  17. contentType := strings.ToLower(c.Ctx.Input.Header("Content-Type"))
  18. body := c.Ctx.Input.RequestBody
  19. if len(body) == 0 {
  20. if c.Ctx.Request != nil && c.Ctx.Request.Body != nil {
  21. readBody, err := io.ReadAll(c.Ctx.Request.Body)
  22. if err != nil {
  23. return nil, err
  24. }
  25. body = readBody
  26. c.Ctx.Input.RequestBody = readBody
  27. c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(readBody))
  28. }
  29. }
  30. if len(body) == 0 {
  31. return nil, nil
  32. }
  33. trimBody := strings.TrimSpace(string(body))
  34. if trimBody == "" {
  35. return nil, nil
  36. }
  37. if !strings.HasPrefix(trimBody, "{") && !strings.HasPrefix(trimBody, "[") {
  38. return nil, nil
  39. }
  40. var m map[string]interface{}
  41. if err := json.Unmarshal(body, &m); err != nil {
  42. if strings.Contains(contentType, "application/json") {
  43. return nil, err
  44. }
  45. return nil, nil
  46. }
  47. c.Ctx.Input.SetData(jsonBodyCacheKey, m)
  48. return m, nil
  49. }
  50. // GetRequestString gets parameter by key.
  51. // It tries form/query first, then falls back to JSON body for application/json.
  52. func GetRequestString(c *web.Controller, key string) (string, error) {
  53. v := strings.TrimSpace(c.GetString(key))
  54. if v != "" {
  55. return v, nil
  56. }
  57. m, err := parseRequestJSONBody(c)
  58. if err != nil {
  59. return "", err
  60. }
  61. if m == nil {
  62. return "", nil
  63. }
  64. raw, ok := m[key]
  65. if !ok || raw == nil {
  66. return "", nil
  67. }
  68. switch vv := raw.(type) {
  69. case string:
  70. return strings.TrimSpace(vv), nil
  71. default:
  72. return strings.TrimSpace(fmt.Sprint(vv)), nil
  73. }
  74. }