mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package caddyfs
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"io/fs"
 | 
						|
 | 
						|
	"go.uber.org/zap"
 | 
						|
 | 
						|
	"github.com/caddyserver/caddy/v2"
 | 
						|
	"github.com/caddyserver/caddy/v2/caddyconfig"
 | 
						|
	"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
 | 
						|
	"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
 | 
						|
)
 | 
						|
 | 
						|
func init() {
 | 
						|
	caddy.RegisterModule(Filesystems{})
 | 
						|
	httpcaddyfile.RegisterGlobalOption("filesystem", parseFilesystems)
 | 
						|
}
 | 
						|
 | 
						|
type moduleEntry struct {
 | 
						|
	Key           string          `json:"name,omitempty"`
 | 
						|
	FileSystemRaw json.RawMessage `json:"file_system,omitempty" caddy:"namespace=caddy.fs inline_key=backend"`
 | 
						|
	fileSystem    fs.FS
 | 
						|
}
 | 
						|
 | 
						|
// Filesystems loads caddy.fs modules into the global filesystem map
 | 
						|
type Filesystems struct {
 | 
						|
	Filesystems []*moduleEntry `json:"filesystems"`
 | 
						|
 | 
						|
	defers []func()
 | 
						|
}
 | 
						|
 | 
						|
func parseFilesystems(d *caddyfile.Dispenser, existingVal any) (any, error) {
 | 
						|
	p := &Filesystems{}
 | 
						|
	current, ok := existingVal.(*Filesystems)
 | 
						|
	if ok {
 | 
						|
		p = current
 | 
						|
	}
 | 
						|
	x := &moduleEntry{}
 | 
						|
	err := x.UnmarshalCaddyfile(d)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	p.Filesystems = append(p.Filesystems, x)
 | 
						|
	return p, nil
 | 
						|
}
 | 
						|
 | 
						|
// CaddyModule returns the Caddy module information.
 | 
						|
func (Filesystems) CaddyModule() caddy.ModuleInfo {
 | 
						|
	return caddy.ModuleInfo{
 | 
						|
		ID:  "caddy.filesystems",
 | 
						|
		New: func() caddy.Module { return new(Filesystems) },
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (xs *Filesystems) Start() error { return nil }
 | 
						|
func (xs *Filesystems) Stop() error  { return nil }
 | 
						|
 | 
						|
func (xs *Filesystems) Provision(ctx caddy.Context) error {
 | 
						|
	// load the filesystem module
 | 
						|
	for _, f := range xs.Filesystems {
 | 
						|
		if len(f.FileSystemRaw) > 0 {
 | 
						|
			mod, err := ctx.LoadModule(f, "FileSystemRaw")
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("loading file system module: %v", err)
 | 
						|
			}
 | 
						|
			f.fileSystem = mod.(fs.FS)
 | 
						|
		}
 | 
						|
		// register that module
 | 
						|
		ctx.Logger().Debug("registering fs", zap.String("fs", f.Key))
 | 
						|
		ctx.Filesystems().Register(f.Key, f.fileSystem)
 | 
						|
		// remember to unregister the module when we are done
 | 
						|
		xs.defers = append(xs.defers, func() {
 | 
						|
			ctx.Logger().Debug("registering fs", zap.String("fs", f.Key))
 | 
						|
			ctx.Filesystems().Unregister(f.Key)
 | 
						|
		})
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (f *Filesystems) Cleanup() error {
 | 
						|
	for _, v := range f.defers {
 | 
						|
		v()
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (f *moduleEntry) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
 | 
						|
	for d.Next() {
 | 
						|
		// key required for now
 | 
						|
		if !d.Args(&f.Key) {
 | 
						|
			return d.ArgErr()
 | 
						|
		}
 | 
						|
		// get the module json
 | 
						|
		if !d.NextArg() {
 | 
						|
			return d.ArgErr()
 | 
						|
		}
 | 
						|
		name := d.Val()
 | 
						|
		modID := "caddy.fs." + name
 | 
						|
		unm, err := caddyfile.UnmarshalModule(d, modID)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		fsys, ok := unm.(fs.FS)
 | 
						|
		if !ok {
 | 
						|
			return d.Errf("module %s (%T) is not a supported file system implementation (requires fs.FS)", modID, unm)
 | 
						|
		}
 | 
						|
		f.FileSystemRaw = caddyconfig.JSONModuleObject(fsys, "backend", name, nil)
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 |