func (m MatchFile) selectFile(r *http.Request) (matched bool) {
	repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)

	root := repl.ReplaceAll(m.Root, ".")

	// common preparation of the file into parts
	prepareFilePath := func(file string) (suffix, fullpath, remainder string) {
		suffix, remainder = m.firstSplit(path.Clean(repl.ReplaceAll(file, "")))
		if strings.HasSuffix(file, "/") {
			suffix += "/"
		}
		fullpath = caddyhttp.SanitizedPathJoin(root, suffix)
		return
	}

	// sets up the placeholders for the matched file
	setPlaceholders := func(info os.FileInfo, rel string, abs string, remainder string) {
		repl.Set("http.matchers.file.relative", rel)
		repl.Set("http.matchers.file.absolute", abs)
		repl.Set("http.matchers.file.remainder", remainder)

		fileType := "file"
		if info.IsDir() {
			fileType = "directory"
		}
		repl.Set("http.matchers.file.type", fileType)
	}

	switch m.TryPolicy {
	case "", tryPolicyFirstExist:
		for _, f := range m.TryFiles {
			if err := parseErrorCode(f); err != nil {
				caddyhttp.SetVar(r.Context(), caddyhttp.MatcherErrorVarKey, err)
				return
			}
			suffix, fullpath, remainder := prepareFilePath(f)
			if info, exists := strictFileExists(fullpath); exists {
				setPlaceholders(info, suffix, fullpath, remainder)
				return true
			}
		}

	case tryPolicyLargestSize:
		var largestSize int64
		var largestFilename string
		var largestSuffix string
		var remainder string
		var info os.FileInfo
		for _, f := range m.TryFiles {
			suffix, fullpath, splitRemainder := prepareFilePath(f)
			info, err := os.Stat(fullpath)
			if err == nil && info.Size() > largestSize {
				largestSize = info.Size()
				largestFilename = fullpath
				largestSuffix = suffix
				remainder = splitRemainder
			}
		}
		setPlaceholders(info, largestSuffix, largestFilename, remainder)
		return true

	case tryPolicySmallestSize:
		var smallestSize int64
		var smallestFilename string
		var smallestSuffix string
		var remainder string
		var info os.FileInfo
		for _, f := range m.TryFiles {
			suffix, fullpath, splitRemainder := prepareFilePath(f)
			info, err := os.Stat(fullpath)
			if err == nil && (smallestSize == 0 || info.Size() < smallestSize) {
				smallestSize = info.Size()
				smallestFilename = fullpath
				smallestSuffix = suffix
				remainder = splitRemainder
			}
		}
		setPlaceholders(info, smallestSuffix, smallestFilename, remainder)
		return true

	case tryPolicyMostRecentlyMod:
		var recentDate time.Time
		var recentFilename string
		var recentSuffix string
		var remainder string
		var info os.FileInfo
		for _, f := range m.TryFiles {
			suffix, fullpath, splitRemainder := prepareFilePath(f)
			info, err := os.Stat(fullpath)
			if err == nil &&
				(recentDate.IsZero() || info.ModTime().After(recentDate)) {
				recentDate = info.ModTime()
				recentFilename = fullpath
				recentSuffix = suffix
				remainder = splitRemainder
			}
		}
		setPlaceholders(info, recentSuffix, recentFilename, remainder)
		return true
	}

	return
}
// selectFile chooses a file according to m.TryPolicy by appending
// the paths in m.TryFiles to m.Root, with placeholder replacements.
selectFile chooses a file according to m.TryPolicy by appending
the paths in m.TryFiles to m.Root, with placeholder replacements.
// selectFile chooses a file according to m . TryPolicy by appending // the paths in m . TryFiles to m . Root with placeholder replacements .
func (m MatchFile) selectFile(r *http.Request) (matched bool) {
	repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
	root := repl.ReplaceAll(m.Root, ".")
	prepareFilePath := func(file string) (suffix, fullpath, remainder string) {
		suffix, remainder = m.firstSplit(path.Clean(repl.ReplaceAll(file, "")))
		if strings.HasSuffix(file, "/") {
			suffix += "/"
		}
		fullpath = caddyhttp.SanitizedPathJoin(root, suffix)
		return
	}
	setPlaceholders := func(info os.FileInfo, rel string, abs string, remainder string) {
		repl.Set("http.matchers.file.relative", rel)
		repl.Set("http.matchers.file.absolute", abs)
		repl.Set("http.matchers.file.remainder", remainder)
		fileType := "file"
		if info.IsDir() {
			fileType = "directory"
		}
		repl.Set("http.matchers.file.type", fileType)
	}
	switch m.TryPolicy {
	case "", tryPolicyFirstExist:
		for _, f := range m.TryFiles {
			if err := parseErrorCode(f); err != nil {
				caddyhttp.SetVar(r.Context(), caddyhttp.MatcherErrorVarKey, err)
				return
			}
			suffix, fullpath, remainder := prepareFilePath(f)
			if info, exists := strictFileExists(fullpath); exists {
				setPlaceholders(info, suffix, fullpath, remainder)
				return true
			}
		}
	case tryPolicyLargestSize:
		var largestSize int64
		var largestFilename string
		var largestSuffix string
		var remainder string
		var info os.FileInfo
		for _, f := range m.TryFiles {
			suffix, fullpath, splitRemainder := prepareFilePath(f)
			info, err := os.Stat(fullpath)
			if err == nil && info.Size() > largestSize {
				largestSize = info.Size()
				largestFilename = fullpath
				largestSuffix = suffix
				remainder = splitRemainder
			}
		}
		setPlaceholders(info, largestSuffix, largestFilename, remainder)
		return true
	case tryPolicySmallestSize:
		var smallestSize int64
		var smallestFilename string
		var smallestSuffix string
		var remainder string
		var info os.FileInfo
		for _, f := range m.TryFiles {
			suffix, fullpath, splitRemainder := prepareFilePath(f)
			info, err := os.Stat(fullpath)
			if err == nil && (smallestSize == 0 || info.Size() < smallestSize) {
				smallestSize = info.Size()
				smallestFilename = fullpath
				smallestSuffix = suffix
				remainder = splitRemainder
			}
		}
		setPlaceholders(info, smallestSuffix, smallestFilename, remainder)
		return true
	case tryPolicyMostRecentlyMod:
		var recentDate time.Time
		var recentFilename string
		var recentSuffix string
		var remainder string
		var info os.FileInfo
		for _, f := range m.TryFiles {
			suffix, fullpath, splitRemainder := prepareFilePath(f)
			info, err := os.Stat(fullpath)
			if err == nil &&
				(recentDate.IsZero() || info.ModTime().After(recentDate)) {
				recentDate = info.ModTime()
				recentFilename = fullpath
				recentSuffix = suffix
				remainder = splitRemainder
			}
		}
		setPlaceholders(info, recentSuffix, recentFilename, remainder)
		return true
	}
	return
}
func ( m MatchFile ) selectFile ( r * http . Request ) ( matched bool ) { repl := r . Context ( ) . Value ( caddy . ReplacerCtxKey ) . ( * caddy . Replacer ) root := repl . ReplaceAll ( m . Root , " " ) prepareFilePath := func ( file string ) ( suffix , fullpath , remainder string ) { suffix , remainder = m . firstSplit ( path . Clean ( repl . ReplaceAll ( file , " " ) ) ) if strings . HasSuffix ( file , " " ) { suffix += " " } fullpath = caddyhttp . SanitizedPathJoin ( root , suffix ) return } setPlaceholders := func ( info os . FileInfo , rel string , abs string , remainder string ) { repl . Set ( " " , rel ) repl . Set ( " " , abs ) repl . Set ( " " , remainder ) fileType := " " if info . IsDir ( ) { fileType = " " } repl . Set ( " " , fileType ) } switch m . TryPolicy { case " " , tryPolicyFirstExist : for _ , f := range m . TryFiles { if err := parseErrorCode ( f ) ; err != nil { caddyhttp . SetVar ( r . Context ( ) , caddyhttp . MatcherErrorVarKey , err ) return } suffix , fullpath , remainder := prepareFilePath ( f ) if info , exists := strictFileExists ( fullpath ) ; exists { setPlaceholders ( info , suffix , fullpath , remainder ) return true } } case tryPolicyLargestSize : var largestSize int64 var largestFilename string var largestSuffix string var remainder string var info os . FileInfo for _ , f := range m . TryFiles { suffix , fullpath , splitRemainder := prepareFilePath ( f ) info , err := os . Stat ( fullpath ) if err == nil && info . Size ( ) > largestSize { largestSize = info . Size ( ) largestFilename = fullpath largestSuffix = suffix remainder = splitRemainder } } setPlaceholders ( info , largestSuffix , largestFilename , remainder ) return true case tryPolicySmallestSize : var smallestSize int64 var smallestFilename string var smallestSuffix string var remainder string var info os . FileInfo for _ , f := range m . TryFiles { suffix , fullpath , splitRemainder := prepareFilePath ( f ) info , err := os . Stat ( fullpath ) if err == nil && ( smallestSize == 0 || info . Size ( ) < smallestSize ) { smallestSize = info . Size ( ) smallestFilename = fullpath smallestSuffix = suffix remainder = splitRemainder } } setPlaceholders ( info , smallestSuffix , smallestFilename , remainder ) return true case tryPolicyMostRecentlyMod : var recentDate time . Time var recentFilename string var recentSuffix string var remainder string var info os . FileInfo for _ , f := range m . TryFiles { suffix , fullpath , splitRemainder := prepareFilePath ( f ) info , err := os . Stat ( fullpath ) if err == nil && ( recentDate . IsZero ( ) || info . ModTime ( ) . After ( recentDate ) ) { recentDate = info . ModTime ( ) recentFilename = fullpath recentSuffix = suffix remainder = splitRemainder } } setPlaceholders ( info , recentSuffix , recentFilename , remainder ) return true } return }
selectFile chooses a file according to m.TryPolicy by appending
the paths in m.TryFiles to m.Root, with placeholder replacements.
selectFile chooses a file according to m . TryPolicy by appending the paths in m . TryFiles to m . Root with placeholder replacements .
// common preparation of the file into parts // sets up the placeholders for the matched file