Skip to content

Commit

Permalink
support specifying the part of the path
Browse files Browse the repository at this point in the history
  • Loading branch information
Samu Tamminen committed Jan 25, 2022
1 parent 7b959d0 commit 04316af
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
22 changes: 17 additions & 5 deletions pkg/filter/headerlookup/headerlookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"context"
"fmt"
"net/http"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -55,6 +56,7 @@ type (
spec *Spec
etcdPrefix string
headerKey string
pathRegExp *regexp.Regexp

cache *lru.Cache
cluster cluster.Cluster
Expand All @@ -71,13 +73,15 @@ type (
// Spec defines header key and etcd prefix that form etcd key like /custom-data/{etcdPrefix}/{headerKey's value}.
// This /custom-data/{etcdPrefix}/{headerKey's value} is retrieved from etcd and HeaderSetters extract keys from the
// from the retrieved etcd item.
// When AppendPath is true, the path (without leading slash) is appended to the etcd key in following format:
// /custom-data/{etcdPrefix}/{headerKey's value}-{path} . For example, for path "/bananas", the etcd key is
// When PathRegExp is defined, PathRegExp is used with `regexp.FindStringSubmatch` to identify a group from path.
// The first captured group is appended to the etcd key in following format:
// /custom-data/{etcdPrefix}/{headerKey's value}-{regex group} . For example, for path
// "/api/bananas/33" and pathRegExp: "^/api/([a-z]+)/[0-9]*", the group "bananas" is extracted and etcd key is
// /custom-data/{etcdPrefix}/{headerKey's value}-bananas.
Spec struct {
HeaderKey string `yaml:"headerKey" jsonschema:"required"`
EtcdPrefix string `yaml:"etcdPrefix" jsonschema:"required"`
AppendPath bool `yaml:"appendPath" jsonschema:"omitempty"`
PathRegExp string `yaml:"pathRegExp" jsonschema:"omitempty"`
HeaderSetters []*HeaderSetterSpec `yaml:"headerSetters" jsonschema:"required"`
}
)
Expand All @@ -101,6 +105,10 @@ func (spec Spec) Validate() error {
return fmt.Errorf("headerSetters[i].headerKey is required")
}
}

if _, err := regexp.Compile(spec.PathRegExp); err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -134,6 +142,7 @@ func (hl *HeaderLookup) Init(filterSpec *httppipeline.FilterSpec) {
hl.headerKey = http.CanonicalHeaderKey(hl.spec.HeaderKey)
hl.cache, _ = lru.New(cacheSize)
hl.stopCtx, hl.cancel = context.WithCancel(context.Background())
hl.pathRegExp = regexp.MustCompile(hl.spec.PathRegExp)
hl.watchChanges()
}

Expand Down Expand Up @@ -253,8 +262,11 @@ func (hl *HeaderLookup) handle(ctx httpcontext.HTTPContext) string {
logger.Warnf("request does not have header '%s'", hl.spec.HeaderKey)
return ""
}
if hl.spec.AppendPath {
headerVal = headerVal + "-" + strings.TrimPrefix(ctx.Request().Path(), "/")
if hl.spec.PathRegExp != "" {
path := ctx.Request().Path()
if match := hl.pathRegExp.FindStringSubmatch(path); match != nil && len(match) > 1 {
headerVal = headerVal + "-" + match[1]
}
}
headersToAdd, err := hl.lookup(headerVal)
if err != nil {
Expand Down
21 changes: 17 additions & 4 deletions pkg/filter/headerlookup/headerlookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ headerKey: "X-AUTH-USER"
etcdPrefix: "/credentials/"
headerSetters:
- headerKey: "X-ext-id"
`,
`
name: headerLookup
kind: HeaderLookup
headerKey: "X-AUTH-USER"
pathRegExp: "**"
etcdPrefix: "/credentials/"
headerSetters:
- headerKey: "X-ext-id"
etcdKey: "ext-id"
`,
}

Expand Down Expand Up @@ -266,7 +276,7 @@ name: headerLookup
kind: HeaderLookup
headerKey: "X-AUTH-USER"
etcdPrefix: "credentials/"
appendPath: true
pathRegExp: "^/api/([a-z]+)/[0-9]*"
headerSetters:
- etcdKey: "ext-id"
headerKey: "user-ext-id"
Expand All @@ -291,17 +301,20 @@ extra-entry: "extra"
check(err)

ctx, header := prepareCtxAndHeader()

header.Set("X-AUTH-USER", "bob")
hl.Handle(ctx) // path does not match
if header.Get("user-ext-id") != "" {
t.Errorf("failed")
}
ctx.MockedRequest.MockedPath = func() string {
return "/bananas"
return "/api/bananas/9281"
}
hl.Handle(ctx)
if header.Get("user-ext-id") != "333" {
t.Errorf("failed")
}
ctx.MockedRequest.MockedPath = func() string {
return "/pearls"
return "/api/pearls/"
}
hl.Handle(ctx)
if header.Get("user-ext-id") != "4444" {
Expand Down

0 comments on commit 04316af

Please sign in to comment.