mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
@@ -43,7 +43,7 @@ import (
|
||||
const (
|
||||
keysPrefix = "/v2/keys"
|
||||
deprecatedMachinesPrefix = "/v2/machines"
|
||||
adminMembersPrefix = "/v2/admin/members/"
|
||||
adminMembersPrefix = "/v2/admin/members"
|
||||
statsPrefix = "/v2/stats"
|
||||
versionPrefix = "/version"
|
||||
)
|
||||
@@ -80,6 +80,7 @@ func NewClientHandler(server *etcdserver.EtcdServer) http.Handler {
|
||||
mux.HandleFunc(statsPrefix+"/self", sh.serveSelf)
|
||||
mux.HandleFunc(statsPrefix+"/leader", sh.serveLeader)
|
||||
mux.Handle(adminMembersPrefix, amh)
|
||||
mux.Handle(adminMembersPrefix+"/", amh)
|
||||
mux.Handle(deprecatedMachinesPrefix, dmh)
|
||||
return mux
|
||||
}
|
||||
@@ -159,7 +160,7 @@ func (h *adminMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
if s := strings.TrimPrefix(r.URL.Path, adminMembersPrefix); s != "" {
|
||||
if trimPrefix(r.URL.Path, adminMembersPrefix) != "" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
@@ -203,7 +204,11 @@ func (h *adminMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
log.Printf("etcdhttp: %v", err)
|
||||
}
|
||||
case "DELETE":
|
||||
idStr := strings.TrimPrefix(r.URL.Path, adminMembersPrefix)
|
||||
idStr := trimPrefix(r.URL.Path, adminMembersPrefix)
|
||||
if idStr == "" {
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
id, err := strconv.ParseUint(idStr, 16, 64)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
@@ -516,6 +521,14 @@ func getBool(form url.Values, key string) (b bool, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// trimPrefix removes a given prefix and any slash following the prefix
|
||||
// e.g.: trimPrefix("foo", "foo") == trimPrefix("foo/", "foo") == ""
|
||||
func trimPrefix(p, prefix string) (s string) {
|
||||
s = strings.TrimPrefix(p, prefix)
|
||||
s = strings.TrimPrefix(s, "/")
|
||||
return
|
||||
}
|
||||
|
||||
func newMemberCollection(ms []*etcdserver.Member) httptypes.MemberCollection {
|
||||
c := httptypes.MemberCollection(make([]httptypes.Member, len(ms)))
|
||||
|
||||
|
||||
@@ -574,6 +574,7 @@ func TestServeAdminMembers(t *testing.T) {
|
||||
wbody string
|
||||
}{
|
||||
{adminMembersPrefix, http.StatusOK, "application/json", wmc},
|
||||
{adminMembersPrefix + "/", http.StatusOK, "application/json", wmc},
|
||||
{path.Join(adminMembersPrefix, "100"), http.StatusNotFound, "text/plain; charset=utf-8", "404 page not found\n"},
|
||||
{path.Join(adminMembersPrefix, "foobar"), http.StatusNotFound, "text/plain; charset=utf-8", "404 page not found\n"},
|
||||
}
|
||||
@@ -778,6 +779,16 @@ func TestServeAdminMembersFail(t *testing.T) {
|
||||
|
||||
http.StatusInternalServerError,
|
||||
},
|
||||
{
|
||||
// etcdserver.RemoveMember error
|
||||
&http.Request{
|
||||
URL: mustNewURL(t, adminMembersPrefix),
|
||||
Method: "DELETE",
|
||||
},
|
||||
nil,
|
||||
|
||||
http.StatusMethodNotAllowed,
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
h := &adminMembersHandler{
|
||||
@@ -1540,3 +1551,20 @@ func TestTrimNodeExternPrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrimPrefix(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
prefix string
|
||||
w string
|
||||
}{
|
||||
{"/v2/admin/members", "/v2/admin/members", ""},
|
||||
{"/v2/admin/members/", "/v2/admin/members", ""},
|
||||
{"/v2/admin/members/foo", "/v2/admin/members", "foo"},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
if g := trimPrefix(tt.in, tt.prefix); g != tt.w {
|
||||
t.Errorf("#%d: trimPrefix = %q, want %q", i, g, tt.w)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user