Repository: caddyserver/caddy
File: replacer.go (Go)

Code before:

func (f fileReplacementProvider) replace(key string) (any, bool) {
	if !strings.HasPrefix(key, filePrefix) {
		return nil, false
	}

	filename := key[len(filePrefix):]
	maxSize := 1024 * 1024
	body, err := readFileIntoBuffer(filename, maxSize)
	if err != nil {
		wd, _ := os.Getwd()
		Log().Error("placeholder: failed to read file",
			zap.String("file", filename),
			zap.String("working_dir", wd),
			zap.Error(err))
		return nil, true
	}
	content := string(body)
	// Remove a single trailing newline, regardless of its type
	if strings.HasSuffix(content, "\r\n") {
		return strings.TrimSuffix(content, "\r\n"), true
	}
	if strings.HasSuffix(content, "\n") {
		return strings.TrimSuffix(content, "\n"), true
	}
	return strings.TrimSuffix(content, "\r"), true
}

// globalDefaultReplacementsProvider handles replacements
// that can be used in any context, such as system variables,
// time, or environment variables.
type globalDefaultReplacementProvider struct{}

func (f globalDefaultReplacementProvider) replace(key string) (any, bool) {
	// check environment variable
	const envPrefix = "env."
	if strings.HasPrefix(key, envPrefix) {
		return os.Getenv(key[len(envPrefix):]), true
	}

	switch key {
	case "system.hostname":
		// OK if there is an error; just return empty string
		name, _ := os.Hostname()
		return name, true
	case "system.slash":
		return string(filepath.Separator), true
	case "system.os":
		return runtime.GOOS, true
	case "system.wd":
		// OK if there is an error; just return empty string

Review comment (suggestion):
```suggestion
	content := string(body)
	content = strings.TrimSuffix(content, "\n")
	content = strings.TrimSuffix(content, "\r")
	return content, true
```

Was suggested already.

Code after:
type fileReplacementProvider struct{}

func (f fileReplacementProvider) replace(key string) (any, bool) {
	if !strings.HasPrefix(key, filePrefix) {
		return nil, false
	}

	filename := key[len(filePrefix):]
	maxSize := 1024 * 1024
	body, err := readFileIntoBuffer(filename, maxSize)
	if err != nil {
		wd, _ := os.Getwd()
		Log().Error("placeholder: failed to read file",
			zap.String("file", filename),
			zap.String("working_dir", wd),
			zap.Error(err))
		return nil, true
	}
	body = bytes.TrimSuffix(body, []byte("\n"))
	body = bytes.TrimSuffix(body, []byte("\r"))
	return string(body), true
}

// globalDefaultReplacementsProvider handles replacements
// that can be used in any context, such as system variables,
// time, or environment variables.
type globalDefaultReplacementProvider struct{}

func (f globalDefaultReplacementProvider) replace(key string) (any, bool) {
	// check environment variable
	const envPrefix = "env."
	if strings.HasPrefix(key, envPrefix) {
		return os.Getenv(key[len(envPrefix):]), true
	}

	switch key {
	case "system.hostname":
		// OK if there is an error; just return empty string
		name, _ := os.Hostname()
		return name, true
	case "system.slash":
		return string(filepath.Separator), true
	case "system.os":
		return runtime.GOOS, true
	case "system.wd":
		// OK if there is an error; just return empty string
		wd, _ := os.Getwd()
		return wd, true
	case "system.arch":
		return runtime.GOARCH, true
	case "time.now":