code.pfad.fr/gohmekit@v0.2.1/hapip/handle_prepare.go (about) 1 package hapip 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "sync" 7 "time" 8 ) 9 10 type timedWrite struct { 11 mu sync.Mutex 12 PID uint64 13 Deadline time.Time 14 } 15 16 func (tw *timedWrite) isValid(pid *uint64) bool { 17 tw.mu.Lock() 18 defer tw.mu.Unlock() 19 20 if tw.Deadline.IsZero() { 21 return pid == nil 22 } 23 isTooLate := time.Since(tw.Deadline) > 0 24 if isTooLate { 25 return pid == nil 26 } 27 28 // within the deadline: 29 // expect the right pid 30 rightPID := pid != nil && *pid == tw.PID 31 if rightPID { 32 tw.Deadline = time.Time{} 33 return true 34 } 35 return false 36 } 37 38 func (h Handler) putPrepare(rw http.ResponseWriter, req *http.Request) error { 39 var timedWrite struct { 40 TTL time.Duration `json:"ttl"` 41 PID uint64 `json:"pid"` 42 } 43 err := json.NewDecoder(req.Body).Decode(&timedWrite) 44 if err != nil { 45 rw.WriteHeader(http.StatusBadRequest) 46 return err 47 } 48 49 tw := h.tw 50 tw.mu.Lock() 51 tw.PID = timedWrite.PID 52 tw.Deadline = time.Now().Add(timedWrite.TTL * time.Millisecond) 53 tw.mu.Unlock() 54 55 return WriteStatus(rw, http.StatusOK, StatusSuccess) 56 }