Mercurial Hosting > d2o
diff icf/icf.go @ 12:84384cccda0e
bubfix subpaths and remove hardcode
| author | atarwn@g5 |
|---|---|
| date | Mon, 23 Mar 2026 12:05:05 +0500 |
| parents | 2ffb8028ccbb |
| children | 9460f83a5664 |
line wrap: on
line diff
--- a/icf/icf.go Thu Mar 19 20:00:49 2026 +0500 +++ b/icf/icf.go Mon Mar 23 12:05:05 2026 +0500 @@ -146,13 +146,14 @@ // Match finds the most specific block matching input (e.g. "host/path") and // returns resolved directives plus named captures. // Domain is matched exactly; path uses prefix match. -func (c *Config) Match(input string) ([]Directive, map[string]string) { +func (c *Config) Match(input string) ([]Directive, map[string]string, string) { inHost, inPath, _ := strings.Cut(input, "/") type hit struct { block ParsedBlock captures map[string]string score int + rem string } var best *hit @@ -166,24 +167,33 @@ } pathScore := 0 + rem := inPath if hasPath { - pathScore, ok = matchPrefix(patPath, inPath, caps) + var pathRem string + pathScore, pathRem, ok = matchPrefix(patPath, inPath, caps) if !ok { continue } + rem = pathRem } score := domScore*1000 + pathScore if best == nil || score > best.score { - best = &hit{block: b, captures: caps, score: score} + best = &hit{block: b, captures: caps, score: score, rem: rem} } } if best == nil { - return nil, nil + return nil, nil, "" } - return c.ResolveBlock(best.block, best.captures), best.captures + // rem is the unmatched suffix after the path pattern. + // Ensure it starts with "/" to form a valid absolute subpath. + subPath := best.rem + if !strings.HasPrefix(subPath, "/") { + subPath = "/" + subPath + } + return c.ResolveBlock(best.block, best.captures), best.captures, subPath } // ResolveBlock merges mixin directives (lower priority) with block directives, @@ -286,9 +296,9 @@ return score, true } -func matchPrefix(pat, s string, caps map[string]string) (int, bool) { - score, _, ok := matchCaptures(pat, s, caps) - return score, ok +func matchPrefix(pat, s string, caps map[string]string) (int, string, bool) { + score, rem, ok := matchCaptures(pat, s, caps) + return score, rem, ok } func matchCaptures(pat, inp string, caps map[string]string) (int, string, bool) { @@ -306,6 +316,10 @@ rest := pat[end+1:] for split := len(inp); split >= 1; split-- { + // Captures never span path separators: <n> matches one segment only. + if strings.Contains(inp[:split], "/") { + continue + } score, finalRem, ok := matchCaptures(rest, inp[split:], caps) if ok { if capName != "_" {
