You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

httpcache_test.go 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package httpcache
  5. import (
  6. "net/http"
  7. "net/http/httptest"
  8. "os"
  9. "strings"
  10. "testing"
  11. "time"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. type mockFileInfo struct{}
  15. func (m mockFileInfo) Name() string { return "gitea.test" }
  16. func (m mockFileInfo) Size() int64 { return int64(10) }
  17. func (m mockFileInfo) Mode() os.FileMode { return os.ModePerm }
  18. func (m mockFileInfo) ModTime() time.Time { return time.Time{} }
  19. func (m mockFileInfo) IsDir() bool { return false }
  20. func (m mockFileInfo) Sys() interface{} { return nil }
  21. func countFormalHeaders(h http.Header) (c int) {
  22. for k := range h {
  23. // ignore our headers for internal usage
  24. if strings.HasPrefix(k, "X-Gitea-") {
  25. continue
  26. }
  27. c++
  28. }
  29. return c
  30. }
  31. func TestHandleFileETagCache(t *testing.T) {
  32. fi := mockFileInfo{}
  33. etag := `"MTBnaXRlYS50ZXN0TW9uLCAwMSBKYW4gMDAwMSAwMDowMDowMCBHTVQ="`
  34. t.Run("No_If-None-Match", func(t *testing.T) {
  35. req := &http.Request{Header: make(http.Header)}
  36. w := httptest.NewRecorder()
  37. handled := HandleFileETagCache(req, w, fi)
  38. assert.False(t, handled)
  39. assert.Equal(t, 2, countFormalHeaders(w.Header()))
  40. assert.Contains(t, w.Header(), "Cache-Control")
  41. assert.Contains(t, w.Header(), "Etag")
  42. assert.Equal(t, etag, w.Header().Get("Etag"))
  43. })
  44. t.Run("Wrong_If-None-Match", func(t *testing.T) {
  45. req := &http.Request{Header: make(http.Header)}
  46. w := httptest.NewRecorder()
  47. req.Header.Set("If-None-Match", `"wrong etag"`)
  48. handled := HandleFileETagCache(req, w, fi)
  49. assert.False(t, handled)
  50. assert.Equal(t, 2, countFormalHeaders(w.Header()))
  51. assert.Contains(t, w.Header(), "Cache-Control")
  52. assert.Contains(t, w.Header(), "Etag")
  53. assert.Equal(t, etag, w.Header().Get("Etag"))
  54. })
  55. t.Run("Correct_If-None-Match", func(t *testing.T) {
  56. req := &http.Request{Header: make(http.Header)}
  57. w := httptest.NewRecorder()
  58. req.Header.Set("If-None-Match", etag)
  59. handled := HandleFileETagCache(req, w, fi)
  60. assert.True(t, handled)
  61. assert.Equal(t, 1, countFormalHeaders(w.Header()))
  62. assert.Contains(t, w.Header(), "Etag")
  63. assert.Equal(t, etag, w.Header().Get("Etag"))
  64. assert.Equal(t, http.StatusNotModified, w.Code)
  65. })
  66. }
  67. func TestHandleGenericETagCache(t *testing.T) {
  68. etag := `"test"`
  69. t.Run("No_If-None-Match", func(t *testing.T) {
  70. req := &http.Request{Header: make(http.Header)}
  71. w := httptest.NewRecorder()
  72. handled := HandleGenericETagCache(req, w, etag)
  73. assert.False(t, handled)
  74. assert.Equal(t, 2, countFormalHeaders(w.Header()))
  75. assert.Contains(t, w.Header(), "Cache-Control")
  76. assert.Contains(t, w.Header(), "Etag")
  77. assert.Equal(t, etag, w.Header().Get("Etag"))
  78. })
  79. t.Run("Wrong_If-None-Match", func(t *testing.T) {
  80. req := &http.Request{Header: make(http.Header)}
  81. w := httptest.NewRecorder()
  82. req.Header.Set("If-None-Match", `"wrong etag"`)
  83. handled := HandleGenericETagCache(req, w, etag)
  84. assert.False(t, handled)
  85. assert.Equal(t, 2, countFormalHeaders(w.Header()))
  86. assert.Contains(t, w.Header(), "Cache-Control")
  87. assert.Contains(t, w.Header(), "Etag")
  88. assert.Equal(t, etag, w.Header().Get("Etag"))
  89. })
  90. t.Run("Correct_If-None-Match", func(t *testing.T) {
  91. req := &http.Request{Header: make(http.Header)}
  92. w := httptest.NewRecorder()
  93. req.Header.Set("If-None-Match", etag)
  94. handled := HandleGenericETagCache(req, w, etag)
  95. assert.True(t, handled)
  96. assert.Equal(t, 1, countFormalHeaders(w.Header()))
  97. assert.Contains(t, w.Header(), "Etag")
  98. assert.Equal(t, etag, w.Header().Get("Etag"))
  99. assert.Equal(t, http.StatusNotModified, w.Code)
  100. })
  101. t.Run("Multiple_Wrong_If-None-Match", func(t *testing.T) {
  102. req := &http.Request{Header: make(http.Header)}
  103. w := httptest.NewRecorder()
  104. req.Header.Set("If-None-Match", `"wrong etag", "wrong etag "`)
  105. handled := HandleGenericETagCache(req, w, etag)
  106. assert.False(t, handled)
  107. assert.Equal(t, 2, countFormalHeaders(w.Header()))
  108. assert.Contains(t, w.Header(), "Cache-Control")
  109. assert.Contains(t, w.Header(), "Etag")
  110. assert.Equal(t, etag, w.Header().Get("Etag"))
  111. })
  112. t.Run("Multiple_Correct_If-None-Match", func(t *testing.T) {
  113. req := &http.Request{Header: make(http.Header)}
  114. w := httptest.NewRecorder()
  115. req.Header.Set("If-None-Match", `"wrong etag", `+etag)
  116. handled := HandleGenericETagCache(req, w, etag)
  117. assert.True(t, handled)
  118. assert.Equal(t, 1, countFormalHeaders(w.Header()))
  119. assert.Contains(t, w.Header(), "Etag")
  120. assert.Equal(t, etag, w.Header().Get("Etag"))
  121. assert.Equal(t, http.StatusNotModified, w.Code)
  122. })
  123. }