github.com/kula/etcd@v0.2.1-0.20131226070625-e96234382ac0/server/v2/get_handler.go (about) 1 package v2 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/url" 8 "strconv" 9 10 etcdErr "github.com/coreos/etcd/error" 11 "github.com/coreos/etcd/log" 12 "github.com/coreos/etcd/store" 13 "github.com/coreos/raft" 14 "github.com/gorilla/mux" 15 ) 16 17 func GetHandler(w http.ResponseWriter, req *http.Request, s Server) error { 18 var err error 19 var event *store.Event 20 21 vars := mux.Vars(req) 22 key := "/" + vars["key"] 23 24 // Help client to redirect the request to the current leader 25 if req.FormValue("consistent") == "true" && s.State() != raft.Leader { 26 leader := s.Leader() 27 hostname, _ := s.ClientURL(leader) 28 29 url, err := url.Parse(hostname) 30 if err != nil { 31 log.Warn("Redirect cannot parse hostName ", hostname) 32 return err 33 } 34 url.RawQuery = req.URL.RawQuery 35 url.Path = req.URL.Path 36 37 log.Debugf("Redirect consistent get to %s", url.String()) 38 http.Redirect(w, req, url.String(), http.StatusTemporaryRedirect) 39 return nil 40 } 41 42 recursive := (req.FormValue("recursive") == "true") 43 sorted := (req.FormValue("sorted") == "true") 44 45 if req.FormValue("wait") == "true" { // watch 46 // Create a command to watch from a given index (default 0). 47 var sinceIndex uint64 = 0 48 49 waitIndex := req.FormValue("waitIndex") 50 if waitIndex != "" { 51 sinceIndex, err = strconv.ParseUint(string(req.FormValue("waitIndex")), 10, 64) 52 if err != nil { 53 return etcdErr.NewError(etcdErr.EcodeIndexNaN, "Watch From Index", s.Store().Index()) 54 } 55 } 56 57 // Start the watcher on the store. 58 eventChan, err := s.Store().Watch(key, recursive, sinceIndex) 59 if err != nil { 60 return err 61 } 62 63 cn, _ := w.(http.CloseNotifier) 64 closeChan := cn.CloseNotify() 65 66 select { 67 case <-closeChan: 68 return nil 69 case event = <-eventChan: 70 } 71 72 } else { //get 73 // Retrieve the key from the store. 74 event, err = s.Store().Get(key, recursive, sorted) 75 if err != nil { 76 return err 77 } 78 } 79 80 w.Header().Set("Content-Type", "application/json") 81 w.Header().Add("X-Etcd-Index", fmt.Sprint(s.Store().Index())) 82 w.Header().Add("X-Raft-Index", fmt.Sprint(s.CommitIndex())) 83 w.Header().Add("X-Raft-Term", fmt.Sprint(s.Term())) 84 w.WriteHeader(http.StatusOK) 85 b, _ := json.Marshal(event) 86 87 w.Write(b) 88 89 return nil 90 }