diff options
Diffstat (limited to 'plugin/kubernetes/apiproxy.go')
-rw-r--r-- | plugin/kubernetes/apiproxy.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/plugin/kubernetes/apiproxy.go b/plugin/kubernetes/apiproxy.go new file mode 100644 index 000000000..3e185f898 --- /dev/null +++ b/plugin/kubernetes/apiproxy.go @@ -0,0 +1,76 @@ +package kubernetes + +import ( + "fmt" + "io" + "log" + "net" + "net/http" + + "github.com/coredns/coredns/plugin/pkg/healthcheck" +) + +type proxyHandler struct { + healthcheck.HealthCheck +} + +type apiProxy struct { + http.Server + listener net.Listener + handler proxyHandler +} + +func (p *proxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + upstream := p.Select() + network := "tcp" + if upstream.Network != "" { + network = upstream.Network + } + address := upstream.Name + d, err := net.Dial(network, address) + if err != nil { + log.Printf("[ERROR] Unable to establish connection to upstream %s://%s: %s", network, address, err) + http.Error(w, fmt.Sprintf("Unable to establish connection to upstream %s://%s: %s", network, address, err), 500) + return + } + hj, ok := w.(http.Hijacker) + if !ok { + log.Printf("[ERROR] Unable to establish connection: no hijacker") + http.Error(w, "Unable to establish connection: no hijacker", 500) + return + } + nc, _, err := hj.Hijack() + if err != nil { + log.Printf("[ERROR] Unable to hijack connection: %s", err) + http.Error(w, fmt.Sprintf("Unable to hijack connection: %s", err), 500) + return + } + defer nc.Close() + defer d.Close() + + err = r.Write(d) + if err != nil { + log.Printf("[ERROR] Unable to copy connection to upstream %s://%s: %s", network, address, err) + http.Error(w, fmt.Sprintf("Unable to copy connection to upstream %s://%s: %s", network, address, err), 500) + return + } + + errChan := make(chan error, 2) + cp := func(dst io.Writer, src io.Reader) { + _, err := io.Copy(dst, src) + errChan <- err + } + go cp(d, nc) + go cp(nc, d) + <-errChan +} + +func (p *apiProxy) Run() { + p.handler.Start() + p.Serve(p.listener) +} + +func (p *apiProxy) Stop() { + p.handler.Stop() + p.listener.Close() +} |