package api import ( "crypto/tls" "fmt" "net/http" "strings" ) var localRoutes = []string{"/info", "/_ping", "/debug"} // Replica is an API replica that reserves proxy to the primary. type Replica struct { handler http.Handler tlsConfig *tls.Config primary string } // NewReplica creates a new API replica. func NewReplica(handler http.Handler, tlsConfig *tls.Config) *Replica { return &Replica{ handler: handler, tlsConfig: tlsConfig, } } // SetPrimary sets the address of the primary Swarm manager func (p *Replica) SetPrimary(primary string) { // FIXME: We have to kill current connections before doing this. p.primary = primary } // ServeHTTP is the http.Handler. func (p *Replica) 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.handler.ServeHTTP(w, r) return } } // Otherwise, forward. if p.primary == "" { httpError(w, "No elected primary cluster manager", http.StatusInternalServerError) return } if err := hijack(p.tlsConfig, p.primary, w, r); err != nil { httpError(w, fmt.Sprintf("Unable to reach primary cluster manager (%s): %v", err, p.primary), http.StatusInternalServerError) } }