mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
Validate /fragment/nodes arguments. Fixes #652
This commit is contained in:
parent
6374fedd7a
commit
8e6041d0fe
2 changed files with 68 additions and 1 deletions
60
handler.go
60
handler.go
|
|
@ -27,6 +27,7 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
// Imported for its side-effect of registering pprof endpoints with the server.
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
|
|
@ -70,6 +71,9 @@ type Handler struct {
|
|||
|
||||
// The writer for any logging.
|
||||
LogOutput io.Writer
|
||||
|
||||
// Keeps the query argument validators for each handler
|
||||
validators map[string]queryValidationSpec
|
||||
}
|
||||
|
||||
// externalPrefixFlag denotes endpoints that are intended to be exposed to clients.
|
||||
|
|
@ -91,9 +95,19 @@ func NewHandler() *Handler {
|
|||
LogOutput: os.Stderr,
|
||||
}
|
||||
handler.Router = NewRouter(handler)
|
||||
handler.populateValidators()
|
||||
return handler
|
||||
}
|
||||
|
||||
func (h *Handler) populateValidators() {
|
||||
h.validators = map[string]queryValidationSpec{}
|
||||
// GetFragmentNodes validator
|
||||
validator := NewQueryValidationSpec()
|
||||
validator.Required("slice")
|
||||
validator.Optional("index")
|
||||
h.validators["GetFragmentNodes"] = validator
|
||||
}
|
||||
|
||||
// NewRouter creates a Gorilla Mux http router.
|
||||
func NewRouter(handler *Handler) *mux.Router {
|
||||
router := mux.NewRouter()
|
||||
|
|
@ -1342,12 +1356,18 @@ func (h *Handler) handleGetExportCSV(w http.ResponseWriter, r *http.Request) {
|
|||
// handleGetFragmentNodes handles /fragment/nodes requests.
|
||||
func (h *Handler) handleGetFragmentNodes(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
validator := h.validators["GetFragmentNodes"]
|
||||
err := validator.validate(q)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
index := q.Get("index")
|
||||
|
||||
// Read slice parameter.
|
||||
slice, err := strconv.ParseUint(q.Get("slice"), 10, 64)
|
||||
if err != nil {
|
||||
http.Error(w, "slice required", http.StatusBadRequest)
|
||||
http.Error(w, "slice should be an unsigned integer", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -2057,3 +2077,41 @@ func (h *Handler) handleGetID(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
type defaultClusterMessageResponse struct{}
|
||||
|
||||
type queryValidationSpec struct {
|
||||
required []string
|
||||
args map[string]bool
|
||||
}
|
||||
|
||||
func NewQueryValidationSpec() queryValidationSpec {
|
||||
return queryValidationSpec{
|
||||
args: map[string]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *queryValidationSpec) Required(args ...string) {
|
||||
s.required = args
|
||||
for _, arg := range args {
|
||||
s.args[arg] = true
|
||||
}
|
||||
}
|
||||
|
||||
func (s *queryValidationSpec) Optional(args ...string) {
|
||||
for _, arg := range args {
|
||||
s.args[arg] = true
|
||||
}
|
||||
}
|
||||
|
||||
func (s queryValidationSpec) validate(query url.Values) error {
|
||||
for _, req := range s.required {
|
||||
if query.Get(req) == "" {
|
||||
return errors.New(fmt.Sprintf("%s is required", req))
|
||||
}
|
||||
}
|
||||
for k, _ := range query {
|
||||
if _, ok := s.args[k]; !ok {
|
||||
return errors.New(fmt.Sprintf("%s is not a valid argument", k))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1198,6 +1198,15 @@ func TestHandler_Fragment_Nodes(t *testing.T) {
|
|||
} else if w.Body.String() != `[{"scheme":"http","host":"host2"},{"scheme":"http","host":"host0"}]`+"\n" {
|
||||
t.Fatalf("unexpected body: %q", w.Body.String())
|
||||
}
|
||||
|
||||
// invalid argument should return BadRequest
|
||||
w = httptest.NewRecorder()
|
||||
r = test.MustNewHTTPRequest("GET", "/fragment/nodes?db=X&slice=0", nil)
|
||||
h.ServeHTTP(w, r)
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status code: %d", w.Code)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Ensure the handler can return expvars without panicking.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue