mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 14:06:36 +08:00
91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
package cap
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Store defines the storage interface for challenge nonces and verification tokens
|
|
type Store interface {
|
|
Get(ctx context.Context, key string) (string, bool, error)
|
|
Set(ctx context.Context, key string, val string, ttl time.Duration) error
|
|
Delete(ctx context.Context, key string) error
|
|
}
|
|
|
|
type memoryItem struct {
|
|
value string
|
|
expiresAt time.Time
|
|
}
|
|
|
|
// MemoryStore is a thread-safe in-memory implementation of Store
|
|
type MemoryStore struct {
|
|
items map[string]memoryItem
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// NewMemoryStore creates and initializes a new MemoryStore
|
|
func NewMemoryStore(cleanupInterval time.Duration) *MemoryStore {
|
|
store := &MemoryStore{
|
|
items: make(map[string]memoryItem),
|
|
}
|
|
if cleanupInterval > 0 {
|
|
go store.startCleanupLoop(cleanupInterval)
|
|
}
|
|
return store
|
|
}
|
|
|
|
func (s *MemoryStore) Get(ctx context.Context, key string) (string, bool, error) {
|
|
s.mu.RLock()
|
|
item, found := s.items[key]
|
|
s.mu.RUnlock()
|
|
|
|
if !found {
|
|
return "", false, nil
|
|
}
|
|
|
|
if time.Now().After(item.expiresAt) {
|
|
s.mu.Lock()
|
|
delete(s.items, key)
|
|
s.mu.Unlock()
|
|
return "", false, nil
|
|
}
|
|
|
|
return item.value, true, nil
|
|
}
|
|
|
|
func (s *MemoryStore) Set(ctx context.Context, key string, val string, ttl time.Duration) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.items[key] = memoryItem{
|
|
value: val,
|
|
expiresAt: time.Now().Add(ttl),
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *MemoryStore) Delete(ctx context.Context, key string) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
delete(s.items, key)
|
|
return nil
|
|
}
|
|
|
|
func (s *MemoryStore) startCleanupLoop(interval time.Duration) {
|
|
ticker := time.NewTicker(interval)
|
|
for range ticker.C {
|
|
s.cleanupExpired()
|
|
}
|
|
}
|
|
|
|
func (s *MemoryStore) cleanupExpired() {
|
|
now := time.Now()
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
for k, v := range s.items {
|
|
if now.After(v.expiresAt) {
|
|
delete(s.items, k)
|
|
}
|
|
}
|
|
}
|