From a859ae02ad26c8a319ae1ab2900e846a97154ce9 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Mon, 6 Jul 2015 18:36:12 +0500 Subject: [PATCH] More tests and simplify hashFilter --- http_modifier.go | 3 +- http_modifier_test.go | 57 +++++++++++++++++++++++++++++++++ settings_header_hash_filters.go | 12 ++----- settings_url_map_test.go | 19 ++++++++++- 4 files changed, 79 insertions(+), 12 deletions(-) diff --git a/http_modifier.go b/http_modifier.go index 95fb819..2f1dc3d 100644 --- a/http_modifier.go +++ b/http_modifier.go @@ -68,7 +68,8 @@ func (m *HTTPModifier) Rewrite(payload []byte) (response []byte) { hasher := fnv.New32a() hasher.Write(value) - if hasher.Sum32() > f.maxHash { + + if (hasher.Sum32() % 100) >= f.percent { return } } diff --git a/http_modifier_test.go b/http_modifier_test.go index 6ca055d..6803587 100644 --- a/http_modifier_test.go +++ b/http_modifier_test.go @@ -2,6 +2,8 @@ package main import ( "testing" + "github.com/buger/gor/proto" + "bytes" ) func TestHTTPModifierWithoutConfig(t *testing.T) { @@ -36,3 +38,58 @@ func TestHTTPModifierHeaderFilters(t *testing.T) { t.Error("Request should not pass filters") } } + + +func TestHTTPModifierURLRegexp(t *testing.T) { + var url, new_url []byte + + rewrites := UrlRewriteMap{} + + payload := func(url []byte) []byte { + return []byte("POST " + string(url) + " HTTP/1.1\r\nContent-Length: 7\r\nHost: www.w3.org\r\n\r\na=1&b=2") + } + + err := rewrites.Set("/v1/user/([^\\/]+)/ping:/v2/user/$1/ping") + if err != nil { + t.Error("Should not error on /v1/user/([^\\/]+)/ping:/v2/user/$1/ping") + } + + modifier := NewHTTPModifier(&HTTPModifierConfig{ + urlRewrite: rewrites, + }) + + url = []byte("/v1/user/joe/ping") + if new_url = proto.Path(modifier.Rewrite(payload(url))); bytes.Equal(new_url, url) { + t.Error("Request url should have been rewritten, wasn't", string(new_url)) + } + + url = []byte("/v1/user/ping") + if new_url = proto.Path(modifier.Rewrite(payload(url))); !bytes.Equal(new_url, url) { + t.Error("Request url should have been rewritten, wasn't", string(new_url)) + } +} + +func TestHTTPModifierHeaderHashFilters(t *testing.T) { + filters := HTTPHeaderHashFilters{} + filters.Set("Header2:1/2") + + modifier := NewHTTPModifier(&HTTPModifierConfig{ + headerHashFilters: filters, + }) + + payload := func(header []byte) []byte { + return []byte("POST / HTTP/1.1\r\n" + string(header) + "Content-Length: 7\r\nHost: www.w3.org\r\n\r\na=1&b=2") + } + + if p := modifier.Rewrite(payload([]byte(""))); len(p) > 0 { + t.Error("Request should not pass filters, Header2 does not exist") + } + + if p := modifier.Rewrite(payload([]byte("Header2: 3\r\n"))); len(p) > 0 { + t.Error("Request should not pass filters, Header2 hash too high") + } + + if p := modifier.Rewrite(payload([]byte("Header2: 1\r\n"))); len(p) == 0 { + t.Error("Request should pass filters") + } +} diff --git a/settings_header_hash_filters.go b/settings_header_hash_filters.go index 0dc9801..5c848fe 100644 --- a/settings_header_hash_filters.go +++ b/settings_header_hash_filters.go @@ -9,7 +9,7 @@ import ( type headerHashFilter struct { name []byte - maxHash uint32 + percent uint32 } type HTTPHeaderHashFilters []headerHashFilter @@ -33,17 +33,9 @@ func (h *HTTPHeaderHashFilters) Set(value string) error { num, _ = strconv.ParseUint(fracArr[0], 10, 64) den, _ = strconv.ParseUint(fracArr[1], 10, 64) - if num < 1 || den < 1 || num > den { - panic("need positive numerators and denominators, with the former less than the latter.") - } - - if den&(den-1) != 0 { - return errors.New("must have a denominator which is a power of two.") - } - var f headerHashFilter f.name = []byte(valArr[0]) - f.maxHash = (uint32)(num * (((uint64)(2 << 31)) / den)) + f.percent = uint32((float64(num) / float64(den)) * 100) *h = append(*h, f) return nil diff --git a/settings_url_map_test.go b/settings_url_map_test.go index 85f0393..de7ad7d 100644 --- a/settings_url_map_test.go +++ b/settings_url_map_test.go @@ -1 +1,18 @@ -package main \ No newline at end of file +package main + +import ( + "testing" +) + +func TestUrlRewriteMap(t *testing.T) { + var err error + rewrites := UrlRewriteMap{} + + if err = rewrites.Set("/v1/user/([^\\/]+)/ping:/v2/user/$1/ping"); err != nil { + t.Error("Should set mapping", err) + } + + if err = rewrites.Set("/v1/user/([^\\/]+)/ping"); err == nil { + t.Error("Should not set mapping without :") + } +} \ No newline at end of file