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 cardinality and label names/values requests handling on POST requests #5524

Merged
merged 5 commits into from
Jul 18, 2023

Conversation

pracucci
Copy link
Collaborator

@pracucci pracucci commented Jul 17, 2023

What this PR does

We found a bug introduced in #5212 and #5426 which caused POST requests returning wrong results. The problem is that, when the cardinality and/or label names/values result cache is enabled, the caching middleware consumes the http.Request Body and so the body will be empty when later read to forward it to the query-scheduler or querier.

In this PR I propose a fix. The fix consists in consuming the Body and then replacing it with the original content. It's not a new approach, in fact we were already doing it in Handler.ServeHTTP() so I've re-used that code, moving it to a common utility function.

Note to reviewers:

  • The modified integration and unit tests fail with the previous buggy version

Which issue(s) this PR fixes or relates to

N/A

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

…ests

Signed-off-by: Marco Pracucci <marco@pracucci.com>
Comment on lines +313 to +314
origBody := r.Body
defer func() { _ = origBody.Close() }()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ParseRequestFormWithoutConsumingBody() logic has been copied from handler.ServeHTTP(). However, previously we didn't close the original Body (in handler.ServeHTTP() we just close the replaced req.Body) but I think we actually have to close the original Body too, so I've added this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you really need to call Close() only if the resource would be leaked otherwise. Like a file descriptor or some pooled memory. Otherwise GC will just clean it up. Probably doesn't hurt to have an extra defer Close, although if Close is transitive, that means calling it twice and the interface says that "The behavior of Close after the first call is undefined."

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference to the original Body is lost, so I'm not sure there's a real risk of closing it twice. On the contrary, I think none else could close it if we don't close it here.

Signed-off-by: Marco Pracucci <marco@pracucci.com>
Signed-off-by: Marco Pracucci <marco@pracucci.com>
Signed-off-by: Marco Pracucci <marco@pracucci.com>
value := req.FormValue(paramName)
func parseRequestTimeParam(values url.Values, paramName string, defaultValue int64) (int64, error) {
var value string
if len(values[paramName]) > 0 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to reviewers: this is the same thing done by req.FormValue() (it picks the 1st one).

Signed-off-by: Marco Pracucci <marco@pracucci.com>
@pracucci pracucci marked this pull request as ready for review July 17, 2023 15:21
@pracucci pracucci requested a review from a team as a code owner July 17, 2023 15:21
Copy link
Contributor

@krajorama krajorama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pracucci pracucci merged commit 0ad2f46 into main Jul 18, 2023
@pracucci pracucci deleted the fix-query-results-cache-for-post-requests branch July 18, 2023 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants