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  }