mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			114 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package caddytls
 | 
						|
 | 
						|
import "net/url"
 | 
						|
 | 
						|
// StorageConstructor is a function type that is used in the Config to
 | 
						|
// instantiate a new Storage instance. This function can return a nil
 | 
						|
// Storage even without an error.
 | 
						|
type StorageConstructor func(caURL *url.URL) (Storage, error)
 | 
						|
 | 
						|
// SiteData contains persisted items pertaining to an individual site.
 | 
						|
type SiteData struct {
 | 
						|
	// Cert is the public cert byte array.
 | 
						|
	Cert []byte
 | 
						|
	// Key is the private key byte array.
 | 
						|
	Key []byte
 | 
						|
	// Meta is metadata about the site used by Caddy.
 | 
						|
	Meta []byte
 | 
						|
}
 | 
						|
 | 
						|
// UserData contains persisted items pertaining to a user.
 | 
						|
type UserData struct {
 | 
						|
	// Reg is the user registration byte array.
 | 
						|
	Reg []byte
 | 
						|
	// Key is the user key byte array.
 | 
						|
	Key []byte
 | 
						|
}
 | 
						|
 | 
						|
// Storage is an interface abstracting all storage used by Caddy's TLS
 | 
						|
// subsystem. Implementations of this interface store both site and
 | 
						|
// user data.
 | 
						|
type Storage interface {
 | 
						|
	// SiteExists returns true if this site exists in storage.
 | 
						|
	// Site data is considered present when StoreSite has been called
 | 
						|
	// successfully (without DeleteSite having been called, of course).
 | 
						|
	SiteExists(domain string) (bool, error)
 | 
						|
 | 
						|
	// TryLock is called before Caddy attempts to obtain or renew a
 | 
						|
	// certificate for a certain name and store it. From the perspective
 | 
						|
	// of this method and its companion Unlock, the actions of
 | 
						|
	// obtaining/renewing and then storing the certificate are atomic,
 | 
						|
	// and both should occur within a lock. This prevents multiple
 | 
						|
	// processes -- maybe distributed ones -- from stepping on each
 | 
						|
	// other's space in the same shared storage, and from spamming
 | 
						|
	// certificate providers with multiple, redundant requests.
 | 
						|
	//
 | 
						|
	// If a lock could be obtained, (nil, nil) is returned and you may
 | 
						|
	// continue normally. If not (meaning another process is already
 | 
						|
	// working on that name), a Waiter value will be returned upon
 | 
						|
	// which you can Wait() until it is finished, and then return
 | 
						|
	// when it unblocks. If waiting, do not unlock!
 | 
						|
	//
 | 
						|
	// To prevent deadlocks, all implementations (where this concern
 | 
						|
	// is relevant) should put a reasonable expiration on the lock in
 | 
						|
	// case Unlock is unable to be called due to some sort of storage
 | 
						|
	// system failure or crash.
 | 
						|
	TryLock(name string) (Waiter, error)
 | 
						|
 | 
						|
	// Unlock unlocks the mutex for name. Only callers of TryLock who
 | 
						|
	// successfully obtained the lock (no Waiter value was returned)
 | 
						|
	// should call this method, and it should be called only after
 | 
						|
	// the obtain/renew and store are finished, even if there was
 | 
						|
	// an error (or a timeout).
 | 
						|
	Unlock(name string) error
 | 
						|
 | 
						|
	// LoadSite obtains the site data from storage for the given domain and
 | 
						|
	// returns it. If data for the domain does not exist, an error value
 | 
						|
	// of type ErrNotExist is returned. For multi-server storage, care
 | 
						|
	// should be taken to make this load atomic to prevent race conditions
 | 
						|
	// that happen with multiple data loads.
 | 
						|
	LoadSite(domain string) (*SiteData, error)
 | 
						|
 | 
						|
	// StoreSite persists the given site data for the given domain in
 | 
						|
	// storage. For multi-server storage, care should be taken to make this
 | 
						|
	// call atomic to prevent half-written data on failure of an internal
 | 
						|
	// intermediate storage step. Implementers can trust that at runtime
 | 
						|
	// this function will only be invoked after LockRegister and before
 | 
						|
	// UnlockRegister of the same domain.
 | 
						|
	StoreSite(domain string, data *SiteData) error
 | 
						|
 | 
						|
	// DeleteSite deletes the site for the given domain from storage.
 | 
						|
	// Multi-server implementations should attempt to make this atomic. If
 | 
						|
	// the site does not exist, an error value of type ErrNotExist is returned.
 | 
						|
	DeleteSite(domain string) error
 | 
						|
 | 
						|
	// LoadUser obtains user data from storage for the given email and
 | 
						|
	// returns it. If data for the email does not exist, an error value
 | 
						|
	// of type ErrNotExist is returned. Multi-server implementations
 | 
						|
	// should take care to make this operation atomic for all loaded
 | 
						|
	// data items.
 | 
						|
	LoadUser(email string) (*UserData, error)
 | 
						|
 | 
						|
	// StoreUser persists the given user data for the given email in
 | 
						|
	// storage. Multi-server implementations should take care to make this
 | 
						|
	// operation atomic for all stored data items.
 | 
						|
	StoreUser(email string, data *UserData) error
 | 
						|
 | 
						|
	// MostRecentUserEmail provides the most recently used email parameter
 | 
						|
	// in StoreUser. The result is an empty string if there are no
 | 
						|
	// persisted users in storage.
 | 
						|
	MostRecentUserEmail() string
 | 
						|
}
 | 
						|
 | 
						|
// ErrNotExist is returned by Storage implementations when
 | 
						|
// a resource is not found. It is similar to os.ErrNotExist
 | 
						|
// except this is a type, not a variable.
 | 
						|
type ErrNotExist interface {
 | 
						|
	error
 | 
						|
}
 | 
						|
 | 
						|
// Waiter is a type that can block until a storage lock is released.
 | 
						|
type Waiter interface {
 | 
						|
	Wait()
 | 
						|
}
 |