From 610c6fc53344cad3c4b730466e7da7d6eb43a7eb Mon Sep 17 00:00:00 2001 From: Adnan Maolood Date: Tue, 3 Nov 2020 16:11:31 -0500 Subject: [PATCH] Add ErrorLog field to Server --- cert.go | 7 +++---- examples/auth.go | 1 + server.go | 19 +++++++++++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/cert.go b/cert.go index 8079a8a..702584c 100644 --- a/cert.go +++ b/cert.go @@ -8,7 +8,6 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" - "log" "math/big" "net" "os" @@ -27,7 +26,7 @@ type CertificateStore struct { // Add adds a certificate for the given scope to the store. // It tries to parse the certificate if it is not already parsed. -func (c *CertificateStore) Add(scope string, cert tls.Certificate) { +func (c *CertificateStore) Add(scope string, cert tls.Certificate) error { if c.store == nil { c.store = map[string]tls.Certificate{} } @@ -40,14 +39,14 @@ func (c *CertificateStore) Add(scope string, cert tls.Certificate) { } if c.dir { // Write certificates - log.Printf("gemini: Writing certificate for %s to %s", scope, c.path) certPath := filepath.Join(c.path, scope+".crt") keyPath := filepath.Join(c.path, scope+".key") if err := WriteCertificate(cert, certPath, keyPath); err != nil { - log.Printf("gemini: Failed to write certificate for %s: %s", scope, err) + return err } } c.store[scope] = cert + return nil } // Lookup returns the certificate for the given scope. diff --git a/examples/auth.go b/examples/auth.go index 41fb70c..13597bb 100644 --- a/examples/auth.go +++ b/examples/auth.go @@ -119,6 +119,7 @@ func logout(w *gemini.ResponseWriter, r *gemini.Request) { fingerprint := gemini.Fingerprint(r.Certificate.Leaf) delete(sessions, fingerprint) fmt.Fprintln(w, "Successfully logged out.") + fmt.Fprintln(w, "=> / Index") } func profile(w *gemini.ResponseWriter, r *gemini.Request) { diff --git a/server.go b/server.go index 45555fc..8db210e 100644 --- a/server.go +++ b/server.go @@ -31,6 +31,11 @@ type Server struct { // if the current one is expired or missing. CreateCertificate func(hostname string) (tls.Certificate, error) + // ErrorLog specifies an optional logger for errors accepting connections + // and file system errors. + // If nil, logging is done via the log package's standard logger. + ErrorLog *log.Logger + // registered responders responders map[responderKey]Responder hosts map[string]bool @@ -117,7 +122,7 @@ func (s *Server) Serve(l net.Listener) error { if max := 1 * time.Second; tempDelay > max { tempDelay = max } - log.Printf("gemini: Accept error: %v; retrying in %v", err, tempDelay) + s.logf("gemini: Accept error: %v; retrying in %v", err, tempDelay) time.Sleep(tempDelay) continue } @@ -154,7 +159,9 @@ func (s *Server) getCertificateFor(hostname string) (*tls.Certificate, error) { if s.CreateCertificate != nil { cert, err := s.CreateCertificate(hostname) if err == nil { - s.Certificates.Add(hostname, cert) + if err := s.Certificates.Add(hostname, cert); err != nil { + s.logf("gemini: Failed to add new certificate for %s: %s", hostname, err) + } } return &cert, err } @@ -241,6 +248,14 @@ func (s *Server) responder(r *Request) Responder { return nil } +func (s *Server) logf(format string, args ...interface{}) { + if s.ErrorLog != nil { + s.ErrorLog.Printf(format, args...) + } else { + log.Printf(format, args...) + } +} + // ResponseWriter is used by a Gemini handler to construct a Gemini response. type ResponseWriter struct { b *bufio.Writer