mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 02:27:19 -04: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
 | |
| }
 |