func (m *TLSMuxer) HandleErrors() {
	for {
		conn, err := m.NextError()
		if conn == nil {
			if _, ok := err.(Closed); ok {
				return
			} else {
				continue
			}
		} else {
			conn.Close()
		}
	}
}
HandleErrors is the default error handler for TLS muxers. At the moment, it simply
closes connections which are invalid or destined for virtual host names that it is
not listening for.
You must invoke this function if you do not want to handle the errors yourself.
package vhost
import (
	"fmt"
	"net"
	"strings"
	"sync"
	"time"
)
var (
	normalize = strings.ToLower
	isClosed  = func(err error) bool {
		netErr, ok := err.(net.Error)
		if ok {
			return netErr.Temporary()
		}
		return false
	}
)
type NotFound struct {
	error
}
type BadRequest struct {
	error
}
type Closed struct {
	error
}
type (
	muxFn func(net.Conn) (Conn, error)
	muxErr struct {
		err  error
		conn net.Conn
	}
)
type VhostMuxer struct {
	listener     net.Listener          
	muxTimeout   time.Duration         
	vhostFn      muxFn                 
	muxErrors    chan muxErr           
	registry     map[string]*Listener  
	sync.RWMutex                       
}
func NewVhostMuxer(listener net.Listener, vhostFn muxFn, muxTimeout time.Duration) (*VhostMuxer, error) {
	mux := &VhostMuxer{
		listener:   listener,
		muxTimeout: muxTimeout,
		vhostFn:    vhostFn,
		muxErrors:  make(chan muxErr),
		registry:   make(map[string]*Listener),
	}
	go mux.run()
	return mux, nil
}
func (m *VhostMuxer) Listen(name string) (net.Listener, error) {
	name = normalize(name)
	vhost := &Listener{
		name:   name,
		mux:    m,
		accept: make(chan Conn),
	}
	if err := m.set(name, vhost); err != nil {
		return nil, err
	}
	return vhost, nil
}
func (m *VhostMuxer) NextError() (net.Conn, error) {
	muxErr := <-m.muxErrors
	return muxErr.conn, muxErr.err
}
func (m *VhostMuxer) Close() {
	m.listener.Close()
}
func (m *VhostMuxer) run() {
	for {
		conn, err := m.listener.Accept()
		if err != nil {
			if isClosed(err) {
				m.sendError(nil, Closed{err})
				return
			} else {
				m.sendError(nil, err)
				continue
			}
		}
		go m.handle(conn)
	}
}
func (m *VhostMuxer) handle(conn net.Conn) {
	defer func() {
		if r := recover(); r != nil {
			m.sendError(conn, fmt.Errorf("NameMux.handle failed with error %v", r))
		}
	}()
	if err := conn.SetDeadline(time.Now().Add(m.muxTimeout)); err != nil {
		m.sendError(conn, fmt.Errorf("Failed to set deadline: %v", err))
		return
	}
	vconn, err := m.vhostFn(conn)
	if err != nil {
		m.sendError(conn, BadRequest{fmt.Errorf("Failed to extract vhost name: %v", err)})
		return
	}
	host := normalize(vconn.Host())
	l, ok := m.get(host)
	if !ok {
		m.sendError(vconn, NotFound{fmt.Errorf("Host not found: %v", host)})
		return
	}
	if err = vconn.SetDeadline(time.Time{}); err != nil {
		m.sendError(vconn, fmt.Errorf("Failed unset connection deadline: %v", err))
		return
	}
	l.accept <- vconn
}
func (m *VhostMuxer) sendError(conn net.Conn, err error) {
	m.muxErrors <- muxErr{conn: conn, err: err}
}
func (m *VhostMuxer) get(name string) (l *Listener, ok bool) {
	m.RLock()
	defer m.RUnlock()
	l, ok = m.registry[name]
	if !ok {
		parts := strings.Split(name, ".")
		for i := 0; i < len(parts)-1; i++ {
			parts[i] = "*"
			name = strings.Join(parts[i:], ".")
			l, ok = m.registry[name]
			if ok {
				break
			}
		}
	}
	return
}
func (m *VhostMuxer) set(name string, l *Listener) error {
	m.Lock()
	defer m.Unlock()
	if _, exists := m.registry[name]; exists {
		return fmt.Errorf("name %s is already bound", name)
	}
	m.registry[name] = l
	return nil
}
func (m *VhostMuxer) del(name string) {
	m.Lock()
	defer m.Unlock()
	delete(m.registry, name)
}
const (
	serverError = `HTTP/1.0 500 Internal Server Error
Content-Length: 22
Internal Server Error
`
	notFound = `HTTP/1.0 404 Not Found
Content-Length: 14
404 not found
`
	badRequest = `HTTP/1.0 400 Bad Request
Content-Length: 12
Bad Request
`
)
type HTTPMuxer struct {
	*VhostMuxer
}
func (m *HTTPMuxer) HandleErrors() {
	for {
		m.HandleError(m.NextError())
	}
}
func (m *HTTPMuxer) HandleError(conn net.Conn, err error) {
	switch err.(type) {
	case Closed:
		return
	case NotFound:
		conn.Write([]byte(notFound))
	case BadRequest:
		conn.Write([]byte(badRequest))
	default:
		if conn != nil {
			conn.Write([]byte(serverError))
		}
	}
	if conn != nil {
		conn.Close()
	}
}
func NewHTTPMuxer(listener net.Listener, muxTimeout time.Duration) (*HTTPMuxer, error) {
	fn := func(c net.Conn) (Conn, error) { return HTTP(c) }
	mux, err := NewVhostMuxer(listener, fn, muxTimeout)
	return &HTTPMuxer{mux}, err
}
type TLSMuxer struct {
	*VhostMuxer
}