75 lines
1.5 KiB
Go
75 lines
1.5 KiB
Go
package proxy
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type ProxySession struct {
|
|
Token string
|
|
TargetURL string
|
|
Created time.Time
|
|
Expires time.Time
|
|
}
|
|
|
|
type ProxySessionManager struct {
|
|
sessions sync.Map
|
|
ttl time.Duration
|
|
}
|
|
|
|
func NewProxySessionManager(ttl time.Duration) *ProxySessionManager {
|
|
sm := &ProxySessionManager{ttl: ttl}
|
|
go sm.cleanup()
|
|
return sm
|
|
}
|
|
|
|
func (sm *ProxySessionManager) Create(targetURL string) string {
|
|
token := generateToken()
|
|
|
|
sm.sessions.Store(token, &ProxySession{
|
|
Token: token,
|
|
TargetURL: targetURL,
|
|
Created: time.Now(),
|
|
Expires: time.Now().Add(sm.ttl),
|
|
})
|
|
|
|
return token
|
|
}
|
|
|
|
func (sm *ProxySessionManager) Get(token string) *ProxySession {
|
|
val, ok := sm.sessions.Load(token)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
session := val.(*ProxySession)
|
|
if time.Now().After(session.Expires) {
|
|
sm.sessions.Delete(token)
|
|
return nil
|
|
}
|
|
|
|
return session
|
|
}
|
|
|
|
func (sm *ProxySessionManager) cleanup() {
|
|
ticker := time.NewTicker(5 * time.Minute)
|
|
for range ticker.C {
|
|
now := time.Now()
|
|
sm.sessions.Range(func(key, value interface{}) bool {
|
|
session := value.(*ProxySession)
|
|
if now.After(session.Expires) {
|
|
sm.sessions.Delete(key)
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
}
|
|
|
|
func generateToken() string {
|
|
b := make([]byte, 16)
|
|
rand.Read(b)
|
|
return hex.EncodeToString(b)
|
|
}
|