@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 01:00 UTC

master
go 112 lines 2.76 KB
Raw
1 package caddyfs
2
3 import (
4 "encoding/json"
5 "fmt"
6 "io/fs"
7
8 "go.uber.org/zap"
9
10 "github.com/caddyserver/caddy/v2"
11 "github.com/caddyserver/caddy/v2/caddyconfig"
12 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
13 "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
14 )
15
16 func init() {
17 caddy.RegisterModule(Filesystems{})
18 httpcaddyfile.RegisterGlobalOption("filesystem", parseFilesystems)
19 }
20
21 type moduleEntry struct {
22 Key string `json:"name,omitempty"`
23 FileSystemRaw json.RawMessage `json:"file_system,omitempty" caddy:"namespace=caddy.fs inline_key=backend"`
24 fileSystem fs.FS
25 }
26
27 // Filesystems loads caddy.fs modules into the global filesystem map
28 type Filesystems struct {
29 Filesystems []*moduleEntry `json:"filesystems"`
30
31 defers []func()
32 }
33
34 func parseFilesystems(d *caddyfile.Dispenser, existingVal any) (any, error) {
35 p := &Filesystems{}
36 current, ok := existingVal.(*Filesystems)
37 if ok {
38 p = current
39 }
40 x := &moduleEntry{}
41 err := x.UnmarshalCaddyfile(d)
42 if err != nil {
43 return nil, err
44 }
45 p.Filesystems = append(p.Filesystems, x)
46 return p, nil
47 }
48
49 // CaddyModule returns the Caddy module information.
50 func (Filesystems) CaddyModule() caddy.ModuleInfo {
51 return caddy.ModuleInfo{
52 ID: "caddy.filesystems",
53 New: func() caddy.Module { return new(Filesystems) },
54 }
55 }
56
57 func (xs *Filesystems) Start() error { return nil }
58 func (xs *Filesystems) Stop() error { return nil }
59
60 func (xs *Filesystems) Provision(ctx caddy.Context) error {
61 // load the filesystem module
62 for _, f := range xs.Filesystems {
63 if len(f.FileSystemRaw) > 0 {
64 mod, err := ctx.LoadModule(f, "FileSystemRaw")
65 if err != nil {
66 return fmt.Errorf("loading file system module: %v", err)
67 }
68 f.fileSystem = mod.(fs.FS)
69 }
70 // register that module
71 ctx.Logger().Debug("registering fs", zap.String("fs", f.Key))
72 ctx.FileSystems().Register(f.Key, f.fileSystem)
73 // remember to unregister the module when we are done
74 xs.defers = append(xs.defers, func() {
75 ctx.Logger().Debug("unregistering fs", zap.String("fs", f.Key))
76 ctx.FileSystems().Unregister(f.Key)
77 })
78 }
79 return nil
80 }
81
82 func (f *Filesystems) Cleanup() error {
83 for _, v := range f.defers {
84 v()
85 }
86 return nil
87 }
88
89 func (f *moduleEntry) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
90 for d.Next() {
91 // key required for now
92 if !d.Args(&f.Key) {
93 return d.ArgErr()
94 }
95 // get the module json
96 if !d.NextArg() {
97 return d.ArgErr()
98 }
99 name := d.Val()
100 modID := "caddy.fs." + name
101 unm, err := caddyfile.UnmarshalModule(d, modID)
102 if err != nil {
103 return err
104 }
105 fsys, ok := unm.(fs.FS)
106 if !ok {
107 return d.Errf("module %s (%T) is not a supported file system implementation (requires fs.FS)", modID, unm)
108 }
109 f.FileSystemRaw = caddyconfig.JSONModuleObject(fsys, "backend", name, nil)
110 }
111 return nil
112 }