From e7dd553a6156494fbf82f7bc3ade26bf93725260 Mon Sep 17 00:00:00 2001 From: T Date: Fri, 23 Feb 2024 10:59:49 +0100 Subject: [PATCH] filters/builtin: performance optimization for sanitize in StripQuery Filter (#2940) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pkg: github.com/zalando/skipper/filters/builtin │ HEAD~1 │ HEAD │ │ sec/op │ sec/op vs base │ Sanitize-8 802.1n ± 0% 748.3n ± 0% -6.71% (p=0.000 n=10) │ HEAD~1 │ HEAD │ │ B/op │ B/op vs base │ Sanitize-8 472.0 ± 0% 192.0 ± 0% -59.32% (p=0.000 n=10) │ HEAD~1 │ HEAD │ │ allocs/op │ allocs/op vs base │ Sanitize-8 15.00 ± 0% 14.00 ± 0% -6.67% (p=0.000 n=10) Signed-off-by: Troy Kohler --------- Signed-off-by: Troy Kohler --- filters/builtin/stripquery.go | 7 +++---- filters/builtin/stripquery_test.go | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/filters/builtin/stripquery.go b/filters/builtin/stripquery.go index 5dd533d017..03787f768c 100644 --- a/filters/builtin/stripquery.go +++ b/filters/builtin/stripquery.go @@ -15,7 +15,6 @@ package builtin import ( - "bytes" "fmt" "net/http" "strconv" @@ -52,14 +51,14 @@ func validHeaderFieldByte(b byte) bool { // make sure we don't generate invalid headers func sanitize(input string) string { + var s strings.Builder toAscii := strconv.QuoteToASCII(input) - var b bytes.Buffer for _, i := range toAscii { if validHeaderFieldByte(byte(i)) { - b.WriteRune(i) + s.WriteRune(i) } } - return b.String() + return s.String() } // Strips the query parameters and optionally preserves them in the X-Query-Param-xyz headers. diff --git a/filters/builtin/stripquery_test.go b/filters/builtin/stripquery_test.go index 643623ae11..dfe4d2c191 100644 --- a/filters/builtin/stripquery_test.go +++ b/filters/builtin/stripquery_test.go @@ -15,11 +15,12 @@ package builtin import ( - "github.com/zalando/skipper/filters/filtertest" "net/http" "net/url" "strings" "testing" + + "github.com/zalando/skipper/filters/filtertest" ) func TestCreateStripQueryFilter(t *testing.T) { @@ -91,3 +92,21 @@ func TestPreserveQuery(t *testing.T) { } } } + +func BenchmarkSanitize(b *testing.B) { + piece := "query=cXVlcnkgUGRwKCRjb25maWdTa3U6IElEIS&variables=%7B%0A%20%20%20%20%22beautyColorImageWidth%22:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20200,%0A%20%20%20%20%22portraitGalleryWidth%22:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20828,%0A%20%20%20%20%22segmentedBannerHeaderLogoWidth%22:%20%20%20%20%20%20%20%20%20%20%20%20%20%2084,%0A%20%20%20%20%22shouldIncludeCtaTrackingKey%22:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20false,%0A%20%20%20%20%22shouldIncludeFlagInfo%22:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20false,%0A%20%20%20%20%22shouldIncludeHistogramValues%22:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20false,%0A%20%20%20%20%22shouldIncludeOfferSelectionValues%22:%20%20%20%20%20%20%20%20%20%20%20true,%0A%20%20%20%20%22shouldIncludeOmnibusConfigModeChanges%22:%20%20%20%20%20%20%20false,%0A%20%20%20%20%22shouldIncludeOmnibusPriceLabelChanges%22:%20%20%20%20%20%20%20false,&apiEndpoint=https%253A%252F%252Fmodified%252Fsecret%252Fgraphql%252Fsecret&frontendType=secret&zalandoFeature=secret" + q := strings.Repeat(piece, 2) + v, e := url.ParseQuery(q) + + if e != nil { + b.Error(e) + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + for k := range v { + sanitize(k) + } + } +}