github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/server/v2/put_handler.go (about) 1 package v2 2 3 import ( 4 "net/http" 5 "strconv" 6 "time" 7 8 etcdErr "github.com/coreos/etcd/error" 9 "github.com/coreos/etcd/store" 10 "github.com/coreos/etcd/third_party/github.com/goraft/raft" 11 "github.com/coreos/etcd/third_party/github.com/gorilla/mux" 12 ) 13 14 func PutHandler(w http.ResponseWriter, req *http.Request, s Server) error { 15 var c raft.Command 16 17 vars := mux.Vars(req) 18 key := "/" + vars["key"] 19 20 req.ParseForm() 21 22 value := req.Form.Get("value") 23 dir := (req.FormValue("dir") == "true") 24 25 expireTime, err := store.TTL(req.Form.Get("ttl")) 26 if err != nil { 27 return etcdErr.NewError(etcdErr.EcodeTTLNaN, "Update", s.Store().Index()) 28 } 29 30 _, valueOk := req.Form["prevValue"] 31 prevValue := req.FormValue("prevValue") 32 33 _, indexOk := req.Form["prevIndex"] 34 prevIndexStr := req.FormValue("prevIndex") 35 36 _, existOk := req.Form["prevExist"] 37 prevExist := req.FormValue("prevExist") 38 39 // Set handler: create a new node or replace the old one. 40 if !valueOk && !indexOk && !existOk { 41 return SetHandler(w, req, s, key, dir, value, expireTime) 42 } 43 44 // update with test 45 if existOk { 46 if prevExist == "false" { 47 // Create command: create a new node. Fail, if a node already exists 48 // Ignore prevIndex and prevValue 49 return CreateHandler(w, req, s, key, dir, value, expireTime) 50 } 51 52 if prevExist == "true" && !indexOk && !valueOk { 53 return UpdateHandler(w, req, s, key, value, expireTime) 54 } 55 } 56 57 var prevIndex uint64 58 59 if indexOk { 60 prevIndex, err = strconv.ParseUint(prevIndexStr, 10, 64) 61 62 // bad previous index 63 if err != nil { 64 return etcdErr.NewError(etcdErr.EcodeIndexNaN, "CompareAndSwap", s.Store().Index()) 65 } 66 } else { 67 prevIndex = 0 68 } 69 70 if valueOk { 71 if prevValue == "" { 72 return etcdErr.NewError(etcdErr.EcodePrevValueRequired, "CompareAndSwap", s.Store().Index()) 73 } 74 } 75 76 c = s.Store().CommandFactory().CreateCompareAndSwapCommand(key, value, prevValue, prevIndex, expireTime) 77 return s.Dispatch(c, w, req) 78 } 79 80 func SetHandler(w http.ResponseWriter, req *http.Request, s Server, key string, dir bool, value string, expireTime time.Time) error { 81 c := s.Store().CommandFactory().CreateSetCommand(key, dir, value, expireTime) 82 return s.Dispatch(c, w, req) 83 } 84 85 func CreateHandler(w http.ResponseWriter, req *http.Request, s Server, key string, dir bool, value string, expireTime time.Time) error { 86 c := s.Store().CommandFactory().CreateCreateCommand(key, dir, value, expireTime, false) 87 return s.Dispatch(c, w, req) 88 } 89 90 func UpdateHandler(w http.ResponseWriter, req *http.Request, s Server, key, value string, expireTime time.Time) error { 91 // Update should give at least one option 92 if value == "" && expireTime.Sub(store.Permanent) == 0 { 93 return etcdErr.NewError(etcdErr.EcodeValueOrTTLRequired, "Update", s.Store().Index()) 94 } 95 96 c := s.Store().CommandFactory().CreateUpdateCommand(key, value, expireTime) 97 return s.Dispatch(c, w, req) 98 }