using go http lib to parse post body
parent
f6b3d8a2af
commit
ab285a90bb
16
etcd.go
16
etcd.go
|
@ -53,18 +53,18 @@ var maxSize int
|
||||||
func init() {
|
func init() {
|
||||||
flag.BoolVar(&verbose, "v", false, "verbose logging")
|
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.StringVar(&address, "a", "", "the ip address of the local machine")
|
||||||
flag.IntVar(&clientPort, "c", 4001, "the port of client")
|
flag.IntVar(&clientPort, "c", 4001, "the port to communicate with clients")
|
||||||
flag.IntVar(&serverPort, "s", 7001, "the port of server")
|
flag.IntVar(&serverPort, "s", 7001, "the port to communicate with servers")
|
||||||
flag.IntVar(&webPort, "w", -1, "the port of web interface")
|
flag.IntVar(&webPort, "w", -1, "the port of web interface")
|
||||||
|
|
||||||
flag.StringVar(&serverCAFile, "serverCAFile", "", "the path of the CAFile")
|
flag.StringVar(&serverCAFile, "serverCAFile", "", "the path of the CAFile")
|
||||||
flag.StringVar(&serverCertFile, "serverCert", "", "the cert file of the server")
|
flag.StringVar(&serverCertFile, "serverCert", "", "the cert file of the server")
|
||||||
flag.StringVar(&serverKeyFile, "serverKey", "", "the key 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(&clientCertFile, "clientCert", "", "the cert file of the client")
|
||||||
flag.StringVar(&clientKeyFile, "clientKey", "", "the key 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) {
|
func startClientTransport(port int, st int) {
|
||||||
// external commands
|
// external commands
|
||||||
http.HandleFunc("/set/", SetHttpHandler)
|
http.HandleFunc("/v1/keys/", Multiplexer)
|
||||||
http.HandleFunc("/get/", GetHttpHandler)
|
http.HandleFunc("/v1/watch/", WatchHttpHandler)
|
||||||
http.HandleFunc("/delete/", DeleteHttpHandler)
|
|
||||||
http.HandleFunc("/watch/", WatchHttpHandler)
|
|
||||||
http.HandleFunc("/master", MasterHttpHandler)
|
http.HandleFunc("/master", MasterHttpHandler)
|
||||||
|
|
||||||
switch st {
|
switch st {
|
||||||
|
|
58
handlers.go
58
handlers.go
|
@ -8,7 +8,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
//"bytes"
|
//"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
//"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -95,30 +95,38 @@ func JoinHttpHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
// external HTTP Handlers via client port
|
// 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 {
|
if req.Method == "GET" {
|
||||||
warn("raftd: Unable to read: %v", err)
|
GetHttpHandler(&w, req)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
} else if req.Method == "POST" {
|
||||||
|
SetHttpHandler(&w, req)
|
||||||
|
} else if req.Method == "DELETE" {
|
||||||
|
DeleteHttpHandler(&w, req)
|
||||||
|
} else {
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
return
|
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 := &SetCommand{}
|
||||||
command.Key = key
|
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 {
|
if err != nil {
|
||||||
warn("raftd: Bad duration: %v", err)
|
warn("raftd: Bad duration: %v", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
(*w).WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
command.ExpireTime = time.Now().Add(time.Second * (time.Duration)(duration))
|
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)
|
command.ExpireTime = time.Unix(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
excute(command, &w, req)
|
excute(command, w, req)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteHttpHandler(w http.ResponseWriter, req *http.Request) {
|
func DeleteHttpHandler(w *http.ResponseWriter, req *http.Request) {
|
||||||
key := req.URL.Path[len("/delete/"):]
|
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 := &DeleteCommand{}
|
||||||
command.Key = key
|
command.Key = key
|
||||||
|
|
||||||
excute(command, &w, req)
|
excute(command, w, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func excute(c Command, w *http.ResponseWriter, req *http.Request) {
|
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()))
|
w.Write([]byte(server.Leader()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetHttpHandler(w http.ResponseWriter, req *http.Request) {
|
func GetHttpHandler(w *http.ResponseWriter, req *http.Request) {
|
||||||
key := req.URL.Path[len("/get/"):]
|
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 := &GetCommand{}
|
||||||
command.Key = key
|
command.Key = key
|
||||||
|
|
||||||
if body, err := command.Apply(server); err != nil {
|
if body, err := command.Apply(server); err != nil {
|
||||||
warn("raftd: Unable to write file: %v", err)
|
warn("raftd: Unable to write file: %v", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
(*w).WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusOK)
|
(*w).WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
body, ok := body.([]byte)
|
body, ok := body.([]byte)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("wrong type")
|
panic("wrong type")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(body)
|
(*w).Write(body)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WatchHttpHandler(w http.ResponseWriter, req *http.Request) {
|
func WatchHttpHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
key := req.URL.Path[len("/watch/"):]
|
key := req.URL.Path[len("/v1/watch/"):]
|
||||||
|
|
||||||
command := &WatchCommand{}
|
command := &WatchCommand{}
|
||||||
command.Key = key
|
command.Key = key
|
||||||
|
|
|
@ -59,7 +59,7 @@ type Response struct {
|
||||||
Action int `json:"action"`
|
Action int `json:"action"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
PrevValue string `json:"prevValue"`
|
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 existed before the action, this field should be true
|
||||||
// if the key did not exist before the action, this field should be false
|
// 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
|
// get the value of the key
|
||||||
func Get(key string) Response {
|
func Get(key string) Response {
|
||||||
|
key = "/" + key
|
||||||
|
|
||||||
key = path.Clean(key)
|
key = path.Clean(key)
|
||||||
|
|
||||||
node, ok := s.Nodes[key]
|
node, ok := s.Nodes[key]
|
||||||
|
@ -290,6 +292,8 @@ func Get(key string) Response {
|
||||||
// delete the key
|
// delete the key
|
||||||
func Delete(key string, index uint64) ([]byte, error) {
|
func Delete(key string, index uint64) ([]byte, error) {
|
||||||
//update index
|
//update index
|
||||||
|
key = "/" + key
|
||||||
|
|
||||||
s.Index = index
|
s.Index = index
|
||||||
|
|
||||||
key = path.Clean(key)
|
key = path.Clean(key)
|
||||||
|
|
Loading…
Reference in New Issue