mirror of
https://github.com/nprasad2077/NBA_Go.git
synced 2026-09-22 14:05:13 +00:00
CDN
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// CacheStrategy defines caching profiles for different API data mutability tiers
|
||||
type CacheStrategy string
|
||||
|
||||
const (
|
||||
// Immutable: For historical completed games, past seasons, and shot charts.
|
||||
// Edge TTL: 30 Days | Browser TTL: 1 Day
|
||||
Immutable CacheStrategy = "immutable"
|
||||
|
||||
// SemiDynamic: For daily leaderboards, player season averages, and standings.
|
||||
// Edge TTL: 1 Day | Browser TTL: 1 Minute | Stale-While-Revalidate: 10 Minutes
|
||||
SemiDynamic CacheStrategy = "semi_dynamic"
|
||||
|
||||
// Realtime: For active game telemetry, live quarter stats, and fast-updating data.
|
||||
// Edge TTL: 10 Seconds | Browser TTL: 5 Seconds | Stale-While-Revalidate: 30 Seconds
|
||||
Realtime CacheStrategy = "realtime"
|
||||
|
||||
// NoCache: For transactional mutations, scrapers, and admin endpoints.
|
||||
NoCache CacheStrategy = "no_cache"
|
||||
)
|
||||
|
||||
// EdgeCache injects standardized Cloudflare & HTTP caching headers
|
||||
func EdgeCache(strategy CacheStrategy, tags ...string) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Only cache idempotent read requests (GET / HEAD)
|
||||
if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead {
|
||||
c.Set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate")
|
||||
c.Set("Pragma", "no-cache")
|
||||
c.Set("Expires", "0")
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
switch strategy {
|
||||
case Immutable:
|
||||
// Served directly by Cloudflare US Edge for 30 days without hitting Europe origin
|
||||
c.Set("Cache-Control", "public, max-age=86400, s-maxage=2592000, immutable")
|
||||
case SemiDynamic:
|
||||
// Instant edge delivery; background revalidation over transatlantic backbone
|
||||
c.Set("Cache-Control", "public, max-age=60, s-maxage=86400, stale-while-revalidate=600")
|
||||
case Realtime:
|
||||
c.Set("Cache-Control", "public, max-age=5, s-maxage=10, stale-while-revalidate=30")
|
||||
case NoCache:
|
||||
c.Set("Cache-Control", "no-store, no-cache, must-revalidate")
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Cloudflare Cache-Tag header for instantaneous programmatic purge by entity
|
||||
if len(tags) > 0 {
|
||||
var tagHeader string
|
||||
for i, tag := range tags {
|
||||
if i > 0 {
|
||||
tagHeader += ","
|
||||
}
|
||||
tagHeader += tag
|
||||
}
|
||||
c.Set("Cache-Tag", tagHeader)
|
||||
}
|
||||
|
||||
c.Set("Vary", "Accept-Encoding, Origin")
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// ComputeETag generates a weak ETag based on response body bytes for 304 Not Modified optimization
|
||||
func ComputeETag(data []byte) string {
|
||||
hash := sha256.Sum256(data)
|
||||
return fmt.Sprintf(`W/"%s"`, hex.EncodeToString(hash[:8]))
|
||||
}
|
||||
Reference in New Issue
Block a user