server: Add Handler field and remove Handle methods
This commit is contained in:
parent
f3cd70612b
commit
6edde376c4
81
server.go
81
server.go
@ -23,6 +23,9 @@ type Server struct {
|
|||||||
// See net.Dial for details of the address format.
|
// See net.Dial for details of the address format.
|
||||||
Addr string
|
Addr string
|
||||||
|
|
||||||
|
// The Handler to invoke.
|
||||||
|
Handler Handler
|
||||||
|
|
||||||
// ReadTimeout is the maximum duration for reading the entire
|
// ReadTimeout is the maximum duration for reading the entire
|
||||||
// request.
|
// request.
|
||||||
//
|
//
|
||||||
@ -48,66 +51,12 @@ type Server struct {
|
|||||||
// If nil, logging is done via the log package's standard logger.
|
// If nil, logging is done via the log package's standard logger.
|
||||||
ErrorLog *log.Logger
|
ErrorLog *log.Logger
|
||||||
|
|
||||||
// registered handlers
|
|
||||||
handlers map[handlerKey]Handler
|
|
||||||
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{}
|
||||||
done int32
|
done int32
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type handlerKey struct {
|
|
||||||
scheme string
|
|
||||||
hostname string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle registers the handler for the given pattern.
|
|
||||||
// If a handler already exists for pattern, Handle panics.
|
|
||||||
//
|
|
||||||
// The pattern must be in the form of "hostname" or "scheme://hostname".
|
|
||||||
// If no scheme is specified, a scheme of "gemini://" is implied.
|
|
||||||
// Wildcard patterns are supported (e.g. "*.example.com").
|
|
||||||
// To handle any hostname, use the wildcard pattern "*".
|
|
||||||
func (srv *Server) Handle(pattern string, handler Handler) {
|
|
||||||
srv.hmu.Lock()
|
|
||||||
defer srv.hmu.Unlock()
|
|
||||||
|
|
||||||
if pattern == "" {
|
|
||||||
panic("gemini: invalid pattern")
|
|
||||||
}
|
|
||||||
if handler == nil {
|
|
||||||
panic("gemini: nil handler")
|
|
||||||
}
|
|
||||||
if srv.handlers == nil {
|
|
||||||
srv.handlers = map[handlerKey]Handler{}
|
|
||||||
srv.hosts = map[string]bool{}
|
|
||||||
}
|
|
||||||
|
|
||||||
split := strings.SplitN(pattern, "://", 2)
|
|
||||||
var key handlerKey
|
|
||||||
if len(split) == 2 {
|
|
||||||
key.scheme = split[0]
|
|
||||||
key.hostname = split[1]
|
|
||||||
} else {
|
|
||||||
key.scheme = "gemini"
|
|
||||||
key.hostname = split[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := srv.handlers[key]; ok {
|
|
||||||
panic("gemini: multiple registrations for " + pattern)
|
|
||||||
}
|
|
||||||
srv.handlers[key] = handler
|
|
||||||
srv.hosts[key.hostname] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleFunc registers the handler function for the given pattern.
|
|
||||||
func (srv *Server) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
|
|
||||||
srv.Handle(pattern, HandlerFunc(handler))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListenAndServe listens for requests at the server's configured address.
|
// ListenAndServe listens for requests at the server's configured address.
|
||||||
// ListenAndServe listens on the TCP network address srv.Addr and then calls
|
// ListenAndServe listens on the TCP network address srv.Addr and then calls
|
||||||
// Serve to handle requests on incoming connections.
|
// Serve to handle requests on incoming connections.
|
||||||
@ -314,9 +263,7 @@ 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) {
|
||||||
srv.hmu.Lock()
|
_, ok := srv.Certificates.Lookup(pattern)
|
||||||
_, ok := srv.hosts[pattern]
|
|
||||||
srv.hmu.Unlock()
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("hostname not registered")
|
return nil, errors.New("hostname not registered")
|
||||||
}
|
}
|
||||||
@ -394,7 +341,7 @@ func (srv *Server) respond(conn net.Conn) {
|
|||||||
// Store remote address
|
// Store remote address
|
||||||
req.RemoteAddr = conn.RemoteAddr()
|
req.RemoteAddr = conn.RemoteAddr()
|
||||||
|
|
||||||
h := srv.handler(req)
|
h := srv.Handler
|
||||||
if h == nil {
|
if h == nil {
|
||||||
w.WriteHeader(StatusNotFound, "Not found")
|
w.WriteHeader(StatusNotFound, "Not found")
|
||||||
w.Flush()
|
w.Flush()
|
||||||
@ -405,24 +352,6 @@ func (srv *Server) respond(conn net.Conn) {
|
|||||||
w.Flush()
|
w.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
wildcard := strings.SplitN(r.URL.Hostname(), ".", 2)
|
|
||||||
if len(wildcard) == 2 {
|
|
||||||
if h, ok := srv.handlers[handlerKey{r.URL.Scheme, "*." + wildcard[1]}]; ok {
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if h, ok := srv.handlers[handlerKey{r.URL.Scheme, "*"}]; ok {
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (srv *Server) logf(format string, args ...interface{}) {
|
func (srv *Server) logf(format string, args ...interface{}) {
|
||||||
if srv.ErrorLog != nil {
|
if srv.ErrorLog != nil {
|
||||||
srv.ErrorLog.Printf(format, args...)
|
srv.ErrorLog.Printf(format, args...)
|
||||||
|
Loading…
Reference in New Issue
Block a user