]> git.lizzy.rs Git - go-anidb.git/blobdiff - udp.go
anidb: Don't use a nil fileLock
[go-anidb.git] / udp.go
diff --git a/udp.go b/udp.go
index 433c9da36219e45f802c084f2a424ab30b9f9542..df320041a6dd208bfd1a6df110ca7531adf61579 100644 (file)
--- 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