http: use default minsize for gzip handler. (#7354)

Fixes #6306
This commit is contained in:
Hans Hasselberg 2020-06-08 10:10:08 +02:00 committed by GitHub
parent 532e14fdc4
commit 4790f97bb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 2 deletions

View File

@ -4451,6 +4451,43 @@ func TestAgent_Monitor(t *testing.T) {
})
})
t.Run("stream compressed unstructured logs", func(t *testing.T) {
// The only purpose of this test is to see something being
// logged. Because /v1/agent/monitor is streaming the response
// it needs special handling with the compression.
retry.Run(t, func(r *retry.R) {
req, _ := http.NewRequest("GET", "/v1/agent/monitor?loglevel=debug", nil)
// Usually this would be automatically set by transport content
// negotiation, but since this call doesn't go through a real
// transport, the header has to be set manually
req.Header["Accept-Encoding"] = []string{"gzip"}
cancelCtx, cancelFunc := context.WithCancel(context.Background())
req = req.WithContext(cancelCtx)
resp := httptest.NewRecorder()
go a.srv.Handler.ServeHTTP(resp, req)
args := &structs.ServiceDefinition{
Name: "monitor",
Port: 8000,
Check: structs.CheckType{
TTL: 15 * time.Second,
},
}
registerReq, _ := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args))
if _, err := a.srv.AgentRegisterService(nil, registerReq); err != nil {
t.Fatalf("err: %v", err)
}
// Wait until we have received some type of logging output
require.Eventually(t, func() bool {
return len(resp.Body.Bytes()) > 0
}, 3*time.Second, 100*time.Millisecond)
cancelFunc()
})
})
t.Run("stream JSON logs", func(t *testing.T) {
// Try to stream logs until we see the expected log line
retry.Run(t, func(r *retry.R) {

View File

@ -258,8 +258,17 @@ func (s *HTTPServer) handler(enableDebug bool) http.Handler {
metrics.MeasureSince(key, start)
}
gzipWrapper, _ := gziphandler.GzipHandlerWithOpts(gziphandler.MinSize(0))
gzipHandler := gzipWrapper(http.HandlerFunc(wrapper))
var gzipHandler http.Handler
minSize := gziphandler.DefaultMinSize
if pattern == "/v1/agent/monitor" {
minSize = 0
}
gzipWrapper, err := gziphandler.GzipHandlerWithOpts(gziphandler.MinSize(minSize))
if err == nil {
gzipHandler = gzipWrapper(http.HandlerFunc(wrapper))
} else {
gzipHandler = gziphandler.GzipHandler(http.HandlerFunc(wrapper))
}
mux.Handle(pattern, gzipHandler)
}

View File

@ -18,6 +18,7 @@ import (
"testing"
"time"
"github.com/NYTimes/gziphandler"
"github.com/hashicorp/consul/agent/structs"
tokenStore "github.com/hashicorp/consul/agent/token"
"github.com/hashicorp/consul/api"
@ -462,6 +463,45 @@ func TestUIResponseHeaders(t *testing.T) {
}
}
func TestAcceptEncodingGzip(t *testing.T) {
t.Parallel()
a := NewTestAgent(t, "")
defer a.Shutdown()
// Setting up the KV to store a short and a long value
buf := bytes.NewBuffer([]byte("short"))
req, _ := http.NewRequest("PUT", "/v1/kv/short", buf)
resp := httptest.NewRecorder()
_, err := a.srv.KVSEndpoint(resp, req)
require.NoError(t, err)
// this generates a string which is longer than
// gziphandler.DefaultMinSize to trigger compression.
long := fmt.Sprintf(fmt.Sprintf("%%0%dd", gziphandler.DefaultMinSize+1), 1)
buf = bytes.NewBuffer([]byte(long))
req, _ = http.NewRequest("PUT", "/v1/kv/long", buf)
resp = httptest.NewRecorder()
_, err = a.srv.KVSEndpoint(resp, req)
require.NoError(t, err)
resp = httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/v1/kv/short", nil)
// Usually this would be automatically set by transport content
// negotiation, but since this call doesn't go through a real
// transport, the header has to be set manually
req.Header["Accept-Encoding"] = []string{"gzip"}
a.srv.Handler.ServeHTTP(resp, req)
require.Equal(t, 200, resp.Code)
require.Equal(t, "", resp.Header().Get("Content-Encoding"))
resp = httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/v1/kv/long", nil)
req.Header["Accept-Encoding"] = []string{"gzip"}
a.srv.Handler.ServeHTTP(resp, req)
require.Equal(t, 200, resp.Code)
require.Equal(t, "gzip", resp.Header().Get("Content-Encoding"))
}
func TestContentTypeIsJSON(t *testing.T) {
t.Parallel()
a := NewTestAgent(t, "")