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.
 | 
			
		||||
	Addr string
 | 
			
		||||
 | 
			
		||||
	// The Handler to invoke.
 | 
			
		||||
	Handler Handler
 | 
			
		||||
 | 
			
		||||
	// ReadTimeout is the maximum duration for reading the entire
 | 
			
		||||
	// request.
 | 
			
		||||
	//
 | 
			
		||||
@ -48,66 +51,12 @@ type Server struct {
 | 
			
		||||
	// If nil, logging is done via the log package's standard logger.
 | 
			
		||||
	ErrorLog *log.Logger
 | 
			
		||||
 | 
			
		||||
	// registered handlers
 | 
			
		||||
	handlers map[handlerKey]Handler
 | 
			
		||||
	hosts    map[string]bool
 | 
			
		||||
	hmu      sync.Mutex
 | 
			
		||||
 | 
			
		||||
	listeners map[*net.Listener]struct{}
 | 
			
		||||
	conns     map[*net.Conn]struct{}
 | 
			
		||||
	done      int32
 | 
			
		||||
	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 on the TCP network address srv.Addr and then calls
 | 
			
		||||
// 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
 | 
			
		||||
// is expired, it calls GetCertificate to retrieve a new certificate.
 | 
			
		||||
func (srv *Server) lookupCertificate(pattern, hostname string) (*tls.Certificate, error) {
 | 
			
		||||
	srv.hmu.Lock()
 | 
			
		||||
	_, ok := srv.hosts[pattern]
 | 
			
		||||
	srv.hmu.Unlock()
 | 
			
		||||
	_, ok := srv.Certificates.Lookup(pattern)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, errors.New("hostname not registered")
 | 
			
		||||
	}
 | 
			
		||||
@ -394,7 +341,7 @@ func (srv *Server) respond(conn net.Conn) {
 | 
			
		||||
	// Store remote address
 | 
			
		||||
	req.RemoteAddr = conn.RemoteAddr()
 | 
			
		||||
 | 
			
		||||
	h := srv.handler(req)
 | 
			
		||||
	h := srv.Handler
 | 
			
		||||
	if h == nil {
 | 
			
		||||
		w.WriteHeader(StatusNotFound, "Not found")
 | 
			
		||||
		w.Flush()
 | 
			
		||||
@ -405,24 +352,6 @@ func (srv *Server) respond(conn net.Conn) {
 | 
			
		||||
	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{}) {
 | 
			
		||||
	if srv.ErrorLog != nil {
 | 
			
		||||
		srv.ErrorLog.Printf(format, args...)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user