MCPcopy
hub / github.com/caddyserver/caddy / matchPatternWithEscapeSequence

Method matchPatternWithEscapeSequence

modules/caddyhttp/matchers.go:545–649  ·  modules/caddyhttp/matchers.go::MatchPath.matchPatternWithEscapeSequence
(escapedPath, matchPath string)

Source from the content-addressed store, hash-verified

543}
544
545func (MatchPath) matchPatternWithEscapeSequence(escapedPath, matchPath string) bool {
546 escapedPath = strings.ToLower(escapedPath)
547 // We would just compare the pattern against r.URL.Path,
548 // but the pattern contains %, indicating that we should
549 // compare at least some part of the path in raw/escaped
550 // space, not normalized space; so we build the string we
551 // will compare against by adding the normalized parts
552 // of the path, then switching to the escaped parts where
553 // the pattern hints to us wherever % is present.
554 var sb strings.Builder
555
556 // iterate the pattern and escaped path in lock-step;
557 // increment iPattern every time we consume a char from the pattern,
558 // increment iPath every time we consume a char from the path;
559 // iPattern and iPath are our cursors/iterator positions for each string
560 var iPattern, iPath int
561 for {
562 if iPattern >= len(matchPath) || iPath >= len(escapedPath) {
563 break
564 }
565 // get the next character from the request path
566
567 pathCh := string(escapedPath[iPath])
568 var escapedPathCh string
569
570 // normalize (decode) escape sequences
571 if pathCh == "%" && len(escapedPath) >= iPath+3 {
572 // hold onto this in case we find out the intent is to match in escaped space here;
573 // we lowercase it even though technically the spec says: "For consistency, URI
574 // producers and normalizers should use uppercase hexadecimal digits for all percent-
575 // encodings" (RFC 3986 section 2.1) - we lowercased the matcher pattern earlier in
576 // provisioning so we do the same here to gain case-insensitivity in equivalence;
577 // besides, this string is never shown visibly
578 escapedPathCh = strings.ToLower(escapedPath[iPath : iPath+3])
579
580 var err error
581 pathCh, err = url.PathUnescape(escapedPathCh)
582 if err != nil {
583 // should be impossible unless EscapedPath() is giving us an invalid sequence!
584 return false
585 }
586 iPath += 2 // escape sequence is 2 bytes longer than normal char
587 }
588
589 // now get the next character from the pattern
590
591 normalize := true
592 switch matchPath[iPattern] {
593 case '%':
594 // escape sequence
595
596 // if not a wildcard ("%*"), compare literally; consume next two bytes of pattern
597 if len(matchPath) >= iPattern+3 && matchPath[iPattern+1] != '*' {
598 sb.WriteString(escapedPathCh)
599 iPath++
600 iPattern += 2
601 break
602 }

Callers 1

MatchWithErrorMethod · 0.95

Calls 3

ReplaceAllMethod · 0.80
MatchMethod · 0.65
StringMethod · 0.45

Tested by

no test coverage detected