Skip to content

Commit

Permalink
The spec of the httpserver supports the AND-OR strategy of the header…
Browse files Browse the repository at this point in the history
…'s match (#613)
  • Loading branch information
sodaRyCN committed May 10, 2022
1 parent 0e762ff commit dd6d2f0
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 12 deletions.
62 changes: 62 additions & 0 deletions pkg/object/httpserver/httpserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ func TestSearchPath(t *testing.T) {
emptyHeaders := make(map[string]string)
jsonHeader := make(map[string]string)
jsonHeader["content-type"] = "application/json"

moreHeader := make(map[string]string)
moreHeader["content-type"] = "application/json"
moreHeader["accept-encoding"] = "gzip"

allMatchHeader := make(map[string]string)
allMatchHeader["content-type"] = "application/json"
allMatchHeader["accept-language"] = "zh-CN"
tests := []testCase{
{
"/path/1", http.MethodGet, emptyHeaders, "", []*muxRule{
Expand Down Expand Up @@ -172,6 +180,60 @@ func TestSearchPath(t *testing.T) {
}),
}, FoundSkipCache,
},
{
"/matchallheader", http.MethodGet, moreHeader, "", []*muxRule{
newMuxRule(&ipfilter.IPFilters{}, &Rule{}, []*MuxPath{
newMuxPath(&ipfilter.IPFilters{}, &Path{
Path: "/matchallheader", Methods: []string{http.MethodGet},
Headers: []*Header{{Key: "content-type", Values: []string{"application/json"}}},
}),
}),
}, FoundSkipCache,
},
//todo: When the pipeline refactoring is complete, the expected results `MethodNotAllowed` need to be adapted
{
"/matchallheader", http.MethodGet, jsonHeader, "", []*muxRule{
newMuxRule(&ipfilter.IPFilters{}, &Rule{}, []*MuxPath{
newMuxPath(&ipfilter.IPFilters{}, &Path{
Path: "/matchallheader", Methods: []string{http.MethodGet},
Headers: []*Header{
{Key: "content-type", Values: []string{"application/json"}},
{Key: "accept-language", Values: []string{"zh-CN"}},
},

MatchAllHeader: true,
}),
}),
}, MethodNotAllowed,
},
{
"/matchallheader", http.MethodGet, moreHeader, "", []*muxRule{
newMuxRule(&ipfilter.IPFilters{}, &Rule{}, []*MuxPath{
newMuxPath(&ipfilter.IPFilters{}, &Path{
Path: "/matchallheader", Methods: []string{http.MethodGet},
Headers: []*Header{
{Key: "content-type", Values: []string{"application/json"}},
{Key: "accept-language", Values: []string{"zh-CN"}},
},
MatchAllHeader: true,
}),
}),
}, MethodNotAllowed,
},
{
"/matchallheader", http.MethodGet, allMatchHeader, "", []*muxRule{
newMuxRule(&ipfilter.IPFilters{}, &Rule{}, []*MuxPath{
newMuxPath(&ipfilter.IPFilters{}, &Path{
Path: "/matchallheader", Methods: []string{http.MethodGet},
Headers: []*Header{
{Key: "content-type", Values: []string{"application/json"}},
{Key: "accept-language", Values: []string{"zh-CN"}},
},
MatchAllHeader: true,
}),
}),
}, FoundSkipCache,
},
}

for i := 0; i < len(tests); i++ {
Expand Down
23 changes: 19 additions & 4 deletions pkg/object/httpserver/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type (
rewriteTarget string
backend string
headers []*Header
mathAllHeader bool
}

// SearchResult is returned by SearchPath
Expand Down Expand Up @@ -230,6 +231,7 @@ func newMuxPath(parentIPFilters *ipfilter.IPFilters, path *Path) *MuxPath {
methods: path.Methods,
backend: path.Backend,
headers: path.Headers,
mathAllHeader: path.MatchAllHeader,
}
}

Expand Down Expand Up @@ -299,18 +301,31 @@ func (mp *MuxPath) hasHeaders() bool {
}

func (mp *MuxPath) matchHeaders(ctx context.HTTPContext) bool {
var result bool
for _, h := range mp.headers {
result = false
v := ctx.Request().Header().Get(h.Key)
if stringtool.StrInSlice(v, h.Values) {
return true
result = true
}
if !mp.mathAllHeader && result {
break
}
if mp.mathAllHeader && result {
continue
}

if h.Regexp != "" && h.headerRE.MatchString(v) {
return true
result = true
}
if !mp.mathAllHeader && result {
break
}
if mp.mathAllHeader && !result {
break
}
}

return false
return result
}

func newMux(httpStat *httpstat.HTTPStat, topN *topn.TopN, mapper protocol.MuxMapper) *mux {
Expand Down
17 changes: 9 additions & 8 deletions pkg/object/httpserver/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,15 @@ type (

// Path is second level entry of router.
Path struct {
IPFilter *ipfilter.Spec `yaml:"ipFilter,omitempty" jsonschema:"omitempty"`
Path string `yaml:"path,omitempty" jsonschema:"omitempty,pattern=^/"`
PathPrefix string `yaml:"pathPrefix,omitempty" jsonschema:"omitempty,pattern=^/"`
PathRegexp string `yaml:"pathRegexp,omitempty" jsonschema:"omitempty,format=regexp"`
RewriteTarget string `yaml:"rewriteTarget" jsonschema:"omitempty"`
Methods []string `yaml:"methods,omitempty" jsonschema:"omitempty,uniqueItems=true,format=httpmethod-array"`
Backend string `yaml:"backend" jsonschema:"required"`
Headers []*Header `yaml:"headers" jsonschema:"omitempty"`
IPFilter *ipfilter.Spec `yaml:"ipFilter,omitempty" jsonschema:"omitempty"`
Path string `yaml:"path,omitempty" jsonschema:"omitempty,pattern=^/"`
PathPrefix string `yaml:"pathPrefix,omitempty" jsonschema:"omitempty,pattern=^/"`
PathRegexp string `yaml:"pathRegexp,omitempty" jsonschema:"omitempty,format=regexp"`
RewriteTarget string `yaml:"rewriteTarget" jsonschema:"omitempty"`
Methods []string `yaml:"methods,omitempty" jsonschema:"omitempty,uniqueItems=true,format=httpmethod-array"`
Backend string `yaml:"backend" jsonschema:"required"`
Headers []*Header `yaml:"headers" jsonschema:"omitempty"`
MatchAllHeader bool `yaml:"MatchAllHeader" jsonschema:"omitempty"`
}

// Header is the third level entry of router. A header entry is always under a specific path entry, that is to mean
Expand Down

0 comments on commit dd6d2f0

Please sign in to comment.