mirror of https://github.com/docker/docs.git
53 lines
1.3 KiB
Go
53 lines
1.3 KiB
Go
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)
|
|
}
|
|
}
|