X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=udp.go;h=df320041a6dd208bfd1a6df110ca7531adf61579;hb=a7bc3af1be220b07490841a896ff6ab7e8e58d34;hp=433c9da36219e45f802c084f2a424ab30b9f9542;hpb=59218ebf4cf9c2353dfa2cb416ee7d2542a3b9b9;p=go-anidb.git diff --git a/udp.go b/udp.go index 433c9da..df32004 100644 --- a/udp.go +++ b/udp.go @@ -1,26 +1,40 @@ package anidb import ( + "encoding/gob" "github.com/Kovensky/go-anidb/udp" - "sync" "time" ) -var banTime time.Time -var banTimeLock sync.Mutex +func init() { + gob.RegisterName("*github.com/Kovensky/go-anidb.banCache", &banCache{}) +} const banDuration = 30*time.Minute + 1*time.Second +type banCache struct{ time.Time } + +func (c *banCache) Touch() { + c.Time = time.Now() +} +func (c *banCache) IsStale() bool { + return time.Now().Sub(c.Time) > banDuration +} + // Returns whether the last UDP API access returned a 555 BANNED message. func Banned() bool { - banTimeLock.Lock() - banTimeLock.Unlock() + var banTime banCache + cache.Get(&banTime, "banned") - return _banned() + stale := banTime.IsStale() + if stale { + cache.Delete("banned") + } + return !stale } -func _banned() bool { - return time.Now().Sub(banTime) > banDuration +func setBanned() { + cache.Set(&banCache{}, "banned") } type paramSet struct { @@ -49,6 +63,22 @@ func newUDPWrap() *udpWrap { type paramMap udpapi.ParamMap // shortcut +type noauthAPIReply struct { + udpapi.APIReply +} + +func (r *noauthAPIReply) Code() int { + return 501 +} + +func (r *noauthAPIReply) Text() string { + return "LOGIN FIRST" +} + +func (r *noauthAPIReply) Error() error { + return &udpapi.APIError{Code: r.Code(), Desc: r.Text()} +} + type bannedAPIReply struct { udpapi.APIReply } @@ -60,7 +90,7 @@ func (r *bannedAPIReply) Text() string { return "BANNED" } func (r *bannedAPIReply) Error() error { - return &udpapi.APIError{Code: 555, Desc: "BANNED"} + return &udpapi.APIError{Code: r.Code(), Desc: r.Text()} } var bannedReply udpapi.APIReply = &bannedAPIReply{} @@ -85,11 +115,7 @@ func (udp *udpWrap) sendQueue() { case 503, 504: // client library rejected panic(reply.Error()) case 555: // IP (and user, possibly client) temporarily banned - banTimeLock.Lock() - - banTime = time.Now() - - banTimeLock.Unlock() + setBanned() } set.ch <- reply close(set.ch) @@ -98,12 +124,13 @@ func (udp *udpWrap) sendQueue() { func (udp *udpWrap) SendRecv(cmd string, params paramMap) <-chan udpapi.APIReply { ch := make(chan udpapi.APIReply, 1) + if udp.credentials == nil { + ch <- &noauthAPIReply{} + close(ch) + return ch + } - banTimeLock.Lock() - defer banTimeLock.Unlock() - if _banned() { - banTime = time.Time{} - } else { + if Banned() { ch <- bannedReply close(ch) return ch