package sni
import (
"net/http"
"crypto/tls"
"net"
)
type Certificates struct {
CertFile string
KeyFile string
}
func ListenAndServeTLSSNI(srv *http.Server, certs []Certificates) error {
addr := srv.Addr
if addr == "" {
addr = ":https"
}
config := &tls.Config{}
if srv.TLSConfig != nil {
*config = *srv.TLSConfig
}
if config.NextProtos == nil {
config.NextProtos = []string{"http/1.1"}
}
var err error
config.Certificates = make([]tls.Certificate, len(certs))
for i, v := range certs {
config.Certificates[i], err = tls.LoadX509KeyPair(v.CertFile, v.KeyFile)
if err != nil {
return err
}
}
config.BuildNameToCertificate()
conn, err := net.Listen("tcp", addr)
if err != nil {
return err
}
tlsListener := tls.NewListener(conn, config)
return srv.Serve(tlsListener)
}
package main
import (
"net/http"
"fmt"
"./sni"
)
func main() {
httpsServer := &http.Server{
Addr: ":8080",
}
var certs []sni.Certificates
certs = append(certs, sni.Certificates{
CertFile: "../etc/site1.pem",
KeyFile: "../etc/site1.key",
})
certs = append(certs, sni.Certificates{
CertFile: "../etc/site2.pem",
KeyFile: "../etc/site2.key",
})
fmt.Println("Listening on port 8080...")
err = sni.ListenAndServeTLSSNI(httpsServer, certs)
if err != nil {
fmt.Printf("err: %s", err)
}
}