You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
3.4 KiB
Go

package matcher
import (
"reflect"
ctxpkg "github.com/noahlann/nnet/pkg/context"
routerpkg "github.com/noahlann/nnet/pkg/router"
)
// FrameHeaderMatcher 帧头匹配器
type FrameHeaderMatcher struct {
field string
operator string
value interface{}
priority int
}
// NewFrameHeaderMatcher 创建帧头匹配器
func NewFrameHeaderMatcher(field, operator string, value interface{}) *FrameHeaderMatcher {
return &FrameHeaderMatcher{
field: field,
operator: operator,
value: value,
priority: 200, // 帧头匹配优先级高于字符串匹配
}
}
// WithPriority 设置优先级
func (m *FrameHeaderMatcher) WithPriority(priority int) *FrameHeaderMatcher {
m.priority = priority
return m
}
// Match 匹配帧头
func (m *FrameHeaderMatcher) Match(input routerpkg.MatchInput, ctx ctxpkg.Context) bool {
header := input.Header
if header == nil {
if req := ctx.Request(); req != nil {
header = req.Header()
}
}
if header == nil {
return false
}
fieldValue := header.Get(m.field)
if fieldValue == nil {
return false
}
return m.compare(fieldValue, m.value, m.operator)
}
// compare 比较值
func (m *FrameHeaderMatcher) compare(actual, expected interface{}, operator string) bool {
switch operator {
case "==":
return reflect.DeepEqual(actual, expected)
case "!=":
return !reflect.DeepEqual(actual, expected)
case ">":
return m.greaterThan(actual, expected)
case "<":
return m.lessThan(actual, expected)
case ">=":
return m.greaterThan(actual, expected) || reflect.DeepEqual(actual, expected)
case "<=":
return m.lessThan(actual, expected) || reflect.DeepEqual(actual, expected)
case "in":
return m.in(actual, expected)
default:
return false
}
}
// greaterThan 大于比较
func (m *FrameHeaderMatcher) greaterThan(a, b interface{}) bool {
switch av := a.(type) {
case int:
if bv, ok := b.(int); ok {
return av > bv
}
case int32:
if bv, ok := b.(int32); ok {
return av > bv
}
case int64:
if bv, ok := b.(int64); ok {
return av > bv
}
case uint8:
if bv, ok := b.(uint8); ok {
return av > bv
}
case uint32:
if bv, ok := b.(uint32); ok {
return av > bv
}
case uint64:
if bv, ok := b.(uint64); ok {
return av > bv
}
}
return false
}
// lessThan 小于比较
func (m *FrameHeaderMatcher) lessThan(a, b interface{}) bool {
switch av := a.(type) {
case int:
if bv, ok := b.(int); ok {
return av < bv
}
case int32:
if bv, ok := b.(int32); ok {
return av < bv
}
case int64:
if bv, ok := b.(int64); ok {
return av < bv
}
case uint8:
if bv, ok := b.(uint8); ok {
return av < bv
}
case uint32:
if bv, ok := b.(uint32); ok {
return av < bv
}
case uint64:
if bv, ok := b.(uint64); ok {
return av < bv
}
}
return false
}
// in 检查是否在列表中
func (m *FrameHeaderMatcher) in(value, list interface{}) bool {
listValue := reflect.ValueOf(list)
if listValue.Kind() != reflect.Slice {
return false
}
for i := 0; i < listValue.Len(); i++ {
if reflect.DeepEqual(value, listValue.Index(i).Interface()) {
return true
}
}
return false
}
// Priority 获取优先级
func (m *FrameHeaderMatcher) Priority() int {
return m.priority
}
// Field 获取字段名
func (m *FrameHeaderMatcher) Field() string {
return m.field
}
// Operator 获取操作符
func (m *FrameHeaderMatcher) Operator() string {
return m.operator
}
// Value 获取匹配值
func (m *FrameHeaderMatcher) Value() interface{} {
return m.value
}