Disable Content-Type auto-detection by default
This commit is contained in:
parent
4d86668af3
commit
db287c4d31
20 changed files with 193 additions and 168 deletions
46
pkg/middlewares/contenttype/content_type.go
Normal file
46
pkg/middlewares/contenttype/content_type.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package contenttype
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares"
|
||||
)
|
||||
|
||||
const (
|
||||
typeName = "ContentType"
|
||||
)
|
||||
|
||||
// ContentType is a middleware used to activate Content-Type auto-detection.
|
||||
type contentType struct {
|
||||
next http.Handler
|
||||
name string
|
||||
}
|
||||
|
||||
// New creates a new handler.
|
||||
func New(ctx context.Context, next http.Handler, name string) (http.Handler, error) {
|
||||
middlewares.GetLogger(ctx, name, typeName).Debug().Msg("Creating middleware")
|
||||
return &contentType{next: next, name: name}, nil
|
||||
}
|
||||
|
||||
func (c *contentType) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
// Re-enable auto-detection.
|
||||
if ct, ok := rw.Header()["Content-Type"]; ok && ct == nil {
|
||||
middlewares.GetLogger(req.Context(), c.name, typeName).
|
||||
Debug().Msg("Enable Content-Type auto-detection.")
|
||||
delete(rw.Header(), "Content-Type")
|
||||
}
|
||||
|
||||
c.next.ServeHTTP(rw, req)
|
||||
}
|
||||
|
||||
func DisableAutoDetection(next http.Handler) http.HandlerFunc {
|
||||
return func(rw http.ResponseWriter, req *http.Request) {
|
||||
// Prevent Content-Type auto-detection.
|
||||
if _, ok := rw.Header()["Content-Type"]; !ok {
|
||||
rw.Header()["Content-Type"] = nil
|
||||
}
|
||||
|
||||
next.ServeHTTP(rw, req)
|
||||
}
|
||||
}
|
79
pkg/middlewares/contenttype/content_type_test.go
Normal file
79
pkg/middlewares/contenttype/content_type_test.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package contenttype
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v2/pkg/testhelpers"
|
||||
)
|
||||
|
||||
func TestAutoDetection(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
autoDetect bool
|
||||
contentType string
|
||||
wantContentType string
|
||||
}{
|
||||
{
|
||||
desc: "Keep the Content-Type returned by the server",
|
||||
autoDetect: false,
|
||||
contentType: "application/json",
|
||||
wantContentType: "application/json",
|
||||
},
|
||||
{
|
||||
desc: "Don't auto-detect Content-Type header by default when not set by the server",
|
||||
autoDetect: false,
|
||||
contentType: "",
|
||||
wantContentType: "",
|
||||
},
|
||||
{
|
||||
desc: "Keep the Content-Type returned by the server with auto-detection middleware",
|
||||
autoDetect: true,
|
||||
contentType: "application/json",
|
||||
wantContentType: "application/json",
|
||||
},
|
||||
{
|
||||
desc: "Auto-detect when Content-Type header is not already set by the server with auto-detection middleware",
|
||||
autoDetect: true,
|
||||
contentType: "",
|
||||
wantContentType: "text/plain; charset=utf-8",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var next http.Handler
|
||||
next = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if test.contentType != "" {
|
||||
w.Header().Set("Content-Type", test.contentType)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("Test"))
|
||||
})
|
||||
|
||||
if test.autoDetect {
|
||||
var err error
|
||||
next, err = New(context.Background(), next, "foo-content-type")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
server := httptest.NewServer(
|
||||
DisableAutoDetection(next),
|
||||
)
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, server.URL, nil)
|
||||
res, err := server.Client().Do(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.wantContentType, res.Header.Get("Content-Type"))
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue