Update documentation
This commit is contained in:
		
							parent
							
								
									34ae2a9066
								
							
						
					
					
						commit
						b5fbd197a1
					
				
							
								
								
									
										29
									
								
								cert.go
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								cert.go
									
									
									
									
									
								
							| @ -8,7 +8,6 @@ import ( | |||||||
| 	"crypto/x509" | 	"crypto/x509" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"net" | 	"net" | ||||||
| 	"path" |  | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| @ -36,9 +35,9 @@ func (c *CertificateStore) Add(scope string, cert tls.Certificate) { | |||||||
| 	c.store[scope] = cert | 	c.store[scope] = cert | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Lookup returns the certificate for the given hostname. | // Lookup returns the certificate for the given scope. | ||||||
| func (c *CertificateStore) Lookup(hostname string) (*tls.Certificate, error) { | func (c *CertificateStore) Lookup(scope string) (*tls.Certificate, error) { | ||||||
| 	cert, ok := c.store[hostname] | 	cert, ok := c.store[scope] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, ErrCertificateUnknown | 		return nil, ErrCertificateUnknown | ||||||
| 	} | 	} | ||||||
| @ -49,25 +48,9 @@ func (c *CertificateStore) Lookup(hostname string) (*tls.Certificate, error) { | |||||||
| 	return &cert, nil | 	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. | // Load loads certificates from the given path. | ||||||
| // The path should lead to a directory containing certificates and private keys | // 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 | // For example, the hostname "localhost" would have the corresponding files | ||||||
| // localhost.crt (certificate) and localhost.key (private key). | // localhost.crt (certificate) and localhost.key (private key). | ||||||
| func (c *CertificateStore) Load(path string) error { | func (c *CertificateStore) Load(path string) error { | ||||||
| @ -81,8 +64,8 @@ func (c *CertificateStore) Load(path string) error { | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		hostname := strings.TrimSuffix(filepath.Base(crtPath), ".crt") | 		scope := strings.TrimSuffix(filepath.Base(crtPath), ".crt") | ||||||
| 		c.Add(hostname, cert) | 		c.Add(scope, cert) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								client.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								client.go
									
									
									
									
									
								
							| @ -6,6 +6,7 @@ import ( | |||||||
| 	"crypto/x509" | 	"crypto/x509" | ||||||
| 	"net" | 	"net" | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  | 	"path" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -153,12 +154,23 @@ func (c *Client) getClientCertificate(req *Request) (*tls.Certificate, error) { | |||||||
| 	if req.Certificate != nil { | 	if req.Certificate != nil { | ||||||
| 		return 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 { | 	// Search recursively for the certificate | ||||||
| 		// Remember the certificate used | 	scope := req.URL.Hostname() + strings.TrimSuffix(req.URL.Path, "/") | ||||||
| 		req.Certificate = cert | 	for { | ||||||
| 		return cert, nil | 		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 | 	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) | 		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 { | 	client.CreateCertificate = func(hostname, path string) *tls.Certificate { | ||||||
| 		// If the certificate is in the store, return it | 		return gemini.CreateCertificate(gemini.CertificateOptions{ | ||||||
| 		if cert, err := store.Lookup(hostname); err == nil { | 			Duration: time.Hour, | ||||||
| 			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 |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| Server is a Gemini server. | Server is a Gemini server. | ||||||
| @ -65,7 +55,7 @@ Server is a Gemini server. | |||||||
| 
 | 
 | ||||||
| Servers must be configured with certificates: | 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 { | 	if err != nil { | ||||||
| 		// handle error | 		// handle error | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -36,9 +36,16 @@ type responderKey struct { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Register registers a responder for the given pattern. | // 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. | // If no scheme is specified, a default scheme of gemini:// is assumed. | ||||||
|  | // | ||||||
| // Wildcard patterns are supported (e.g. *.example.com). | // 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) { | func (s *Server) Register(pattern string, responder Responder) { | ||||||
| 	if pattern == "" { | 	if pattern == "" { | ||||||
| 		panic("gemini: invalid pattern") | 		panic("gemini: invalid pattern") | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user