Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: stale querystring parameter value as boolean #15605

Merged
merged 9 commits into from
Jan 1, 2023
15 changes: 11 additions & 4 deletions command/agent/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -783,10 +783,17 @@ func parseWait(resp http.ResponseWriter, req *http.Request, b *structs.QueryOpti
}

// parseConsistency is used to parse the ?stale query params.
func parseConsistency(req *http.Request, b *structs.QueryOptions) {
func parseConsistency(resp http.ResponseWriter, req *http.Request, b *structs.QueryOptions) {
query := req.URL.Query()
if _, ok := query["stale"]; ok {
b.AllowStale = true
if staleVal, ok := query["stale"]; ok {
if staleVal[0] == "true" || staleVal[0] == "" {
dttung2905 marked this conversation as resolved.
Show resolved Hide resolved
b.AllowStale = true
} else if staleVal[0] == "false" {
// fall through
dttung2905 marked this conversation as resolved.
Show resolved Hide resolved
} else {
resp.WriteHeader(400)
resp.Write([]byte(fmt.Sprintf("Expect `true` or `false` for `stale` query string parameter, got %s", staleVal[0])))
}
}
}

Expand Down Expand Up @@ -884,7 +891,7 @@ func (s *HTTPServer) parseToken(req *http.Request, token *string) {
func (s *HTTPServer) parse(resp http.ResponseWriter, req *http.Request, r *string, b *structs.QueryOptions) bool {
s.parseRegion(req, r)
s.parseToken(req, &b.AuthToken)
parseConsistency(req, b)
parseConsistency(resp, req, b)
parsePrefix(req, b)
parseNamespace(req, &b.Namespace)
parsePagination(req, b)
Expand Down
28 changes: 22 additions & 6 deletions command/agent/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,16 +476,31 @@ func TestParseWait_InvalidIndex(t *testing.T) {
func TestParseConsistency(t *testing.T) {
ci.Parallel(t)
var b structs.QueryOptions
var resp *httptest.ResponseRecorder

testCases := [3]string{"/v1/catalog/nodes?stale", "/v1/catalog/nodes?stale=true", "/v1/catalog/nodes?stale=false"}
for _, url := range testCases {
req, err := http.NewRequest("GET",
url, nil)
dttung2905 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
t.Fatalf("err: %v", err)
}
dttung2905 marked this conversation as resolved.
Show resolved Hide resolved
resp = httptest.NewRecorder()
parseConsistency(resp, req, &b)
if !b.AllowStale {
t.Fatalf("Bad: %v", b)
}
dttung2905 marked this conversation as resolved.
Show resolved Hide resolved
}

req, err := http.NewRequest("GET",
"/v1/catalog/nodes?stale", nil)
"/v1/catalog/nodes?stale=random", nil)
if err != nil {
t.Fatalf("err: %v", err)
}

parseConsistency(req, &b)
if !b.AllowStale {
t.Fatalf("Bad: %v", b)
resp = httptest.NewRecorder()
parseConsistency(resp, req, &b)
if resp.Code != 400 {
t.Fatalf("bad code: %v", resp.Code)
}
dttung2905 marked this conversation as resolved.
Show resolved Hide resolved

b = structs.QueryOptions{}
Expand All @@ -495,7 +510,8 @@ func TestParseConsistency(t *testing.T) {
t.Fatalf("err: %v", err)
}

parseConsistency(req, &b)
resp = httptest.NewRecorder()
parseConsistency(resp, req, &b)
if b.AllowStale {
t.Fatalf("Bad: %v", b)
}
Expand Down