1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Bugfix] Fix GZIP encoding in case of small responses (#1397)

This commit is contained in:
Adam Janikowski 2023-09-04 10:49:41 +02:00 committed by GitHub
parent ecb3482f34
commit 278cc60b4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 283 additions and 12 deletions

View file

@ -12,6 +12,7 @@
- (Bugfix) (EE) Fix MemberMaintenance Context and ClusterMaintenance discovery
- (Feature) Add proper Prometheus endpoint compression + 204 response code
- (Feature) Reconciliation Loop Interval option
- (Bugfix) Fix GZIP encoding in case of small responses
## [1.2.32](https://github.com/arangodb/kube-arangodb/tree/1.2.32) (2023-08-07)
- (Feature) Backup lifetime - remove Backup once its lifetime has been reached

15
go.mod
View file

@ -39,8 +39,8 @@ require (
github.com/pkg/errors v0.9.1
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.44.1
github.com/prometheus-operator/prometheus-operator/pkg/client v0.0.0-00010101000000-000000000000
github.com/prometheus/client_golang v1.12.1
github.com/prometheus/client_model v0.2.0
github.com/prometheus/client_golang v1.15.1
github.com/prometheus/client_model v0.4.0
github.com/robfig/cron v1.2.0
github.com/rs/zerolog v1.19.0
github.com/spf13/cobra v1.4.0
@ -94,7 +94,7 @@ require (
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/cel-go v0.12.6 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.5.9 // indirect
@ -111,7 +111,7 @@ require (
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@ -120,8 +120,9 @@ require (
github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/prometheus/prom2json v1.3.3 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
@ -147,7 +148,7 @@ require (
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/tools v0.6.0 // indirect
google.golang.org/appengine v1.6.7 // indirect

17
go.sum
View file

@ -220,6 +220,7 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
@ -315,6 +316,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@ -485,6 +488,8 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@ -571,11 +576,15 @@ github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@ -586,6 +595,8 @@ github.com/prometheus/common v0.28.0 h1:vGVfV9KrDTvWt5boZO0I19g2E3CsWfpPPKZM9dt3
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@ -594,6 +605,10 @@ github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3x
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/prometheus/prom2json v1.3.3 h1:IYfSMiZ7sSOfliBoo89PcufjWO4eAR0gznGcETyaUgo=
github.com/prometheus/prom2json v1.3.3/go.mod h1:Pv4yIPktEkK7btWsrUTWDDDrnpUrAELaOCj+oFwlgmc=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
@ -887,6 +902,8 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.

View file

@ -46,8 +46,6 @@ func WithBuffer(maxSize int, in http.HandlerFunc) http.HandlerFunc {
// We have constant size
bytes := data.Bytes()
println(len(bytes))
writer.Header().Set(ContentLengthHeader, fmt.Sprintf("%d", len(bytes)))
_, err := util.WriteAll(writer, bytes)

View file

@ -45,8 +45,6 @@ func WithEncoding(in http.HandlerFunc) http.HandlerFunc {
default:
WithIdentityEncoding(in)(writer, request)
}
in(writer, request)
}
}
@ -58,8 +56,14 @@ func WithIdentityEncoding(in http.HandlerFunc) http.HandlerFunc {
func WithGZipEncoding(in http.HandlerFunc) http.HandlerFunc {
return func(responseWriter http.ResponseWriter, request *http.Request) {
responseWriter.Header().Add(EncodingResponseHeader, "gzip")
stream := gzip.NewWriter(responseWriter)
in(NewWriter(responseWriter, stream), request)
if err := stream.Close(); err != nil {
logger.Err(err).Warn("Unable to write GZIP response")
}
}
}

View file

@ -0,0 +1,190 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package metrics
import (
"compress/gzip"
"fmt"
"io"
"net/http"
"testing"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/prom2json"
"github.com/stretchr/testify/require"
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
)
func Test_Handler(t *testing.T) {
m := http.NewServeMux()
m.HandleFunc("/metrics", Handler())
m.HandleFunc("/empty", operatorHTTP.WithNoContent(func(writer http.ResponseWriter, request *http.Request) {
}))
endpoint, c := StartHTTP(t, m)
defer c()
metricsEndpoint := fmt.Sprintf("%s/metrics", endpoint)
emptyEndpoint := fmt.Sprintf("%s/empty", endpoint)
t.Run("Get metrics in plain", func(t *testing.T) {
r, err := http.NewRequest("GET", metricsEndpoint, nil)
require.NoError(t, err)
r.Header.Add("Accept-Encoding", "identity")
resp, err := http.DefaultClient.Do(r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
data, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.True(t, len(data) > 0)
})
t.Run("Get metrics in gzip", func(t *testing.T) {
r, err := http.NewRequest("GET", metricsEndpoint, nil)
require.NoError(t, err)
r.Header.Add("Accept-Encoding", "gzip")
resp, err := http.DefaultClient.Do(r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
data, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.True(t, len(data) > 0)
})
t.Run("Get metrics in default", func(t *testing.T) {
r, err := http.NewRequest("GET", metricsEndpoint, nil)
require.NoError(t, err)
resp, err := http.DefaultClient.Do(r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
data, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.True(t, len(data) > 0)
})
t.Run("Get empty", func(t *testing.T) {
r, err := http.NewRequest("GET", emptyEndpoint, nil)
require.NoError(t, err)
resp, err := http.DefaultClient.Do(r)
require.NoError(t, err)
require.Equal(t, http.StatusNoContent, resp.StatusCode)
data, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.True(t, len(data) == 0)
})
t.Run("Read metrics - plain", func(t *testing.T) {
mfChan := make(chan *dto.MetricFamily, 1024*1024)
r, err := http.NewRequest("GET", metricsEndpoint, nil)
require.NoError(t, err)
r.Header.Add("Accept-Encoding", "identity")
resp, err := http.DefaultClient.Do(r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(t, prom2json.ParseReader(resp.Body, mfChan))
metrics := map[string]bool{}
for mf := range mfChan {
result := prom2json.NewFamily(mf)
metrics[result.Name] = true
}
require.Contains(t, metrics, "go_info")
})
t.Run("Read metrics - gzip", func(t *testing.T) {
mfChan := make(chan *dto.MetricFamily, 1024*1024)
r, err := http.NewRequest("GET", metricsEndpoint, nil)
require.NoError(t, err)
r.Header.Add("Accept-Encoding", "gzip")
resp, err := http.DefaultClient.Do(r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
reader, err := gzip.NewReader(resp.Body)
require.NoError(t, err)
require.NoError(t, prom2json.ParseReader(reader, mfChan))
metrics := map[string]bool{}
for mf := range mfChan {
result := prom2json.NewFamily(mf)
metrics[result.Name] = true
}
require.Contains(t, metrics, "go_info")
})
t.Run("Read metrics - default", func(t *testing.T) {
mfChan := make(chan *dto.MetricFamily, 1024*1024)
r, err := http.NewRequest("GET", metricsEndpoint, nil)
require.NoError(t, err)
resp, err := http.DefaultClient.Do(r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.NoError(t, prom2json.ParseReader(resp.Body, mfChan))
metrics := map[string]bool{}
for mf := range mfChan {
result := prom2json.NewFamily(mf)
metrics[result.Name] = true
}
require.Contains(t, metrics, "go_info")
})
}

View file

@ -0,0 +1,60 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package metrics
import (
"errors"
"fmt"
"net"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func StartHTTP(t *testing.T, mux *http.ServeMux) (string, func()) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
port := listener.Addr().(*net.TCPAddr).Port
server := &http.Server{}
server.Handler = mux
closed := make(chan struct{})
go func() {
defer close(closed)
if err := server.Serve(listener); err != nil {
if !errors.Is(err, http.ErrServerClosed) {
require.NoError(t, err)
}
}
}()
time.Sleep(500 * time.Millisecond)
return fmt.Sprintf("http://127.0.0.1:%d", port), func() {
require.NoError(t, server.Close())
<-closed
}
}