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

Always set the Content-Type header when a body is present #10204

Closed

Conversation

remilapeyre
Copy link
Contributor

Closes #10011

@vercel vercel bot temporarily deployed to Preview – consul May 7, 2021 10:26 Inactive
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging May 7, 2021 10:26 Inactive
@vercel vercel bot temporarily deployed to Preview – consul May 7, 2021 12:08 Inactive
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging May 7, 2021 12:08 Inactive
@remilapeyre remilapeyre marked this pull request as ready for review May 7, 2021 12:21
remilapeyre added a commit to remilapeyre/terraform-provider-consul that referenced this pull request May 7, 2021
This define a custom RoundTripper to add the Content-Type header when
it is needed. This commit should be reverted once hashicorp/consul#10204
is merged and released upstream.

I did not write a test for this change but tested locally and the
header is correctly present for PUT requests but not for GET or DELETE.
@blake blake added the type/enhancement Proposed improvement or new feature label May 10, 2021
remilapeyre added a commit to hashicorp/terraform-provider-consul that referenced this pull request May 12, 2021
This define a custom RoundTripper to add the Content-Type header when
it is needed. This commit should be reverted once hashicorp/consul#10204
is merged and released upstream.

I did not write a test for this change but tested locally and the
header is correctly present for PUT requests but not for GET or DELETE.
Copy link
Member

@banks banks left a comment

Choose a reason for hiding this comment

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

Thanks @remilapeyre this is a great PR.

I think it can probably be merged as-is I just had one Q about those non-JSON exceptions and whether we need to do any more diligence to make sure we didn't miss any other edge cases?

@@ -100,6 +100,7 @@ func (op *Operator) LicensePut(license string, opts *WriteOptions) (*LicenseRepl
r := op.c.newRequest("PUT", "/v1/operator/license")
r.setWriteOptions(opts)
r.body = strings.NewReader(license)
r.header.Set("Content-Type", "application/octet-stream")
Copy link
Member

Choose a reason for hiding this comment

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

Great job finding these exceptions! How did you find them out of interest? Did tests break for these endpoints because of the wrong content type?

I can't think of any other exceptions but then I doubt I'd have remembered this one either so wondering if there is anything else we should do to be sure we caught all the non-json endpoints.

If you already went through exhaustively though then great!

@remilapeyre
Copy link
Contributor Author

I just remembered those two and looked briefly at the documentation and thought I had found them all. Looking at the output of rg -P 'curl.*?```' website/content/api-docs/ --multiline --multiline-dotall actually finds more cases where the payload sent is not JSON. I've added them but I'm not sure if it's possible to be sure to have found them all without doing something more complicated.

@vercel vercel bot temporarily deployed to Preview – consul May 16, 2021 16:11 Inactive
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging May 16, 2021 16:11 Inactive
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging May 16, 2021 16:31 Inactive
@vercel vercel bot temporarily deployed to Preview – consul May 16, 2021 16:31 Inactive
Copy link
Member

@banks banks left a comment

Choose a reason for hiding this comment

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

Oh nice idea!

I tried a few things in the code to pick up possible others:

$ rg -P 'io.Copy' agent/*endpoint.go
agent/operator_license_endpoint.go
37:	if _, err := io.Copy(buf, req.Body); err != nil {

agent/kvs_endpoint.go
219:	if _, err := io.Copy(buf, req.Body); err != nil {

agent/event_endpoint.go
49:		if _, err := io.Copy(&buf, req.Body); err != nil

Which you've already got all of anyway.

I also tried:

rg -P '\.Body' agent/*.go | rg -v 'decodeBody\(|DecodeJSON\(|_test.go'
agent/watch_handler.go:		defer resp.Body.Close()
agent/watch_handler.go:		io.Copy(output, resp.Body)
agent/txn_endpoint.go:	req.Body = http.MaxBytesReader(resp, req.Body, maxTxnLen)
agent/txn_endpoint.go:							Body:                           check.Definition.Body,
agent/snapshot_endpoint.go:		if err := s.agent.delegate.SnapshotRPC(&args, req.Body, resp, nil); err != nil {
agent/operator_license_endpoint.go:	if _, err := io.Copy(buf, req.Body); err != nil {
agent/namespace_endpoint.go:	if req.Body == nil {
agent/kvs_endpoint.go:	if _, err := io.Copy(buf, req.Body); err != nil {
agent/event_endpoint.go:		if _, err := io.Copy(&buf, req.Body); err != nil {
agent/http.go:	if req.Body == nil {
agent/http.go:	dec := json.NewDecoder(req.Body)
agent/acl_endpoint.go:	policyBytes, err := ioutil.ReadAll(req.Body)
agent/agent.go:				Body:            chkType.Body,

Which are all false-positives except one: https://www.consul.io/api-docs/acl#translate-rules expects a raw HCL ACL token policy as the body so it probably needs a different content type. So I think we need an update here too:

consul/api/acl.go

Lines 896 to 918 in cc5dba1

// RulesTranslate translates the legacy rule syntax into the current syntax.
//
// Deprecated: Support for the legacy syntax translation will be removed
// when legacy ACL support is removed.
func (a *ACL) RulesTranslate(rules io.Reader) (string, error) {
r := a.c.newRequest("POST", "/v1/acl/rules/translate")
r.body = rules
rtt, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
return "", err
}
defer resp.Body.Close()
qm := &QueryMeta{}
parseQueryMeta(resp, qm)
qm.RequestTime = rtt
ruleBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("Failed to read translated rule body: %v", err)
}
return string(ruleBytes), nil
}

I think with that we can merge!

Thanks for this Remi! Much appreciated.

@remilapeyre
Copy link
Contributor Author

Hi Paul I added the Content Type for the ACL and fixed the conflicts. I think it should be good now :)

@remilapeyre remilapeyre requested a review from banks May 25, 2021 11:43
Copy link
Member

@banks banks left a comment

Choose a reason for hiding this comment

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

Perfect!

Thanks for getting this in Remi!

@banks
Copy link
Member

banks commented May 25, 2021

GitHub did something strange here when I merged - it errored on my several times but when I went to merge manually I found the merge actually worked and this is already in master: 213524a

Despite that GH isn't marking this PR as merged and if I attempt to merge again it just creates another empty commit on master and fails again.

So I'll manually close this and go and do the 1.10 backport cherry-pick by hand.

@banks banks closed this May 25, 2021
banks pushed a commit that referenced this pull request May 25, 2021
* Always set the Content-Type header when a body is present

Closes #10011

* Add Changelog entry

* Add more Content-Type exceptions

* Fix tests
dhiaayachi pushed a commit that referenced this pull request May 25, 2021
* Always set the Content-Type header when a body is present

Closes #10011

* Add Changelog entry

* Add more Content-Type exceptions

* Fix tests
dhiaayachi pushed a commit that referenced this pull request May 25, 2021
* Always set the Content-Type header when a body is present

Closes #10011

* Add Changelog entry

* Add more Content-Type exceptions

* Fix tests
dhiaayachi pushed a commit that referenced this pull request May 25, 2021
* Always set the Content-Type header when a body is present

Closes #10011

* Add Changelog entry

* Add more Content-Type exceptions

* Fix tests
dhiaayachi pushed a commit that referenced this pull request May 25, 2021
* Always set the Content-Type header when a body is present

Closes #10011

* Add Changelog entry

* Add more Content-Type exceptions

* Fix tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/enhancement Proposed improvement or new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Set Content-Type header for requests from Consul Go API
3 participants