in router/core/header_rule_engine.go [394:512]
func (h *HeaderPropagation) applyRequestRule(ctx RequestContext, request *http.Request, rule *config.RequestHeaderRule) {
if rule.Operation == config.HeaderRuleOperationSet {
reqCtx := getRequestContext(request.Context())
if rule.ValueFrom != nil && rule.ValueFrom.ContextField != "" {
val := getCustomDynamicAttributeValue(rule.ValueFrom, reqCtx, nil)
value := fmt.Sprintf("%v", val)
if value != "" {
request.Header.Set(rule.Name, value)
}
return
}
if rule.Expression != "" {
value, err := h.getRequestRuleExpressionValue(rule, reqCtx)
if err != nil {
reqCtx.SetError(err)
} else if value != "" {
request.Header.Set(rule.Name, value)
}
return
}
request.Header.Set(rule.Name, rule.Value)
return
}
if rule.Operation != config.HeaderRuleOperationPropagate {
return
}
/**
* Rename the header before propagating and delete the original
*/
if rule.Rename != "" && rule.Named != "" {
// Ignore the rule when the target header is in the ignored list
if slices.Contains(ignoredHeaders, rule.Rename) {
return
}
value := ctx.Request().Header.Get(rule.Named)
if value != "" {
request.Header.Set(rule.Rename, ctx.Request().Header.Get(rule.Named))
request.Header.Del(rule.Named)
return
} else if rule.Default != "" {
request.Header.Set(rule.Rename, rule.Default)
request.Header.Del(rule.Named)
return
}
return
}
/**
* Propagate the header as is
*/
if rule.Named != "" {
if slices.Contains(ignoredHeaders, rule.Named) {
return
}
values := ctx.Request().Header.Values(rule.Named)
if len(values) > 0 {
request.Header[http.CanonicalHeaderKey(rule.Named)] = values
} else if rule.Default != "" {
request.Header.Set(rule.Named, rule.Default)
}
return
}
/**
* Matching based on regex
*/
if regex, ok := h.regex[rule.Matching]; ok {
// Headers are case-insensitive, but Go canonicalize them
// Issue: https://github.com/golang/go/issues/37834
for name := range ctx.Request().Header {
result := regex.MatchString(name)
if rule.NegateMatch {
result = !result
}
if result {
/**
* Rename the header before propagating and delete the original
*/
if rule.Rename != "" && rule.Named == "" {
if slices.Contains(ignoredHeaders, rule.Rename) {
continue
}
value := ctx.Request().Header.Get(name)
if value != "" {
request.Header.Set(rule.Rename, ctx.Request().Header.Get(name))
request.Header.Del(name)
} else if rule.Default != "" {
request.Header.Set(rule.Rename, rule.Default)
request.Header.Del(name)
}
continue
}
/**
* Propagate the header as is
*/
if slices.Contains(ignoredHeaders, name) {
continue
}
request.Header.Set(name, ctx.Request().Header.Get(name))
}
}
}
}