fix(backend): back off Sentinel lockdown retries, validate product_id in /proxy

Log analysis over 17 days showed 181 Sentinel-block retry attempts on
/proxy, all 181 failed (0% success). Retrying every 90 minutes yields
zero value right now and just adds more blocked-request noise against
our own IP for nothing in return. Bumped lockdownTTL to 5h so it backs
off harder while still recovering same-day if Microsoft's block ever
eases.

Also found /proxy never validated product_id against the known
catalog, so a request for a nonexistent ID (e.g. product_id=2861,
never a real product) still burned a full outbound Microsoft session
attempt and a Sentinel-block hit for something that could never
succeed anyway. Now rejected with 404 before any Microsoft call,
reusing the existing validContributeProducts allow-list.

Verified locally: unknown product_id -> 404 (no MS fetch attempted in
logs), missing params -> 400 unchanged, known product_id -> proceeds
to a real MS session attempt as before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Shekhar Vaidya 2026-07-31 11:35:44 +05:30
parent 5a806eea87
commit 6ab849be5e

View file

@ -132,7 +132,7 @@ func truncateBody(s string) string {
return s return s
} }
// --- Negative cache (60s normal / 90min Sentinel lockdown) --- // --- Negative cache (60s normal / 5h Sentinel lockdown) ---
type negCacheEntry struct { type negCacheEntry struct {
Message string Message string
@ -145,7 +145,10 @@ var (
negCache = make(map[string]negCacheEntry) negCache = make(map[string]negCacheEntry)
negCacheMu sync.RWMutex negCacheMu sync.RWMutex
negCacheTTL = 60 * time.Second negCacheTTL = 60 * time.Second
lockdownTTL = 90 * time.Minute // Bumped from 90min on 2026-07-31: 181 retry attempts over 17 days, 0 successes.
// Retries yield zero value right now, so back off harder instead of hammering
// Microsoft (and our own IP's reputation) every 90 minutes for nothing.
lockdownTTL = 5 * time.Hour
) )
// --- Singleflight (one in-flight Microsoft fetch per unique key) --- // --- Singleflight (one in-flight Microsoft fetch per unique key) ---
@ -1184,6 +1187,10 @@ func handleProxy(w http.ResponseWriter, r *http.Request) {
respondJSONError(w, http.StatusBadRequest, "sku_id contains invalid characters") respondJSONError(w, http.StatusBadRequest, "sku_id contains invalid characters")
return return
} }
if !validContributeProducts[productID] {
respondJSONError(w, http.StatusNotFound, "unknown product_id")
return
}
atomic.AddInt64(&mLinkRequests, 1) atomic.AddInt64(&mLinkRequests, 1)
cacheKey := productID + ":" + skuID cacheKey := productID + ":" + skuID
@ -1301,7 +1308,7 @@ func handleProxy(w http.ResponseWriter, r *http.Request) {
atomic.AddInt64(&mLinkStale, 1) atomic.AddInt64(&mLinkStale, 1)
if isSentinel { if isSentinel {
// Sentinel lockdown: set 90-min neg cache, add lockdown header, skip // Sentinel lockdown: set lockdownTTL neg cache, add lockdown header, skip
// background refresh — retrying extends the Sentinel block timer. // background refresh — retrying extends the Sentinel block timer.
negCacheMu.Lock() negCacheMu.Lock()
negCache[negKey] = negCacheEntry{ negCache[negKey] = negCacheEntry{
@ -1311,7 +1318,7 @@ func handleProxy(w http.ResponseWriter, r *http.Request) {
IsSentinel: true, IsSentinel: true,
} }
negCacheMu.Unlock() negCacheMu.Unlock()
log.Printf("/proxy: product_id=%s sku_id=%s -> Sentinel lockdown (90min), serving stale\n", productID, skuID) log.Printf("/proxy: product_id=%s sku_id=%s -> Sentinel lockdown (%s), serving stale\n", productID, skuID, lockdownTTL)
w.Header().Set("X-MSDL-Lockdown", "1") w.Header().Set("X-MSDL-Lockdown", "1")
w.Header().Set("X-MSDL-Link-Status", "stale") w.Header().Set("X-MSDL-Link-Status", "stale")
if exp := extractRawExpiry(cached.RawJSON); exp != "" { if exp := extractRawExpiry(cached.RawJSON); exp != "" {
@ -1365,7 +1372,7 @@ func handleProxy(w http.ResponseWriter, r *http.Request) {
} }
negCacheMu.Unlock() negCacheMu.Unlock()
if isSentinel { if isSentinel {
log.Printf("/proxy: product_id=%s sku_id=%s -> Sentinel lockdown (90min), no stale\n", productID, skuID) log.Printf("/proxy: product_id=%s sku_id=%s -> Sentinel lockdown (%s), no stale\n", productID, skuID, lockdownTTL)
w.Header().Set("X-MSDL-Lockdown", "1") w.Header().Set("X-MSDL-Lockdown", "1")
w.WriteHeader(code) w.WriteHeader(code)
json.NewEncoder(w).Encode(map[string]interface{}{ json.NewEncoder(w).Encode(map[string]interface{}{