mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00

The director class drives an httputil.ReverseProxy. This is used when etcd is deployed in proxy mode.
65 lines
1.1 KiB
Go
65 lines
1.1 KiB
Go
package proxy
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
)
|
|
|
|
func NewHandler(endpoints []string) (*httputil.ReverseProxy, error) {
|
|
d, err := newDirector(endpoints)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
proxy := httputil.ReverseProxy{
|
|
Director: d.direct,
|
|
Transport: &http.Transport{},
|
|
FlushInterval: 0,
|
|
}
|
|
|
|
return &proxy, nil
|
|
}
|
|
|
|
func newDirector(endpoints []string) (*director, error) {
|
|
if len(endpoints) == 0 {
|
|
return nil, errors.New("one or more endpoints required")
|
|
}
|
|
|
|
urls := make([]url.URL, len(endpoints))
|
|
for i, e := range endpoints {
|
|
u, err := url.Parse(e)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid endpoint %q: %v", e, err)
|
|
}
|
|
|
|
if u.Scheme == "" {
|
|
return nil, fmt.Errorf("invalid endpoint %q: scheme required", e)
|
|
}
|
|
|
|
if u.Host == "" {
|
|
return nil, fmt.Errorf("invalid endpoint %q: host empty", e)
|
|
}
|
|
|
|
urls[i] = *u
|
|
}
|
|
|
|
d := director{
|
|
endpoints: urls,
|
|
}
|
|
|
|
return &d, nil
|
|
}
|
|
|
|
type director struct {
|
|
endpoints []url.URL
|
|
}
|
|
|
|
func (d *director) direct(req *http.Request) {
|
|
choice := d.endpoints[0]
|
|
req.URL.Scheme = choice.Scheme
|
|
req.URL.Host = choice.Host
|
|
}
|