fix(v2): Use case-insensitive check on bool query params

Fix issue #261
This commit is contained in:
Brian Waldon 2014-02-07 12:48:18 -08:00
parent ed3d63248a
commit 42363001b4
4 changed files with 100 additions and 11 deletions

36
http/query_params.go Normal file
View File

@ -0,0 +1,36 @@
package http
import (
"net/http"
"strings"
)
func NewLowerQueryParamsHandler(hdlr http.Handler) *LowerQueryParamsHandler {
return &LowerQueryParamsHandler{hdlr}
}
type LowerQueryParamsHandler struct {
Handler http.Handler
}
func (h *LowerQueryParamsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
err := req.ParseForm()
if err == nil {
lowerBoolQueryParams(req)
}
h.Handler.ServeHTTP(w, req)
}
func lowerBoolQueryParams(req *http.Request) {
form := req.Form
for key, vals := range form {
for i, val := range vals {
lowered := strings.ToLower(val)
if lowered == "true" || lowered == "false" {
req.Form[key][i] = lowered
} else {
req.Form[key][i] = val
}
}
}
}

46
http/query_params_test.go Normal file
View File

@ -0,0 +1,46 @@
package http
import (
"net/http"
"testing"
)
type NilResponseWriter struct{}
func (w NilResponseWriter) Header() http.Header {
return http.Header{}
}
func (w NilResponseWriter) Write(data []byte) (int, error) {
return 0, nil
}
func (w NilResponseWriter) WriteHeader(code int) {
return
}
type FunctionHandler struct {
f func(*http.Request)
}
func (h FunctionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.f(r)
}
func TestQueryParamsLowered(t *testing.T) {
assertFunc := func(req *http.Request) {
if len(req.Form["One"]) != 1 || req.Form["One"][0] != "true" {
t.Errorf("Unexpected value for One: %s", req.Form["One"])
} else if len(req.Form["TWO"]) != 1 || req.Form["TWO"][0] != "false" {
t.Errorf("Unexpected value for TWO")
} else if len(req.Form["three"]) != 2 || req.Form["three"][0] != "true" || req.Form["three"][1] != "false" {
t.Errorf("Unexpected value for three")
}
}
assertHdlr := FunctionHandler{assertFunc}
hdlr := NewLowerQueryParamsHandler(assertHdlr)
respWriter := NilResponseWriter{}
req, _ := http.NewRequest("GET", "http://example.com?One=TRUE&TWO=False&three=true&three=FALSE", nil)
hdlr.ServeHTTP(respWriter, req)
}

View File

@ -15,6 +15,7 @@ import (
"github.com/coreos/etcd/log"
"github.com/coreos/etcd/metrics"
"github.com/coreos/etcd/mod"
ehttp "github.com/coreos/etcd/http"
uhttp "github.com/coreos/etcd/pkg/http"
"github.com/coreos/etcd/server/v1"
"github.com/coreos/etcd/server/v2"
@ -107,17 +108,20 @@ func (s *Server) installV1(r *mux.Router) {
}
func (s *Server) installV2(r *mux.Router) {
s.handleFuncV2(r, "/v2/keys/{key:.*}", v2.GetHandler).Methods("GET")
s.handleFuncV2(r, "/v2/keys/{key:.*}", v2.PostHandler).Methods("POST")
s.handleFuncV2(r, "/v2/keys/{key:.*}", v2.PutHandler).Methods("PUT")
s.handleFuncV2(r, "/v2/keys/{key:.*}", v2.DeleteHandler).Methods("DELETE")
s.handleFunc(r, "/v2/leader", s.GetLeaderHandler).Methods("GET")
s.handleFunc(r, "/v2/machines", s.GetPeersHandler).Methods("GET")
s.handleFunc(r, "/v2/peers", s.GetPeersHandler).Methods("GET")
s.handleFunc(r, "/v2/stats/self", s.GetStatsHandler).Methods("GET")
s.handleFunc(r, "/v2/stats/leader", s.GetLeaderStatsHandler).Methods("GET")
s.handleFunc(r, "/v2/stats/store", s.GetStoreStatsHandler).Methods("GET")
s.handleFunc(r, "/v2/speedTest", s.SpeedTestHandler).Methods("GET")
r2 := mux.NewRouter()
r.PathPrefix("/v2").Handler(ehttp.NewLowerQueryParamsHandler(r2))
s.handleFuncV2(r2, "/v2/keys/{key:.*}", v2.GetHandler).Methods("GET")
s.handleFuncV2(r2, "/v2/keys/{key:.*}", v2.PostHandler).Methods("POST")
s.handleFuncV2(r2, "/v2/keys/{key:.*}", v2.PutHandler).Methods("PUT")
s.handleFuncV2(r2, "/v2/keys/{key:.*}", v2.DeleteHandler).Methods("DELETE")
s.handleFunc(r2, "/v2/leader", s.GetLeaderHandler).Methods("GET")
s.handleFunc(r2, "/v2/machines", s.GetPeersHandler).Methods("GET")
s.handleFunc(r2, "/v2/peers", s.GetPeersHandler).Methods("GET")
s.handleFunc(r2, "/v2/stats/self", s.GetStatsHandler).Methods("GET")
s.handleFunc(r2, "/v2/stats/leader", s.GetLeaderStatsHandler).Methods("GET")
s.handleFunc(r2, "/v2/stats/store", s.GetStoreStatsHandler).Methods("GET")
s.handleFunc(r2, "/v2/speedTest", s.SpeedTestHandler).Methods("GET")
}
func (s *Server) installMod(r *mux.Router) {

View File

@ -2,6 +2,9 @@
. ./build
go test -i ./http
go test -v ./http
go test -i ./store
go test -v ./store