Update documentation
This commit is contained in:
		
							parent
							
								
									34ae2a9066
								
							
						
					
					
						commit
						b5fbd197a1
					
				
							
								
								
									
										29
									
								
								cert.go
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								cert.go
									
									
									
									
									
								
							@ -8,7 +8,6 @@ import (
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"math/big"
 | 
			
		||||
	"net"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
@ -36,9 +35,9 @@ func (c *CertificateStore) Add(scope string, cert tls.Certificate) {
 | 
			
		||||
	c.store[scope] = cert
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Lookup returns the certificate for the given hostname.
 | 
			
		||||
func (c *CertificateStore) Lookup(hostname string) (*tls.Certificate, error) {
 | 
			
		||||
	cert, ok := c.store[hostname]
 | 
			
		||||
// Lookup returns the certificate for the given scope.
 | 
			
		||||
func (c *CertificateStore) Lookup(scope string) (*tls.Certificate, error) {
 | 
			
		||||
	cert, ok := c.store[scope]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, ErrCertificateUnknown
 | 
			
		||||
	}
 | 
			
		||||
@ -49,25 +48,9 @@ func (c *CertificateStore) Lookup(hostname string) (*tls.Certificate, error) {
 | 
			
		||||
	return &cert, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// lookup returns the certificate for the given hostname + path.
 | 
			
		||||
func (c *CertificateStore) lookup(scope string) (*tls.Certificate, error) {
 | 
			
		||||
	for {
 | 
			
		||||
		cert, err := c.Lookup(scope)
 | 
			
		||||
		switch err {
 | 
			
		||||
		case ErrCertificateExpired, nil:
 | 
			
		||||
			return cert, err
 | 
			
		||||
		}
 | 
			
		||||
		scope = path.Dir(scope)
 | 
			
		||||
		if scope == "." {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, ErrCertificateUnknown
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Load loads certificates from the given path.
 | 
			
		||||
// The path should lead to a directory containing certificates and private keys
 | 
			
		||||
// in the form hostname.crt and hostname.key.
 | 
			
		||||
// in the form scope.crt and scope.key.
 | 
			
		||||
// For example, the hostname "localhost" would have the corresponding files
 | 
			
		||||
// localhost.crt (certificate) and localhost.key (private key).
 | 
			
		||||
func (c *CertificateStore) Load(path string) error {
 | 
			
		||||
@ -81,8 +64,8 @@ func (c *CertificateStore) Load(path string) error {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		hostname := strings.TrimSuffix(filepath.Base(crtPath), ".crt")
 | 
			
		||||
		c.Add(hostname, cert)
 | 
			
		||||
		scope := strings.TrimSuffix(filepath.Base(crtPath), ".crt")
 | 
			
		||||
		c.Add(scope, cert)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								client.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								client.go
									
									
									
									
									
								
							@ -6,6 +6,7 @@ import (
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -153,12 +154,23 @@ func (c *Client) getClientCertificate(req *Request) (*tls.Certificate, error) {
 | 
			
		||||
	if req.Certificate != nil {
 | 
			
		||||
		return req.Certificate, nil
 | 
			
		||||
	}
 | 
			
		||||
	hostname, path := req.URL.Hostname(), strings.TrimSuffix(req.URL.Path, "/")
 | 
			
		||||
	if cert, err := c.Certificates.lookup(hostname + path); err == nil {
 | 
			
		||||
		// Remember the certificate used
 | 
			
		||||
		req.Certificate = cert
 | 
			
		||||
		return cert, nil
 | 
			
		||||
 | 
			
		||||
	// Search recursively for the certificate
 | 
			
		||||
	scope := req.URL.Hostname() + strings.TrimSuffix(req.URL.Path, "/")
 | 
			
		||||
	for {
 | 
			
		||||
		cert, err := c.Certificates.Lookup(scope)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			return cert, err
 | 
			
		||||
		}
 | 
			
		||||
		if err == ErrCertificateExpired {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		scope = path.Dir(scope)
 | 
			
		||||
		if scope == "." {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &tls.Certificate{}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								doc.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								doc.go
									
									
									
									
									
								
							@ -41,22 +41,12 @@ Clients can control when to trust certificates with TrustCertificate:
 | 
			
		||||
		return knownHosts.Lookup(hostname, cert)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
Clients can control what to do when a server requests a certificate:
 | 
			
		||||
Clients can create client certificates upon the request of a server:
 | 
			
		||||
 | 
			
		||||
	client.GetCertificate = func(hostname string, store *gemini.CertificateStore) *tls.Certificate {
 | 
			
		||||
		// If the certificate is in the store, return it
 | 
			
		||||
		if cert, err := store.Lookup(hostname); err == nil {
 | 
			
		||||
			return &cert
 | 
			
		||||
		}
 | 
			
		||||
		// Otherwise, generate a certificate
 | 
			
		||||
		duration := time.Hour
 | 
			
		||||
		cert, err := gemini.NewCertificate(hostname, duration)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		// Store and return the certificate
 | 
			
		||||
		store.Add(hostname, cert)
 | 
			
		||||
		return &cert
 | 
			
		||||
	client.CreateCertificate = func(hostname, path string) *tls.Certificate {
 | 
			
		||||
		return gemini.CreateCertificate(gemini.CertificateOptions{
 | 
			
		||||
			Duration: time.Hour,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
Server is a Gemini server.
 | 
			
		||||
@ -65,7 +55,7 @@ Server is a Gemini server.
 | 
			
		||||
 | 
			
		||||
Servers must be configured with certificates:
 | 
			
		||||
 | 
			
		||||
	err := server.CertificateStore.Load("/var/lib/gemini/certs")
 | 
			
		||||
	err := server.Certificates.Load("/var/lib/gemini/certs")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// handle error
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -36,9 +36,16 @@ type responderKey struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register registers a responder for the given pattern.
 | 
			
		||||
// Patterns must be in the form of scheme://hostname (e.g. gemini://example.com).
 | 
			
		||||
//
 | 
			
		||||
// Patterns must be in the form of hostname or scheme://hostname
 | 
			
		||||
// (e.g. gemini://example.com).
 | 
			
		||||
// If no scheme is specified, a default scheme of gemini:// is assumed.
 | 
			
		||||
//
 | 
			
		||||
// Wildcard patterns are supported (e.g. *.example.com).
 | 
			
		||||
// To register a certificate for a wildcard domain, call Certificates.Add:
 | 
			
		||||
//
 | 
			
		||||
//     var s gemini.Server
 | 
			
		||||
//     s.Certificates.Add("*.example.com", cert)
 | 
			
		||||
func (s *Server) Register(pattern string, responder Responder) {
 | 
			
		||||
	if pattern == "" {
 | 
			
		||||
		panic("gemini: invalid pattern")
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user