1
0
Fork 0

When joining try HTTPS if HTTP fails

master
Philip O'Toole 5 years ago
parent f01e6b1b0a
commit de379a883c

@ -31,7 +31,7 @@ func Join(joinAddr []string, advAddr string, tlsConfig *tls.Config) (string, err
for i := 0; i < numAttempts; i++ {
for _, a := range joinAddr {
j, err = join(a, advAddr, tlsConfig)
j, err = join(a, advAddr, tlsConfig, logger)
if err == nil {
// Success!
return j, nil
@ -44,7 +44,7 @@ func Join(joinAddr []string, advAddr string, tlsConfig *tls.Config) (string, err
return "", err
}
func join(joinAddr string, advAddr string, tlsConfig *tls.Config) (string, error) {
func join(joinAddr string, advAddr string, tlsConfig *tls.Config, logger *log.Logger) (string, error) {
// Join using IP address, as that is what Hashicorp Raft works in.
resv, err := net.ResolveTCPAddr("tcp", advAddr)
if err != nil {
@ -90,6 +90,22 @@ func join(joinAddr string, advAddr string, tlsConfig *tls.Config) (string, error
return "", fmt.Errorf("failed to join, invalid redirect received")
}
continue
case http.StatusBadRequest:
// One possible cause is that the target server is listening for HTTPS, but a HTTP
// attempt was made. Switch the protocol to HTTPS, and try again. This
if isHTTPS, err := httpd.CheckHTTPS(fullAddr); err != nil {
return "", err
} else if isHTTPS {
// It's already HTTPS, give up.
return "", fmt.Errorf("failed to join, node returned: %s: (%s)", resp.Status, string(b))
}
logger.Print("join via HTTP failed, trying HTTPS")
fullAddr, err = httpd.EnsureHTTPS(fullAddr)
if err != nil {
return "", err
}
continue
default:
return "", fmt.Errorf("failed to join, node returned: %s: (%s)", resp.Status, string(b))
}

@ -120,7 +120,7 @@ func sendRequest(ctx *cli.Context, urlStr string, line string, argv *argT, ret i
var rootCAs *x509.CertPool
if argv.CACert != "" {
pemCerts, err:= ioutil.ReadFile(argv.CACert)
pemCerts, err := ioutil.ReadFile(argv.CACert)
if err != nil {
return err
}

@ -354,7 +354,7 @@ func determineJoinAddresses() ([]string, error) {
if discoID != "" {
log.Printf("registering with Discovery Service at %s with ID %s", discoURL, discoID)
c := disco.New(discoURL)
r, err := c.Register(discoID, apiAdv)
r, err := c.Register(discoID, "http", apiAdv)
if err != nil {
return nil, err
}

@ -39,10 +39,10 @@ func (c *Client) URL() string {
}
// Register attempts to register with the Discovery Service, using the given
// address.
func (c *Client) Register(id, addr string) (*Response, error) {
// proto and address.
func (c *Client) Register(id, proto, addr string) (*Response, error) {
m := map[string]string{
"addr": addr,
"addr": fmt.Sprintf("%s:%s", proto, addr),
}
url := c.registrationURL(c.url, id)

@ -15,6 +15,7 @@ import (
"net"
"net/http"
"net/http/pprof"
"net/url"
"os"
"runtime"
"strings"
@ -146,8 +147,8 @@ type Service struct {
statuses map[string]Statuser
CACertFile string // Path to root X.509 certificate.
CertFile string // Path to SSL certificate.
KeyFile string // Path to SSL private key.
CertFile string // Path to SSL certificate.
KeyFile string // Path to SSL private key.
credentialStore CredentialStore
@ -892,3 +893,26 @@ func NormalizeAddr(addr string) string {
}
return addr
}
// EnsureHTTPS returns the given URL, ensuring it is using the HTTPS protocol.
func EnsureHTTPS(addr string) (string, error) {
u, err := url.Parse(addr)
if err != nil {
return "", err
}
if u.Scheme == "https" {
// It's already HTTPS, nothing to do.
return addr, nil
}
u.Scheme = "https"
return u.String(), nil
}
// CheckHTTPS returns true of the given URL uses HTTPS.
func CheckHTTPS(addr string) (bool, error) {
u, err := url.Parse(addr)
if err != nil {
return false, err
}
return u.Scheme == "https", nil
}

Loading…
Cancel
Save