[#149] Use chi instead of gorilla mux

Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
pull/164/head
Denis Kirillov 2023-07-05 17:02:36 +03:00 committed by Alex Vanin
parent 7be70243f7
commit e30a452cdb
3 changed files with 136 additions and 3 deletions

View File

@ -0,0 +1,133 @@
package api
import (
"fmt"
"net/http"
)
type HandlerFilters struct {
filters []Filter
defaultHandler http.Handler
}
type Filter struct {
queries []Pair
headers []Pair
h http.Handler
}
type Pair struct {
Key string
Value string
}
func NewHandlerFilter() *HandlerFilters {
return &HandlerFilters{}
}
func NewFilter() *Filter {
return &Filter{}
}
func (hf *HandlerFilters) Add(filter *Filter) *HandlerFilters {
hf.filters = append(hf.filters, *filter)
return hf
}
// HeadersMatch adds a matcher for header values.
// It accepts a sequence of key/value pairs. Values may define variables.
// Panics if number of parameters is not even.
// Supports only exact matching.
// If the value is an empty string, it will match any value if the key is set.
func (f *Filter) HeadersMatch(pairs ...string) *Filter {
length := len(pairs)
if length%2 != 0 {
panic(fmt.Errorf("filter headers: number of parameters must be multiple of 2, got %v", pairs))
}
for i := 0; i < length; i += 2 {
f.headers = append(f.headers, Pair{
Key: pairs[i],
Value: pairs[i+1],
})
}
return f
}
// Headers is similar to HeadersMatch but accept only header keys, set value to empty string internally.
func (f *Filter) Headers(headers ...string) *Filter {
for _, header := range headers {
f.headers = append(f.headers, Pair{
Key: header,
Value: "",
})
}
return f
}
func (f *Filter) Handler(handler http.HandlerFunc) *Filter {
f.h = handler
return f
}
// QueriesMatch adds a matcher for URL query values.
// It accepts a sequence of key/value pairs. Values may define variables.
// Panics if number of parameters is not even.
// Supports only exact matching.
// If the value is an empty string, it will match any value if the key is set.
func (f *Filter) QueriesMatch(pairs ...string) *Filter {
length := len(pairs)
if length%2 != 0 {
panic(fmt.Errorf("filter headers: number of parameters must be multiple of 2, got %v", pairs))
}
for i := 0; i < length; i += 2 {
f.queries = append(f.queries, Pair{
Key: pairs[i],
Value: pairs[i+1],
})
}
return f
}
// Queries is similar to QueriesMatch but accept only query keys, set value to empty string internally.
func (f *Filter) Queries(queries ...string) *Filter {
for _, query := range queries {
f.queries = append(f.queries, Pair{
Key: query,
Value: "",
})
}
return f
}
func (hf *HandlerFilters) DefaultHandler(handler http.HandlerFunc) *HandlerFilters {
hf.defaultHandler = handler
return hf
}
func (hf *HandlerFilters) ServeHTTP(w http.ResponseWriter, r *http.Request) {
LOOP:
for _, filter := range hf.filters {
for _, header := range filter.headers {
hdrVals := r.Header.Values(header.Key)
if len(hdrVals) == 0 || header.Value != "" && header.Value != hdrVals[0] {
continue LOOP
}
}
for _, query := range filter.queries {
queryVal := r.URL.Query().Get(query.Key)
if !r.URL.Query().Has(query.Key) || queryVal != "" && query.Value != queryVal {
continue LOOP
}
}
filter.h.ServeHTTP(w, r)
return
}
hf.defaultHandler.ServeHTTP(w, r)
}

2
go.mod
View File

@ -8,8 +8,8 @@ require (
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20230707115716-fe35373d8f1b
github.com/aws/aws-sdk-go v1.44.6
github.com/bluele/gcache v0.0.2
github.com/go-chi/chi/v5 v5.0.8
github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
github.com/minio/sio v0.3.0
github.com/nats-io/nats.go v1.13.1-0.20220121202836-972a071d373d
github.com/nspcc-dev/neo-go v0.101.1

4
go.sum
View File

@ -149,6 +149,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -243,8 +245,6 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=