docs/api/proxy.go

53 lines
1.2 KiB
Go

package api
import (
"crypto/tls"
"fmt"
"net/http"
"strings"
)
var localRoutes = []string{"/info", "/_ping"}
// ReverseProxy is a Docker reverse proxy.
type ReverseProxy struct {
api http.Handler
tlsConfig *tls.Config
dest string
}
// NewReverseProxy creates a new reverse proxy.
func NewReverseProxy(api http.Handler, tlsConfig *tls.Config) *ReverseProxy {
return &ReverseProxy{
api: api,
tlsConfig: tlsConfig,
}
}
// SetDestination sets the HTTP destination of the Docker endpoint.
func (p *ReverseProxy) SetDestination(dest string) {
// FIXME: We have to kill current connections before doing this.
p.dest = dest
}
// ServeHTTP is the http.Handler.
func (p *ReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Check whether we should handle this request locally.
for _, route := range localRoutes {
if strings.HasSuffix(r.URL.Path, route) {
p.api.ServeHTTP(w, r)
return
}
}
// Otherwise, forward.
if p.dest == "" {
httpError(w, "No cluster leader", http.StatusInternalServerError)
return
}
if err := hijack(p.tlsConfig, p.dest, w, r); err != nil {
httpError(w, fmt.Sprintf("Unable to reach cluster leader: %v", err), http.StatusInternalServerError)
}
}