Performance enhancements for the rules matchers.
This commit is contained in:
parent
333b785061
commit
bf73127e0b
6 changed files with 192 additions and 35 deletions
42
middlewares/request_host.go
Normal file
42
middlewares/request_host.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package middlewares
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/containous/traefik/types"
|
||||
)
|
||||
|
||||
var requestHostKey struct{}
|
||||
|
||||
// RequestHost is the struct for the middleware that adds the CanonicalDomain of the request Host into a context for later use.
|
||||
type RequestHost struct{}
|
||||
|
||||
func (rh *RequestHost) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
||||
if next != nil {
|
||||
host := types.CanonicalDomain(parseHost(r.Host))
|
||||
next.ServeHTTP(rw, r.WithContext(context.WithValue(r.Context(), requestHostKey, host)))
|
||||
}
|
||||
}
|
||||
|
||||
func parseHost(addr string) string {
|
||||
if !strings.Contains(addr, ":") {
|
||||
return addr
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return addr
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
// GetCanonizedHost plucks the canonized host key from the request of a context that was put through the middleware
|
||||
func GetCanonizedHost(ctx context.Context) string {
|
||||
if val, ok := ctx.Value(requestHostKey).(string); ok {
|
||||
return val
|
||||
}
|
||||
return ""
|
||||
}
|
94
middlewares/request_host_test.go
Normal file
94
middlewares/request_host_test.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package middlewares
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/containous/traefik/testhelpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRequestHost(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
url string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "host without :",
|
||||
url: "http://host",
|
||||
expected: "host",
|
||||
},
|
||||
{
|
||||
desc: "host with : and without port",
|
||||
url: "http://host:",
|
||||
expected: "host",
|
||||
},
|
||||
{
|
||||
desc: "IP host with : and with port",
|
||||
url: "http://127.0.0.1:123",
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
desc: "IP host with : and without port",
|
||||
url: "http://127.0.0.1:",
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
}
|
||||
|
||||
rh := &RequestHost{}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, test.url, nil)
|
||||
|
||||
rh.ServeHTTP(nil, req, func(_ http.ResponseWriter, r *http.Request) {
|
||||
host := GetCanonizedHost(r.Context())
|
||||
assert.Equal(t, test.expected, host)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestHostParseHost(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
host string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "host without :",
|
||||
host: "host",
|
||||
expected: "host",
|
||||
},
|
||||
{
|
||||
desc: "host with : and without port",
|
||||
host: "host:",
|
||||
expected: "host",
|
||||
},
|
||||
{
|
||||
desc: "IP host with : and with port",
|
||||
host: "127.0.0.1:123",
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
desc: "IP host with : and without port",
|
||||
host: "127.0.0.1:",
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := parseHost(test.host)
|
||||
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue