forked from docker-archive/classicswarm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreplica.go
52 lines (44 loc) · 1.25 KB
/
replica.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package api
import (
"crypto/tls"
"fmt"
"net/http"
"strings"
)
var localRoutes = []string{"/info", "/_ping"}
// 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)
}
}