server: Use separate mutex for handlers

This commit is contained in:
Adnan Maolood 2021-02-15 20:05:47 -05:00
parent ec269c5c9d
commit f158bb5f1d

View File

@ -51,6 +51,7 @@ type Server struct {
// registered handlers // registered handlers
handlers map[handlerKey]Handler handlers map[handlerKey]Handler
hosts map[string]bool hosts map[string]bool
hmu sync.Mutex
listeners map[*net.Listener]struct{} listeners map[*net.Listener]struct{}
conns map[*net.Conn]struct{} conns map[*net.Conn]struct{}
@ -71,8 +72,8 @@ type handlerKey struct {
// Wildcard patterns are supported (e.g. "*.example.com"). // Wildcard patterns are supported (e.g. "*.example.com").
// To handle any hostname, use the wildcard pattern "*". // To handle any hostname, use the wildcard pattern "*".
func (srv *Server) Handle(pattern string, handler Handler) { func (srv *Server) Handle(pattern string, handler Handler) {
srv.mu.Lock() srv.hmu.Lock()
defer srv.mu.Unlock() defer srv.hmu.Unlock()
if pattern == "" { if pattern == "" {
panic("gemini: invalid pattern") panic("gemini: invalid pattern")
@ -309,7 +310,10 @@ func (srv *Server) getCertificate(h *tls.ClientHelloInfo) (*tls.Certificate, err
// If no certificate is found in the certificate store or the certificate // If no certificate is found in the certificate store or the certificate
// is expired, it calls GetCertificate to retrieve a new certificate. // is expired, it calls GetCertificate to retrieve a new certificate.
func (srv *Server) lookupCertificate(pattern, hostname string) (*tls.Certificate, error) { func (srv *Server) lookupCertificate(pattern, hostname string) (*tls.Certificate, error) {
if _, ok := srv.hosts[pattern]; !ok { srv.hmu.Lock()
_, ok := srv.hosts[pattern]
srv.hmu.Unlock()
if !ok {
return nil, errors.New("hostname not registered") return nil, errors.New("hostname not registered")
} }
@ -398,6 +402,8 @@ func (srv *Server) respond(conn net.Conn) {
} }
func (srv *Server) handler(r *Request) Handler { func (srv *Server) handler(r *Request) Handler {
srv.hmu.Lock()
defer srv.hmu.Unlock()
if h, ok := srv.handlers[handlerKey{r.URL.Scheme, r.URL.Hostname()}]; ok { if h, ok := srv.handlers[handlerKey{r.URL.Scheme, r.URL.Hostname()}]; ok {
return h return h
} }