| 
									
										
										
										
											2019-03-29 19:40:23 +00:00
										 |  |  | // Package cancel implements a plugin adds a canceling context to each request.
 | 
					
						
							|  |  |  | package cancel
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import (
 | 
					
						
							|  |  |  | 	"context"
 | 
					
						
							|  |  |  | 	"fmt"
 | 
					
						
							|  |  |  | 	"time"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/core/dnsserver"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 09:04:47 +08:00
										 |  |  | 	"github.com/caddyserver/caddy"
 | 
					
						
							| 
									
										
										
										
											2019-03-29 19:40:23 +00:00
										 |  |  | 	"github.com/miekg/dns"
 | 
					
						
							|  |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-28 10:40:43 +01:00
										 |  |  | func init() { plugin.Register("cancel", setup) }
 | 
					
						
							| 
									
										
										
										
											2019-03-29 19:40:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | func setup(c *caddy.Controller) error {
 | 
					
						
							| 
									
										
										
										
											2019-10-01 07:41:29 +01:00
										 |  |  | 	ca := Cancel{}
 | 
					
						
							| 
									
										
										
										
											2019-03-29 19:40:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for c.Next() {
 | 
					
						
							|  |  |  | 		args := c.RemainingArgs()
 | 
					
						
							|  |  |  | 		switch len(args) {
 | 
					
						
							|  |  |  | 		case 0:
 | 
					
						
							| 
									
										
										
										
											2019-10-01 07:41:29 +01:00
										 |  |  | 			ca.timeout = 5001 * time.Millisecond
 | 
					
						
							| 
									
										
										
										
											2019-03-29 19:40:23 +00:00
										 |  |  | 		case 1:
 | 
					
						
							|  |  |  | 			dur, err := time.ParseDuration(args[0])
 | 
					
						
							|  |  |  | 			if err != nil {
 | 
					
						
							|  |  |  | 				return plugin.Error("cancel", fmt.Errorf("invalid duration: %q", args[0]))
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 			if dur <= 0 {
 | 
					
						
							|  |  |  | 				return plugin.Error("cancel", fmt.Errorf("invalid negative duration: %q", args[0]))
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 			ca.timeout = dur
 | 
					
						
							|  |  |  | 		default:
 | 
					
						
							|  |  |  | 			return plugin.Error("cancel", c.ArgErr())
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
 | 
					
						
							|  |  |  | 		ca.Next = next
 | 
					
						
							|  |  |  | 		return ca
 | 
					
						
							|  |  |  | 	})
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Cancel is a plugin that adds a canceling context to each request's context.
 | 
					
						
							|  |  |  | type Cancel struct {
 | 
					
						
							|  |  |  | 	timeout time.Duration
 | 
					
						
							|  |  |  | 	Next    plugin.Handler
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ServeDNS implements the plugin.Handler interface.
 | 
					
						
							|  |  |  | func (c Cancel) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithTimeout(ctx, c.timeout)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	code, err := plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cancel()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return code, err
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Name implements the Handler interface.
 | 
					
						
							|  |  |  | func (c Cancel) Name() string { return "cancel" }
 |