upstream_response_limit_test.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package service
  2. import (
  3. "bytes"
  4. "errors"
  5. "testing"
  6. "testing/iotest"
  7. "github.com/Wei-Shaw/sub2api/internal/config"
  8. "github.com/gin-gonic/gin"
  9. "github.com/stretchr/testify/require"
  10. )
  11. func TestResolveUpstreamResponseReadLimit(t *testing.T) {
  12. t.Run("use default when config missing", func(t *testing.T) {
  13. require.Equal(t, defaultUpstreamResponseReadMaxBytes, resolveUpstreamResponseReadLimit(nil))
  14. })
  15. t.Run("use configured value", func(t *testing.T) {
  16. cfg := &config.Config{}
  17. cfg.Gateway.UpstreamResponseReadMaxBytes = 1234
  18. require.Equal(t, int64(1234), resolveUpstreamResponseReadLimit(cfg))
  19. })
  20. }
  21. func TestReadUpstreamResponseBodyLimited(t *testing.T) {
  22. t.Run("within limit", func(t *testing.T) {
  23. body, err := readUpstreamResponseBodyLimited(bytes.NewReader([]byte("ok")), 2)
  24. require.NoError(t, err)
  25. require.Equal(t, []byte("ok"), body)
  26. })
  27. t.Run("exceeds limit", func(t *testing.T) {
  28. body, err := readUpstreamResponseBodyLimited(bytes.NewReader([]byte("toolong")), 3)
  29. require.Nil(t, body)
  30. require.Error(t, err)
  31. require.True(t, errors.Is(err, ErrUpstreamResponseBodyTooLarge))
  32. })
  33. }
  34. func TestReadUpstreamResponseBody(t *testing.T) {
  35. t.Run("within limit", func(t *testing.T) {
  36. body, err := ReadUpstreamResponseBody(bytes.NewReader([]byte("ok")), nil, nil, nil)
  37. require.NoError(t, err)
  38. require.Equal(t, []byte("ok"), body)
  39. })
  40. t.Run("exceeds limit calls onTooLarge", func(t *testing.T) {
  41. cfg := &config.Config{}
  42. cfg.Gateway.UpstreamResponseReadMaxBytes = 3
  43. called := false
  44. onTooLarge := func(_ *gin.Context) { called = true }
  45. body, err := ReadUpstreamResponseBody(bytes.NewReader([]byte("toolong")), cfg, nil, onTooLarge)
  46. require.Nil(t, body)
  47. require.True(t, errors.Is(err, ErrUpstreamResponseBodyTooLarge))
  48. require.True(t, called)
  49. })
  50. t.Run("nil onTooLarge does not panic", func(t *testing.T) {
  51. cfg := &config.Config{}
  52. cfg.Gateway.UpstreamResponseReadMaxBytes = 3
  53. body, err := ReadUpstreamResponseBody(bytes.NewReader([]byte("toolong")), cfg, nil, nil)
  54. require.Nil(t, body)
  55. require.True(t, errors.Is(err, ErrUpstreamResponseBodyTooLarge))
  56. })
  57. t.Run("io error does not call onTooLarge", func(t *testing.T) {
  58. called := false
  59. onTooLarge := func(_ *gin.Context) { called = true }
  60. body, err := ReadUpstreamResponseBody(iotest.ErrReader(errors.New("disk failure")), nil, nil, onTooLarge)
  61. require.Nil(t, body)
  62. require.Error(t, err)
  63. require.False(t, errors.Is(err, ErrUpstreamResponseBodyTooLarge))
  64. require.False(t, called)
  65. })
  66. }