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  }