mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-22 23:13:01 +00:00
Support regex matching with attr (#2258)
* Support regex matching with attr * Add test case * Optimizing regex parsing at core start * simpliy
This commit is contained in:
parent
07389eca96
commit
a6c5c57930
@ -1,6 +1,7 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
@ -282,18 +283,18 @@ func (m *ProtocolMatcher) Apply(ctx routing.Context) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AttributeMatcher struct {
|
type AttributeMatcher struct {
|
||||||
configuredKeys map[string]string
|
configuredKeys map[string]*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match implements attributes matching.
|
// Match implements attributes matching.
|
||||||
func (m *AttributeMatcher) Match(attrs map[string]string) bool {
|
func (m *AttributeMatcher) Match(attrs map[string]string) bool {
|
||||||
// headers are insensitive most likely. So we do a convert
|
// header keys are case insensitive most likely. So we do a convert
|
||||||
httpHeaders := make(map[string]string)
|
httpHeaders := make(map[string]string)
|
||||||
for key, value := range attrs {
|
for key, value := range attrs {
|
||||||
httpHeaders[strings.ToLower(key)] = strings.ToLower(value)
|
httpHeaders[strings.ToLower(key)] = value
|
||||||
}
|
}
|
||||||
for key, value := range m.configuredKeys {
|
for key, regex := range m.configuredKeys {
|
||||||
if a, ok := httpHeaders[key]; !ok || !strings.Contains(a, value) {
|
if a, ok := httpHeaders[key]; !ok || !regex.MatchString(a) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,6 +319,19 @@ func TestRoutingRule(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
rule: &RoutingRule{
|
||||||
|
Attributes: map[string]string{
|
||||||
|
"Custom": "p([a-z]+)ch",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
test: []ruleTest{
|
||||||
|
{
|
||||||
|
input: withContent(&session.Content{Attributes: map[string]string{"custom": "peach"}}),
|
||||||
|
output: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range cases {
|
for _, test := range cases {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
@ -145,9 +146,9 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(rr.Attributes) > 0 {
|
if len(rr.Attributes) > 0 {
|
||||||
configuredKeys := make(map[string]string)
|
configuredKeys := make(map[string]*regexp.Regexp)
|
||||||
for key, value := range rr.Attributes {
|
for key, value := range rr.Attributes {
|
||||||
configuredKeys[strings.ToLower(key)] = strings.ToLower(value)
|
configuredKeys[strings.ToLower(key)] = regexp.MustCompile(value)
|
||||||
}
|
}
|
||||||
conds.Add(&AttributeMatcher{configuredKeys})
|
conds.Add(&AttributeMatcher{configuredKeys})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user