diff --git a/internal/matcher/exact.go b/internal/matcher/exact.go index 40915f4..b64e5a2 100644 --- a/internal/matcher/exact.go +++ b/internal/matcher/exact.go @@ -15,6 +15,9 @@ type ExactMatcher struct { // handler 请求处理器 handler fasthttp.RequestHandler + // internal 是否为 internal location + internal bool + // path 精确匹配路径 path string @@ -28,14 +31,16 @@ type ExactMatcher struct { // - path: 精确匹配的路径 // - handler: 匹配成功后的请求处理器 // - priority: 优先级(通常设为 1) +// - internal: 是否为 internal location // // 返回值: // - *ExactMatcher: 精确匹配器实例 -func NewExactMatcher(path string, handler fasthttp.RequestHandler, priority int) *ExactMatcher { +func NewExactMatcher(path string, handler fasthttp.RequestHandler, priority int, internal bool) *ExactMatcher { return &ExactMatcher{ path: path, handler: handler, priority: priority, + internal: internal, } } @@ -60,5 +65,6 @@ func (m *ExactMatcher) Result() *MatchResult { Path: m.path, Priority: m.priority, LocationType: LocationTypeExact, + Internal: m.internal, } } diff --git a/internal/matcher/location.go b/internal/matcher/location.go index cd4419c..a96153d 100644 --- a/internal/matcher/location.go +++ b/internal/matcher/location.go @@ -74,10 +74,11 @@ func NewLocationEngine() *LocationEngine { // 参数: // - path: 精确匹配路径 // - handler: 请求处理器 +// - internal: 是否为 internal location // // 返回值: // - error: 引擎已初始化或路径冲突时返回错误 -func (e *LocationEngine) AddExact(path string, handler fasthttp.RequestHandler) error { +func (e *LocationEngine) AddExact(path string, handler fasthttp.RequestHandler, internal bool) error { if e.initialized { return errors.New("LocationEngine already initialized") } @@ -86,7 +87,7 @@ func (e *LocationEngine) AddExact(path string, handler fasthttp.RequestHandler) return err } - matcher := NewExactMatcher(path, handler, 1) + matcher := NewExactMatcher(path, handler, 1, internal) e.exactMatchers[path] = matcher return nil } @@ -96,10 +97,11 @@ func (e *LocationEngine) AddExact(path string, handler fasthttp.RequestHandler) // 参数: // - path: 前缀优先路径 // - handler: 请求处理器 +// - internal: 是否为 internal location // // 返回值: // - error: 引擎已初始化或路径冲突时返回错误 -func (e *LocationEngine) AddPrefixPriority(path string, handler fasthttp.RequestHandler) error { +func (e *LocationEngine) AddPrefixPriority(path string, handler fasthttp.RequestHandler, internal bool) error { if e.initialized { return errors.New("LocationEngine already initialized") } @@ -108,7 +110,7 @@ func (e *LocationEngine) AddPrefixPriority(path string, handler fasthttp.Request return err } - return e.prefixPriorityTree.Insert(path, handler, 2, "prefix_priority") + return e.prefixPriorityTree.Insert(path, handler, 2, "prefix_priority", internal) } // AddRegex 添加正则匹配 location。 @@ -117,15 +119,16 @@ func (e *LocationEngine) AddPrefixPriority(path string, handler fasthttp.Request // - pattern: 正则表达式模式 // - handler: 请求处理器 // - caseInsensitive: 是否大小写不敏感(~* 模式) +// - internal: 是否为 internal location // // 返回值: // - error: 引擎已初始化或正则表达式无效时返回错误 -func (e *LocationEngine) AddRegex(pattern string, handler fasthttp.RequestHandler, caseInsensitive bool) error { +func (e *LocationEngine) AddRegex(pattern string, handler fasthttp.RequestHandler, caseInsensitive bool, internal bool) error { if e.initialized { return errors.New("LocationEngine already initialized") } - matcher, err := NewRegexMatcher(pattern, handler, 3, caseInsensitive) + matcher, err := NewRegexMatcher(pattern, handler, 3, caseInsensitive, internal) if err != nil { return fmt.Errorf("invalid regex pattern: %w", err) } @@ -139,10 +142,11 @@ func (e *LocationEngine) AddRegex(pattern string, handler fasthttp.RequestHandle // 参数: // - path: 前缀路径 // - handler: 请求处理器 +// - internal: 是否为 internal location // // 返回值: // - error: 引擎已初始化或路径冲突时返回错误 -func (e *LocationEngine) AddPrefix(path string, handler fasthttp.RequestHandler) error { +func (e *LocationEngine) AddPrefix(path string, handler fasthttp.RequestHandler, internal bool) error { if e.initialized { return errors.New("LocationEngine already initialized") } @@ -151,7 +155,7 @@ func (e *LocationEngine) AddPrefix(path string, handler fasthttp.RequestHandler) return err } - return e.prefixTree.Insert(path, handler, 4, "prefix") + return e.prefixTree.Insert(path, handler, 4, "prefix", internal) } // AddNamed 添加命名 location。 diff --git a/internal/matcher/matcher.go b/internal/matcher/matcher.go index a300cdb..d69f9d1 100644 --- a/internal/matcher/matcher.go +++ b/internal/matcher/matcher.go @@ -42,6 +42,9 @@ type MatchResult struct { // Handler 匹配到的请求处理器 Handler fasthttp.RequestHandler + // Internal 是否为 internal location + Internal bool + // LocationType 匹配类型(exact/prefix/regex 等) LocationType string diff --git a/internal/matcher/prefix.go b/internal/matcher/prefix.go index 02264bf..4f50496 100644 --- a/internal/matcher/prefix.go +++ b/internal/matcher/prefix.go @@ -35,11 +35,12 @@ func NewPrefixMatcher() *PrefixMatcher { // 参数: // - path: 前缀路径 // - handler: 匹配成功后的请求处理器 +// - internal: 是否为 internal location // // 返回值: // - error: 路径重复或树已初始化时返回错误 -func (pm *PrefixMatcher) AddPath(path string, handler fasthttp.RequestHandler) error { - return pm.tree.Insert(path, handler, pm.priority, "prefix") +func (pm *PrefixMatcher) AddPath(path string, handler fasthttp.RequestHandler, internal bool) error { + return pm.tree.Insert(path, handler, pm.priority, "prefix", internal) } // Match 前缀匹配,返回最长前缀匹配结果。 diff --git a/internal/matcher/prefix_priority.go b/internal/matcher/prefix_priority.go index a5ff73a..67d3342 100644 --- a/internal/matcher/prefix_priority.go +++ b/internal/matcher/prefix_priority.go @@ -35,11 +35,12 @@ func NewPrefixPriorityMatcher() *PrefixPriorityMatcher { // 参数: // - path: 前缀优先路径 // - handler: 匹配成功后的请求处理器 +// - internal: 是否为 internal location // // 返回值: // - error: 路径重复或树已初始化时返回错误 -func (ppm *PrefixPriorityMatcher) AddPath(path string, handler fasthttp.RequestHandler) error { - return ppm.tree.Insert(path, handler, ppm.priority, "prefix_priority") +func (ppm *PrefixPriorityMatcher) AddPath(path string, handler fasthttp.RequestHandler, internal bool) error { + return ppm.tree.Insert(path, handler, ppm.priority, "prefix_priority", internal) } // Match 前缀优先匹配,返回最长前缀匹配结果。 diff --git a/internal/matcher/radix.go b/internal/matcher/radix.go index a12cff1..af599cb 100644 --- a/internal/matcher/radix.go +++ b/internal/matcher/radix.go @@ -29,6 +29,9 @@ type RadixNode struct { // priority 匹配优先级 priority int + // internal 是否为 internal location + internal bool + // isLeaf 是否为叶子节点(有 handler) isLeaf bool @@ -70,14 +73,15 @@ func NewRadixTree() *RadixTree { // - handler: 匹配成功后的请求处理器 // - priority: 匹配优先级 // - locationType: 位置类型标识 +// - internal: 是否为 internal location // // 返回值: // - error: 树已初始化或路径已存在时返回错误 -func (t *RadixTree) Insert(path string, handler fasthttp.RequestHandler, priority int, locationType string) error { +func (t *RadixTree) Insert(path string, handler fasthttp.RequestHandler, priority int, locationType string, internal bool) error { if t.initialized { return errors.New("RadixTree already initialized") } - return t.insertNode(nil, t.root, path, handler, priority, locationType) + return t.insertNode(nil, t.root, path, handler, priority, locationType, internal) } // insertNode 完整路径分割插入算法。 @@ -95,10 +99,11 @@ func (t *RadixTree) Insert(path string, handler fasthttp.RequestHandler, priorit // - handler: 请求处理器 // - priority: 优先级 // - locationType: 位置类型 +// - internal: 是否为 internal location // // 返回值: // - error: 路径已存在时返回错误 -func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string, handler fasthttp.RequestHandler, priority int, locationType string) error { +func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string, handler fasthttp.RequestHandler, priority int, locationType string, internal bool) error { // Case 1: 空节点(根节点),直接设置 if node.prefix == "" && len(node.children) == 0 && node.handler == nil { if path == "" { @@ -106,6 +111,7 @@ func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string, node.priority = priority node.isLeaf = true node.locationType = locationType + node.internal = internal return nil } // 创建新子节点 @@ -115,6 +121,7 @@ func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string, isLeaf: true, priority: priority, locationType: locationType, + internal: internal, } node.children = append(node.children, newNode) return nil @@ -140,13 +147,14 @@ func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string, node.priority = priority node.isLeaf = true node.locationType = locationType + node.internal = internal return nil } // 搜索匹配剩余路径的子节点 for _, child := range node.children { if strings.HasPrefix(remaining, child.prefix) { - return t.insertNode(node, child, remaining, handler, priority, locationType) + return t.insertNode(node, child, remaining, handler, priority, locationType, internal) } } @@ -157,6 +165,7 @@ func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string, isLeaf: true, priority: priority, locationType: locationType, + internal: internal, } node.children = append(node.children, newNode) return nil @@ -179,6 +188,7 @@ func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string, isLeaf: true, priority: priority, locationType: locationType, + internal: internal, } // 将原节点和新节点作为 splitNode 的子节点 @@ -243,6 +253,7 @@ func (t *RadixTree) searchLongest(node *RadixNode, path string, bestMatch *Match Path: node.prefix, Priority: node.priority, LocationType: node.locationType, + Internal: node.internal, } // nil-safe 优先级比较 + 长度比较 diff --git a/internal/matcher/regex.go b/internal/matcher/regex.go index d6b58f9..e3df97d 100644 --- a/internal/matcher/regex.go +++ b/internal/matcher/regex.go @@ -28,6 +28,9 @@ type RegexMatcher struct { // priority 匹配优先级,正则匹配为 3 priority int + // internal 是否为 internal location + internal bool + // caseInsensitive 是否大小写不敏感(~* 模式) caseInsensitive bool } @@ -39,11 +42,12 @@ type RegexMatcher struct { // - handler: 匹配成功后的请求处理器 // - priority: 优先级(通常设为 3) // - caseInsensitive: 是否大小写不敏感 +// - internal: 是否为 internal location // // 返回值: // - *RegexMatcher: 正则匹配器实例 // - error: 正则表达式编译失败时返回错误 -func NewRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority int, caseInsensitive bool) (*RegexMatcher, error) { +func NewRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority int, caseInsensitive bool, internal bool) (*RegexMatcher, error) { re, err := regexp.Compile(pattern) if err != nil { return nil, err @@ -54,6 +58,7 @@ func NewRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority i handler: handler, priority: priority, caseInsensitive: caseInsensitive, + internal: internal, captures: make(map[string]string), }, nil } @@ -67,11 +72,12 @@ func NewRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority i // - handler: 匹配成功后的请求处理器 // - priority: 优先级 // - caseInsensitive: 是否大小写不敏感 +// - internal: 是否为 internal location // // 返回值: // - *RegexMatcher: 正则匹配器实例 -func MustRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority int, caseInsensitive bool) *RegexMatcher { - m, err := NewRegexMatcher(pattern, handler, priority, caseInsensitive) +func MustRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority int, caseInsensitive bool, internal bool) *RegexMatcher { + m, err := NewRegexMatcher(pattern, handler, priority, caseInsensitive, internal) if err != nil { panic(err) } @@ -104,6 +110,7 @@ func (m *RegexMatcher) Result() *MatchResult { Priority: m.priority, LocationType: locType, Captures: m.captures, + Internal: m.internal, } }