From ab285a90bba103d200b04e0c24e69a5817fcd440 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Mon, 1 Jul 2013 11:16:30 -0700 Subject: [PATCH] using go http lib to parse post body --- etcd.go | 16 ++++++-------- handlers.go | 58 ++++++++++++++++++++++++++++---------------------- store/store.go | 6 +++++- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/etcd.go b/etcd.go index 7d34cdc3a..721193143 100644 --- a/etcd.go +++ b/etcd.go @@ -53,18 +53,18 @@ var maxSize int func init() { flag.BoolVar(&verbose, "v", false, "verbose logging") - flag.StringVar(&cluster, "C", "", "join to a existing cluster") + flag.StringVar(&cluster, "C", "", "the ip address and port of a existing cluster") - flag.StringVar(&address, "a", "", "the ip address of the machine") - flag.IntVar(&clientPort, "c", 4001, "the port of client") - flag.IntVar(&serverPort, "s", 7001, "the port of server") + flag.StringVar(&address, "a", "", "the ip address of the local machine") + flag.IntVar(&clientPort, "c", 4001, "the port to communicate with clients") + flag.IntVar(&serverPort, "s", 7001, "the port to communicate with servers") flag.IntVar(&webPort, "w", -1, "the port of web interface") flag.StringVar(&serverCAFile, "serverCAFile", "", "the path of the CAFile") flag.StringVar(&serverCertFile, "serverCert", "", "the cert file of the server") flag.StringVar(&serverKeyFile, "serverKey", "", "the key file of the server") - flag.StringVar(&clientCAFile, "clientCAFile", "", "the path of the CAFile") + flag.StringVar(&clientCAFile, "clientCAFile", "", "the path of the client CAFile") flag.StringVar(&clientCertFile, "clientCert", "", "the cert file of the client") flag.StringVar(&clientKeyFile, "clientKey", "", "the key file of the client") @@ -316,10 +316,8 @@ func startServTransport(port int, st int) { func startClientTransport(port int, st int) { // external commands - http.HandleFunc("/set/", SetHttpHandler) - http.HandleFunc("/get/", GetHttpHandler) - http.HandleFunc("/delete/", DeleteHttpHandler) - http.HandleFunc("/watch/", WatchHttpHandler) + http.HandleFunc("/v1/keys/", Multiplexer) + http.HandleFunc("/v1/watch/", WatchHttpHandler) http.HandleFunc("/master", MasterHttpHandler) switch st { diff --git a/handlers.go b/handlers.go index 1fb429019..d84457a7b 100644 --- a/handlers.go +++ b/handlers.go @@ -8,7 +8,7 @@ import ( "io/ioutil" //"bytes" "strconv" - "strings" + //"strings" "time" ) @@ -95,30 +95,38 @@ func JoinHttpHandler(w http.ResponseWriter, req *http.Request) { //-------------------------------------- // external HTTP Handlers via client port //-------------------------------------- -func SetHttpHandler(w http.ResponseWriter, req *http.Request) { - key := req.URL.Path[len("/set/"):] - content, err := ioutil.ReadAll(req.Body) +func Multiplexer(w http.ResponseWriter, req *http.Request) { - if err != nil { - warn("raftd: Unable to read: %v", err) - w.WriteHeader(http.StatusInternalServerError) + if req.Method == "GET" { + GetHttpHandler(&w, req) + } else if req.Method == "POST" { + SetHttpHandler(&w, req) + } else if req.Method == "DELETE" { + DeleteHttpHandler(&w, req) + } else { + w.WriteHeader(http.StatusMethodNotAllowed) return } +} - debug("[recv] POST http://%v/set/%s [%s]", server.Name(), key, content) +func SetHttpHandler(w *http.ResponseWriter, req *http.Request) { + key := req.URL.Path[len("/v1/keys/"):] + + debug("[recv] POST http://%v/v1/keys/%s", server.Name(), key) command := &SetCommand{} command.Key = key - values := strings.Split(string(content), ",") - command.Value = values[0] + command.Value = req.FormValue("value") + strDuration := req.FormValue("ttl") + + if strDuration != "" { + duration, err := strconv.Atoi(strDuration) - if len(values) == 2 { - duration, err := strconv.Atoi(values[1]) if err != nil { warn("raftd: Bad duration: %v", err) - w.WriteHeader(http.StatusInternalServerError) + (*w).WriteHeader(http.StatusInternalServerError) return } command.ExpireTime = time.Now().Add(time.Second * (time.Duration)(duration)) @@ -126,19 +134,19 @@ func SetHttpHandler(w http.ResponseWriter, req *http.Request) { command.ExpireTime = time.Unix(0, 0) } - excute(command, &w, req) + excute(command, w, req) } -func DeleteHttpHandler(w http.ResponseWriter, req *http.Request) { - key := req.URL.Path[len("/delete/"):] +func DeleteHttpHandler(w *http.ResponseWriter, req *http.Request) { + key := req.URL.Path[len("/v1/keys/"):] - debug("[recv] GET http://%v/delete/%s", server.Name(), key) + debug("[recv] DELETE http://%v/v1/keys/%s", server.Name(), key) command := &DeleteCommand{} command.Key = key - excute(command, &w, req) + excute(command, w, req) } func excute(c Command, w *http.ResponseWriter, req *http.Request) { @@ -197,34 +205,34 @@ func MasterHttpHandler(w http.ResponseWriter, req *http.Request) { w.Write([]byte(server.Leader())) } -func GetHttpHandler(w http.ResponseWriter, req *http.Request) { - key := req.URL.Path[len("/get/"):] +func GetHttpHandler(w *http.ResponseWriter, req *http.Request) { + key := req.URL.Path[len("/v1/keys/"):] - debug("[recv] GET http://%v/get/%s", server.Name(), key) + debug("[recv] GET http://%v/v1/keys/%s", server.Name(), key) command := &GetCommand{} command.Key = key if body, err := command.Apply(server); err != nil { warn("raftd: Unable to write file: %v", err) - w.WriteHeader(http.StatusInternalServerError) + (*w).WriteHeader(http.StatusInternalServerError) return } else { - w.WriteHeader(http.StatusOK) + (*w).WriteHeader(http.StatusOK) body, ok := body.([]byte) if !ok { panic("wrong type") } - w.Write(body) + (*w).Write(body) return } } func WatchHttpHandler(w http.ResponseWriter, req *http.Request) { - key := req.URL.Path[len("/watch/"):] + key := req.URL.Path[len("/v1/watch/"):] command := &WatchCommand{} command.Key = key diff --git a/store/store.go b/store/store.go index 4d8a14a55..c10a93848 100644 --- a/store/store.go +++ b/store/store.go @@ -59,7 +59,7 @@ type Response struct { Action int `json:"action"` Key string `json:"key"` PrevValue string `json:"prevValue"` - Value string `json:"Value"` + Value string `json:"value"` // if the key existed before the action, this field should be true // if the key did not exist before the action, this field should be false @@ -263,6 +263,8 @@ func updateMap(index uint64, resp *Response) { // get the value of the key func Get(key string) Response { + key = "/" + key + key = path.Clean(key) node, ok := s.Nodes[key] @@ -290,6 +292,8 @@ func Get(key string) Response { // delete the key func Delete(key string, index uint64) ([]byte, error) { //update index + key = "/" + key + s.Index = index key = path.Clean(key)