feat: deduplicate proxy token creation

This commit is contained in:
2026-06-16 01:04:21 +02:00
committed by Milas Holsting
parent ec10fa56b4
commit 622418f96c
2 changed files with 99 additions and 6 deletions

View File

@@ -15,33 +15,52 @@ type proxyTokenTarget struct {
expiresAt time.Time
}
type proxyTokenKey struct {
targetURL string
referer string
scope string
}
type proxyTokenStore struct {
mu sync.Mutex
tokens map[string]proxyTokenTarget
mu sync.Mutex
tokens map[string]proxyTokenTarget
byTarget map[proxyTokenKey]string
}
func newProxyTokenStore() *proxyTokenStore {
return &proxyTokenStore{
tokens: make(map[string]proxyTokenTarget),
tokens: make(map[string]proxyTokenTarget),
byTarget: make(map[proxyTokenKey]string),
}
}
func (s *proxyTokenStore) create(targetURL, referer, scope string, ttl time.Duration, now time.Time) (string, error) {
key := proxyTokenKey{targetURL: targetURL, referer: referer, scope: scope}
s.mu.Lock()
defer s.mu.Unlock()
s.pruneExpiredLocked(now)
if token, ok := s.byTarget[key]; ok {
if target, ok := s.tokens[token]; ok && target.expiresAt.After(now) {
return token, nil
}
delete(s.byTarget, key)
}
tokenBytes := make([]byte, 32)
if _, err := rand.Read(tokenBytes); err != nil {
return "", fmt.Errorf("generate proxy token: %w", err)
}
token := base64.RawURLEncoding.EncodeToString(tokenBytes)
s.mu.Lock()
defer s.mu.Unlock()
s.pruneExpiredLocked(now)
s.tokens[token] = proxyTokenTarget{
targetURL: targetURL,
referer: referer,
scope: scope,
expiresAt: now.Add(ttl),
}
s.byTarget[key] = token
return token, nil
}
@@ -55,6 +74,7 @@ func (s *proxyTokenStore) resolve(token string, now time.Time) (proxyTokenTarget
}
if !target.expiresAt.After(now) {
delete(s.tokens, token)
delete(s.byTarget, target.key())
return proxyTokenTarget{}, fmt.Errorf("proxy token expired")
}
return target, nil
@@ -64,6 +84,11 @@ func (s *proxyTokenStore) pruneExpiredLocked(now time.Time) {
for token, target := range s.tokens {
if !target.expiresAt.After(now) {
delete(s.tokens, token)
delete(s.byTarget, target.key())
}
}
}
func (t proxyTokenTarget) key() proxyTokenKey {
return proxyTokenKey{targetURL: t.targetURL, referer: t.referer, scope: t.scope}
}