Skip to content

Commit

Permalink
Always set the Content-Type header when a body is present (#10204)
Browse files Browse the repository at this point in the history
* Always set the Content-Type header when a body is present

Closes #10011

* Add Changelog entry

* Add more Content-Type exceptions

* Fix tests
  • Loading branch information
remilapeyre authored and banks committed May 25, 2021
1 parent f054099 commit 4677321
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .changelog/10204.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
api: The `Content-Type` header is now always set when a body is present in a request.
```
1 change: 1 addition & 0 deletions api/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,7 @@ func (a *ACL) PolicyList(q *QueryOptions) ([]*ACLPolicyListEntry, *QueryMeta, er
func (a *ACL) RulesTranslate(rules io.Reader) (string, error) {
r := a.c.newRequest("POST", "/v1/acl/rules/translate")
r.body = rules
r.header.Set("Content-Type", "text/plain")
rtt, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
return "", err
Expand Down
6 changes: 6 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,12 @@ func (r *request) toHTTP() (*http.Request, error) {
req.Host = r.url.Host
req.Header = r.header

// Content-Type must always be set when a body is present
// See https://github.com/hashicorp/consul/issues/10011
if req.Body != nil && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "application/json")
}

// Setup auth
if r.config.HttpAuth != nil {
req.SetBasicAuth(r.config.HttpAuth.Username, r.config.HttpAuth.Password)
Expand Down
46 changes: 45 additions & 1 deletion api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
Expand Down Expand Up @@ -810,7 +811,17 @@ func TestAPI_SetWriteOptions(t *testing.T) {

func TestAPI_Headers(t *testing.T) {
t.Parallel()
c, s := makeClient(t)

var request *http.Request
c, s := makeClientWithConfig(t, func(c *Config) {
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.Proxy = func(r *http.Request) (*url.URL, error) {
// Keep track of the last request sent
request = r
return nil, nil
}
c.Transport = transport
}, nil)
defer s.Stop()

if len(c.Headers()) != 0 {
Expand All @@ -836,6 +847,39 @@ func TestAPI_Headers(t *testing.T) {
if r.header.Get("Auth") != "Token" {
t.Fatalf("Auth header not set: %v", r.header)
}

kv := c.KV()
_, err := kv.Put(&KVPair{Key: "test-headers", Value: []byte("foo")}, nil)
require.NoError(t, err)
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))

_, _, err = kv.Get("test-headers", nil)
require.NoError(t, err)
require.Equal(t, "", request.Header.Get("Content-Type"))

_, err = kv.Delete("test-headers", nil)
require.NoError(t, err)
require.Equal(t, "", request.Header.Get("Content-Type"))

err = c.Snapshot().Restore(nil, strings.NewReader("foo"))
require.Error(t, err)
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))

_, err = c.ACL().RulesTranslate(strings.NewReader(`
agent "" {
policy = "read"
}
`))
// ACL support is disabled
require.Error(t, err)
require.Equal(t, "text/plain", request.Header.Get("Content-Type"))

_, _, err = c.Event().Fire(&UserEvent{
Name: "test",
Payload: []byte("foo"),
}, nil)
require.NoError(t, err)
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))
}

func TestAPI_RequestToHTTP(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions api/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func (e *Event) Fire(params *UserEvent, q *WriteOptions) (string, *WriteMeta, er
if params.Payload != nil {
r.body = bytes.NewReader(params.Payload)
}
r.header.Set("Content-Type", "application/octet-stream")

rtt, resp, err := requireOK(e.c.doRequest(r))
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions api/kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func (k *KV) put(key string, params map[string]string, body []byte, q *WriteOpti
r.params.Set(param, val)
}
r.body = bytes.NewReader(body)
r.header.Set("Content-Type", "application/octet-stream")
rtt, resp, err := requireOK(k.c.doRequest(r))
if err != nil {
return false, nil, err
Expand Down
1 change: 1 addition & 0 deletions api/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func (s *Snapshot) Save(q *QueryOptions) (io.ReadCloser, *QueryMeta, error) {
func (s *Snapshot) Restore(q *WriteOptions, in io.Reader) error {
r := s.c.newRequest("PUT", "/v1/snapshot")
r.body = in
r.header.Set("Content-Type", "application/octet-stream")
r.setWriteOptions(q)
_, _, err := requireOK(s.c.doRequest(r))
if err != nil {
Expand Down

0 comments on commit 4677321

Please sign in to comment.