aboutsummaryrefslogtreecommitdiff
path: root/internal/api/api_test.go
diff options
context:
space:
mode:
authorJonathan Amsterdam <jba@google.com>2026-04-07 18:52:05 -0400
committerJonathan Amsterdam <jba@google.com>2026-04-08 13:35:34 -0700
commitb0096dc799437fdf92fc65135a7141fa8ad358be (patch)
tree59514073b525d15fd7917f424d0228ded51e67b9 /internal/api/api_test.go
parent0ef8af41d6814a34f239b02ab621c4cfcb8c0019 (diff)
downloadgo-x-pkgsite-b0096dc799437fdf92fc65135a7141fa8ad358be.tar.xz
internal/api: set cache-control headers
Set an HTTP Cache-Control header for all API responses. Since requests that reference a specific, numbered version apparently always produce the same response, it is tempting to use the "immutable" Cache-Control directive so these pages can be cached indefinitely. But occasionally we must exclude a module. It would be unfortunate if the module's data lived in caches forever. Instead, we cache such pages for one day. Pages that are subject to more rapid change, like those with versions "latest", "master" and so on, or those that depend on data other than a module (imported-by, search, etc.) are cached for an hour. That is an arbitrary value that seems like a good compromise, since the likelihood of a particular page's value changing in an hour is low. Change-Id: I21414c22c724220c993c1dd7e7a0b49074efd8b9 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/763782 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ethan Lee <ethanalee@google.com> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com> TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Diffstat (limited to 'internal/api/api_test.go')
-rw-r--r--internal/api/api_test.go55
1 files changed, 55 insertions, 0 deletions
diff --git a/internal/api/api_test.go b/internal/api/api_test.go
index 5d5c9c03..5de0ab6e 100644
--- a/internal/api/api_test.go
+++ b/internal/api/api_test.go
@@ -1053,3 +1053,58 @@ func unmarshalResponse[T any](data []byte) (any, error) {
}
return nil, errors.Join(err1, err2)
}
+
+func TestCacheControl(t *testing.T) {
+ ctx := context.Background()
+ ds := fakedatasource.New()
+ const modulePath = "example.com"
+ for _, v := range []string{"v1.0.0", "master"} {
+ ds.MustInsertModule(ctx, &internal.Module{
+ ModuleInfo: internal.ModuleInfo{
+ ModulePath: modulePath,
+ Version: v,
+ },
+ Units: []*internal.Unit{{
+ UnitMeta: internal.UnitMeta{
+ Path: modulePath,
+ ModuleInfo: internal.ModuleInfo{
+ ModulePath: modulePath,
+ Version: v,
+ },
+ },
+ }},
+ })
+ }
+
+ for _, test := range []struct {
+ version string
+ want string
+ }{
+ {"v1.0.0", "public, max-age=10800"},
+ {"latest", "public, max-age=3600"},
+ {"master", "public, max-age=3600"},
+ {"", "public, max-age=3600"},
+ } {
+ t.Run(test.version, func(t *testing.T) {
+ url := "/v1/module/" + modulePath
+ if test.version != "" {
+ url += "?version=" + test.version
+ }
+ r := httptest.NewRequest("GET", url, nil)
+ w := httptest.NewRecorder()
+
+ if err := ServeModule(w, r, ds); err != nil {
+ t.Fatal(err)
+ }
+
+ if w.Code != http.StatusOK {
+ t.Fatalf("status = %d, want %d", w.Code, http.StatusOK)
+ }
+
+ got := w.Header().Get("Cache-Control")
+ if got != test.want {
+ t.Errorf("Cache-Control = %q, want %q", got, test.want)
+ }
+ })
+ }
+}