mirror of
https://github.com/coredns/coredns.git
synced 2025-12-12 05:15:12 -05:00
plugin/rewrite: streamline the ResponseRule handling. (#4473)
* plugin/rewrite: streamline the ResponseRule handling. The functionality of a response rule is now completely encapsulated behind a `ResponseRule` interface. This significantly simplifies the complete processing flow, it enables more flexible response handling and it is possible to eliminate lots of state flags, ifs and switches. Based on the new flexibility the pull request also enables to support a response name rewrite for all name rewrite types. To be compatible, an explicit `answer auto` option is added to support a best effort response rewrite (name and value). Additionally now all name rewrite rules support additional name and value reponse rewrite options. Using this feature it is also possible now to rewrite a complete sub domain hierarchy to a single domain name combined with a correct rewrite (#2389). Signed-off-by: Uwe Krueger <uwe.krueger@sap.com> * revert policy Signed-off-by: Uwe Krueger <uwe.krueger@sap.com> Co-authored-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
@@ -31,40 +31,34 @@ const (
|
||||
|
||||
// Rewrite is a plugin to rewrite requests internally before being handled.
|
||||
type Rewrite struct {
|
||||
Next plugin.Handler
|
||||
Rules []Rule
|
||||
noRevert bool
|
||||
Next plugin.Handler
|
||||
Rules []Rule
|
||||
RevertPolicy
|
||||
}
|
||||
|
||||
// ServeDNS implements the plugin.Handler interface.
|
||||
func (rw Rewrite) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
||||
wr := NewResponseReverter(w, r)
|
||||
if rw.RevertPolicy == nil {
|
||||
rw.RevertPolicy = NewRevertPolicy(false, false)
|
||||
}
|
||||
wr := NewResponseReverter(w, r, rw.RevertPolicy)
|
||||
state := request.Request{W: w, Req: r}
|
||||
|
||||
for _, rule := range rw.Rules {
|
||||
switch result := rule.Rewrite(ctx, state); result {
|
||||
case RewriteDone:
|
||||
respRules, result := rule.Rewrite(ctx, state)
|
||||
if result == RewriteDone {
|
||||
if _, ok := dns.IsDomainName(state.Req.Question[0].Name); !ok {
|
||||
err := fmt.Errorf("invalid name after rewrite: %s", state.Req.Question[0].Name)
|
||||
state.Req.Question[0] = wr.originalQuestion
|
||||
return dns.RcodeServerFailure, err
|
||||
}
|
||||
for _, respRule := range rule.GetResponseRules() {
|
||||
if respRule.Active {
|
||||
wr.ResponseRewrite = true
|
||||
wr.ResponseRules = append(wr.ResponseRules, respRule)
|
||||
}
|
||||
}
|
||||
wr.ResponseRules = append(wr.ResponseRules, respRules...)
|
||||
if rule.Mode() == Stop {
|
||||
if rw.noRevert {
|
||||
return plugin.NextOrFailure(rw.Name(), rw.Next, ctx, w, r)
|
||||
}
|
||||
return plugin.NextOrFailure(rw.Name(), rw.Next, ctx, wr, r)
|
||||
break
|
||||
}
|
||||
case RewriteIgnored:
|
||||
}
|
||||
}
|
||||
if rw.noRevert || len(wr.ResponseRules) == 0 {
|
||||
if !rw.RevertPolicy.DoRevert() || len(wr.ResponseRules) == 0 {
|
||||
return plugin.NextOrFailure(rw.Name(), rw.Next, ctx, w, r)
|
||||
}
|
||||
return plugin.NextOrFailure(rw.Name(), rw.Next, ctx, wr, r)
|
||||
@@ -76,11 +70,9 @@ func (rw Rewrite) Name() string { return "rewrite" }
|
||||
// Rule describes a rewrite rule.
|
||||
type Rule interface {
|
||||
// Rewrite rewrites the current request.
|
||||
Rewrite(ctx context.Context, state request.Request) Result
|
||||
Rewrite(ctx context.Context, state request.Request) (ResponseRules, Result)
|
||||
// Mode returns the processing mode stop or continue.
|
||||
Mode() string
|
||||
// GetResponseRules returns rules to rewrite response with, if any.
|
||||
GetResponseRules() []ResponseRule
|
||||
}
|
||||
|
||||
func newRule(args ...string) (Rule, error) {
|
||||
|
||||
Reference in New Issue
Block a user