1
0

bodylimit_test.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package middleware
  2. import (
  3. "bytes"
  4. "io"
  5. "net/http"
  6. "net/http/httptest"
  7. "strings"
  8. "testing"
  9. "github.com/gin-gonic/gin"
  10. )
  11. func TestMaxBodyBytes(t *testing.T) {
  12. gin.SetMode(gin.TestMode)
  13. const limit = 16
  14. r := gin.New()
  15. r.Use(MaxBodyBytes(limit))
  16. r.POST("/x", func(c *gin.Context) {
  17. if _, err := io.ReadAll(c.Request.Body); err != nil {
  18. c.String(http.StatusRequestEntityTooLarge, "too big")
  19. return
  20. }
  21. c.String(http.StatusOK, "ok")
  22. })
  23. r.GET("/x", func(c *gin.Context) { c.String(http.StatusOK, "ok") })
  24. // Body within the limit is read normally.
  25. w := httptest.NewRecorder()
  26. r.ServeHTTP(w, httptest.NewRequest(http.MethodPost, "/x", strings.NewReader("0123456789")))
  27. if w.Code != http.StatusOK {
  28. t.Errorf("under-limit POST: got %d, want 200", w.Code)
  29. }
  30. // Body over the limit makes the handler's read fail (no unbounded buffer).
  31. w = httptest.NewRecorder()
  32. r.ServeHTTP(w, httptest.NewRequest(http.MethodPost, "/x", bytes.NewReader(make([]byte, limit*4))))
  33. if w.Code == http.StatusOK {
  34. t.Errorf("over-limit POST should not succeed, got 200")
  35. }
  36. // Bodyless methods pass through untouched.
  37. w = httptest.NewRecorder()
  38. r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/x", nil))
  39. if w.Code != http.StatusOK {
  40. t.Errorf("GET should pass through, got %d", w.Code)
  41. }
  42. }
  43. func TestMaxBodyBytesSkipSuffix(t *testing.T) {
  44. gin.SetMode(gin.TestMode)
  45. const limit = 10 << 20
  46. r := gin.New()
  47. r.Use(MaxBodyBytes(limit, "/server/importDB"))
  48. read := func(c *gin.Context) {
  49. if _, err := io.ReadAll(c.Request.Body); err != nil {
  50. c.String(http.StatusRequestEntityTooLarge, "too big")
  51. return
  52. }
  53. c.String(http.StatusOK, "ok")
  54. }
  55. r.POST("/prefix/panel/api/server/importDB", read)
  56. r.POST("/prefix/panel/api/server/importDB/other", read)
  57. r.POST("/x", read)
  58. large := bytes.Repeat([]byte("x"), limit+1)
  59. w := httptest.NewRecorder()
  60. r.ServeHTTP(w, httptest.NewRequest(http.MethodPost, "/prefix/panel/api/server/importDB", bytes.NewReader(large)))
  61. if w.Code != http.StatusOK {
  62. t.Fatalf("restore route should accept an over-limit body, got %d", w.Code)
  63. }
  64. for _, path := range []string{"/x", "/prefix/panel/api/server/importDB/other"} {
  65. w = httptest.NewRecorder()
  66. r.ServeHTTP(w, httptest.NewRequest(http.MethodPost, path, bytes.NewReader(large)))
  67. if w.Code == http.StatusOK {
  68. t.Fatalf("non-exempt path %q accepted an over-limit body", path)
  69. }
  70. }
  71. }