Repository: caddyserver/caddy
File: modules/caddyhttp/headers/headers.go (Go)

Code before:

	// The string with which to replace matches.
	Replace string `json:"replace,omitempty"`

	re *regexp.Regexp
}

// RespHeaderOps defines manipulations for response headers.
type RespHeaderOps struct {
	*HeaderOps

	// If set, header operations will be deferred until
	// they are written out and only performed if the
	// response matches these criteria.
	Require *caddyhttp.ResponseMatcher `json:"require,omitempty"`

	// If true, header operations will be deferred until
	// they are written out. Superceded if Require is set.
	// Usually you will need to set this to true if any
	// fields are being deleted.
	Deferred bool `json:"deferred,omitempty"`
}

// ApplyTo applies ops to hdr using repl.
func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) {
	// delete all fields before manipulating HTTP headers
	for _, fieldName := range ops.Delete {
		fieldName = strings.ToLower(repl.ReplaceKnown(fieldName, ""))
		if fieldName == "*" {
			for existingField := range hdr {
				delete(hdr, existingField)
			}
		}
	}

	// add
	for fieldName, vals := range ops.Add {
		fieldName = repl.ReplaceKnown(fieldName, "")
		for _, v := range vals {
			hdr.Add(fieldName, repl.ReplaceKnown(v, ""))
		}
	}

	// set
	for fieldName, vals := range ops.Set {
		fieldName = repl.ReplaceKnown(fieldName, "")
		var newVals []string
		for i := range vals {
			// append to new slice so we don't overwrite
			// the original values in ops.Set
			newVals = append(newVals, repl.ReplaceKnown(vals[i], ""))

Review comment (suggestion):
```suggestion
	// before manipulating headers in other ways, check if there
	// is configuration to delete all headers, and do that first
	// because if a header is to be added, we don't want to delete
	// it also
```

Code after:

	// The string with which to replace matches.
	Replace string `json:"replace,omitempty"`

	re *regexp.Regexp
}

// RespHeaderOps defines manipulations for response headers.
type RespHeaderOps struct {
	*HeaderOps

	// If set, header operations will be deferred until
	// they are written out and only performed if the
	// response matches these criteria.
	Require *caddyhttp.ResponseMatcher `json:"require,omitempty"`

	// If true, header operations will be deferred until
	// they are written out. Superceded if Require is set.
	// Usually you will need to set this to true if any
	// fields are being deleted.
	Deferred bool `json:"deferred,omitempty"`
}

// ApplyTo applies ops to hdr using repl.
func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) {
	// before manipulating headers in other ways, check if there
	// is configuration to delete all headers, and do that first
	// because if a header is to be added, we don't want to delete
	// it also
	for _, fieldName := range ops.Delete {
		fieldName = repl.ReplaceKnown(fieldName, "")
		if fieldName == "*" {
			for existingField := range hdr {
				delete(hdr, existingField)
			}
		}
	}

	// add
	for fieldName, vals := range ops.Add {
		fieldName = repl.ReplaceKnown(fieldName, "")
		for _, v := range vals {
			hdr.Add(fieldName, repl.ReplaceKnown(v, ""))
		}
	}

	// set
	for fieldName, vals := range ops.Set {
		fieldName = repl.ReplaceKnown(fieldName, "")
		var newVals []string
		for i := range vals {