amfora/cache/redir.go
2020-07-28 16:58:32 -04:00

61 lines
1.3 KiB
Go

package cache
import (
"sync"
)
// Functions for caching redirects.
var redirUrls = make(map[string]string) // map original URL to redirect
var redirMu = sync.RWMutex{}
// AddRedir adds a original-to-redirect pair to the cache.
func AddRedir(og, redir string) {
redirMu.Lock()
defer redirMu.Unlock()
for k, v := range redirUrls {
if og == v {
// The original URL param is the redirect URL for `k`.
// This means there is a chain: k -> og -> redir
// The chain should be removed
redirUrls[k] = redir
}
if redir == k {
// There's a loop
// The newer version is preferred
delete(redirUrls, k)
}
}
redirUrls[og] = redir
}
// ClearRedirs removes all redirects from the cache.
func ClearRedirs() {
redirMu.Lock()
defer redirMu.Unlock()
redirUrls = make(map[string]string)
}
// Redirect takes the provided URL and returns a redirected version, if a redirect
// exists for that URL in the cache.
// If one does not then the original URL is returned.
func Redirect(u string) string {
redirMu.RLock()
defer redirMu.RUnlock()
// A single lookup is enough, because AddRedir
// removes loops and chains.
redir, ok := redirUrls[u]
if ok {
return redir
}
return u
}
func NumRedirs() int {
redirMu.RLock()
defer redirMu.RUnlock()
return len(redirUrls)
}