package goxy import ( "crypto/tls" "encoding/json" "errors" "os" ) // Route defines a set of routes including correspondent TLS certificates type Route map[string]Entry // GetCertificate returns certificate for SNI negotiation func (r Route) GetCertificate(h *tls.ClientHelloInfo) (*tls.Certificate, error) { if e, ok := r[h.ServerName]; ok && e.cert != nil { return e.cert, nil } return nil, errors.New("no cert for " + h.ServerName) } // Save routes to persistent file func (r Route) Save(fname string) error { fd, err := os.Create(fname) if err != nil { return err } defer fd.Close() return json.NewEncoder(fd).Encode(r) } // Load routes from persistent file func (r *Route) Load(fname string) error { fd, err := os.Open(fname) if err != nil { return err } defer fd.Close() return json.NewDecoder(fd).Decode(r) } // Entry holds routing settings type Entry struct { Host string // HostName Upstream string // URL Cert []byte // PEM Key []byte // PEM cert *tls.Certificate // Parsed } func (e Entry) String() string { ret := e.Host + " → " + e.Upstream if e.cert != nil { ret += " with TLS" } return ret }