@@ -20,6 +20,7 @@ import (
20
20
21
21
"github.com/caddyserver/caddy/v2"
22
22
"github.com/caddyserver/caddy/v2/caddyconfig"
23
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
23
24
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
24
25
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
25
26
"github.com/caddyserver/caddy/v2/modules/caddyhttp/encode"
@@ -31,8 +32,23 @@ func init() {
31
32
httpcaddyfile .RegisterDirective ("try_files" , parseTryFiles )
32
33
}
33
34
34
- // parseCaddyfile parses the file_server directive. It enables the static file
35
- // server and configures it with this syntax:
35
+ // parseCaddyfile parses the file_server directive.
36
+ // See UnmarshalCaddyfile for the syntax.
37
+ func parseCaddyfile (h httpcaddyfile.Helper ) (caddyhttp.MiddlewareHandler , error ) {
38
+ fsrv := new (FileServer )
39
+ err := fsrv .UnmarshalCaddyfile (h .Dispenser )
40
+ if err != nil {
41
+ return fsrv , err
42
+ }
43
+ err = fsrv .FinalizeUnmarshalCaddyfile (h )
44
+ if err != nil {
45
+ return nil , err
46
+ }
47
+ return fsrv , err
48
+ }
49
+
50
+ // UnmarshalCaddyfile parses the file_server directive. It enables
51
+ // the static file server and configures it with this syntax:
36
52
//
37
53
// file_server [<matcher>] [browse] {
38
54
// fs <filesystem>
@@ -44,103 +60,115 @@ func init() {
44
60
// status <status>
45
61
// disable_canonical_uris
46
62
// }
47
- func parseCaddyfile (h httpcaddyfile.Helper ) (caddyhttp.MiddlewareHandler , error ) {
48
- var fsrv FileServer
63
+ //
64
+ // The FinalizeUnmarshalCaddyfile method should be called after this
65
+ // to finalize setup of hidden Caddyfiles.
66
+ func (fsrv * FileServer ) UnmarshalCaddyfile (d * caddyfile.Dispenser ) error {
67
+ d .Next () // consume directive name
49
68
50
- for h .Next () {
51
- args := h .RemainingArgs ()
52
- switch len (args ) {
53
- case 0 :
54
- case 1 :
55
- if args [0 ] != "browse" {
56
- return nil , h .ArgErr ()
57
- }
58
- fsrv .Browse = new (Browse )
59
- default :
60
- return nil , h .ArgErr ()
69
+ args := d .RemainingArgs ()
70
+ switch len (args ) {
71
+ case 0 :
72
+ case 1 :
73
+ if args [0 ] != "browse" {
74
+ return d .ArgErr ()
61
75
}
76
+ fsrv .Browse = new (Browse )
77
+ default :
78
+ return d .ArgErr ()
79
+ }
62
80
63
- for h .NextBlock (0 ) {
64
- switch h .Val () {
65
- case "fs" :
66
- if ! h .NextArg () {
67
- return nil , h .ArgErr ()
68
- }
69
- if fsrv .FileSystem != "" {
70
- return nil , h .Err ("file system already specified" )
71
- }
72
- fsrv .FileSystem = h .Val ()
73
- case "hide" :
74
- fsrv .Hide = h .RemainingArgs ()
75
- if len (fsrv .Hide ) == 0 {
76
- return nil , h .ArgErr ()
77
- }
81
+ for d .NextBlock (0 ) {
82
+ switch d .Val () {
83
+ case "fs" :
84
+ if ! d .NextArg () {
85
+ return d .ArgErr ()
86
+ }
87
+ if fsrv .FileSystem != "" {
88
+ return d .Err ("file system already specified" )
89
+ }
90
+ fsrv .FileSystem = d .Val ()
78
91
79
- case "index " :
80
- fsrv .IndexNames = h .RemainingArgs ()
81
- if len (fsrv .IndexNames ) == 0 {
82
- return nil , h .ArgErr ()
83
- }
92
+ case "hide " :
93
+ fsrv .Hide = d .RemainingArgs ()
94
+ if len (fsrv .Hide ) == 0 {
95
+ return d .ArgErr ()
96
+ }
84
97
85
- case "root" :
86
- if ! h .Args (& fsrv .Root ) {
87
- return nil , h .ArgErr ()
88
- }
98
+ case "index" :
99
+ fsrv .IndexNames = d .RemainingArgs ()
100
+ if len (fsrv .IndexNames ) == 0 {
101
+ return d .ArgErr ()
102
+ }
89
103
90
- case "browse" :
91
- if fsrv .Browse != nil {
92
- return nil , h .Err ("browsing is already configured" )
93
- }
94
- fsrv .Browse = new (Browse )
95
- h .Args (& fsrv .Browse .TemplateFile )
104
+ case "root" :
105
+ if ! d .Args (& fsrv .Root ) {
106
+ return d .ArgErr ()
107
+ }
96
108
97
- case "precompressed" :
98
- var order []string
99
- for h .NextArg () {
100
- modID := "http.precompressed." + h .Val ()
101
- mod , err := caddy .GetModule (modID )
102
- if err != nil {
103
- return nil , h .Errf ("getting module named '%s': %v" , modID , err )
104
- }
105
- inst := mod .New ()
106
- precompress , ok := inst .(encode.Precompressed )
107
- if ! ok {
108
- return nil , h .Errf ("module %s is not a precompressor; is %T" , modID , inst )
109
- }
110
- if fsrv .PrecompressedRaw == nil {
111
- fsrv .PrecompressedRaw = make (caddy.ModuleMap )
112
- }
113
- fsrv .PrecompressedRaw [h .Val ()] = caddyconfig .JSON (precompress , nil )
114
- order = append (order , h .Val ())
115
- }
116
- fsrv .PrecompressedOrder = order
109
+ case "browse" :
110
+ if fsrv .Browse != nil {
111
+ return d .Err ("browsing is already configured" )
112
+ }
113
+ fsrv .Browse = new (Browse )
114
+ d .Args (& fsrv .Browse .TemplateFile )
117
115
118
- case "status" :
119
- if ! h .NextArg () {
120
- return nil , h .ArgErr ()
116
+ case "precompressed" :
117
+ var order []string
118
+ for d .NextArg () {
119
+ modID := "http.precompressed." + d .Val ()
120
+ mod , err := caddy .GetModule (modID )
121
+ if err != nil {
122
+ return d .Errf ("getting module named '%s': %v" , modID , err )
121
123
}
122
- fsrv .StatusCode = caddyhttp .WeakString (h .Val ())
123
-
124
- case "disable_canonical_uris" :
125
- if h .NextArg () {
126
- return nil , h .ArgErr ()
124
+ inst := mod .New ()
125
+ precompress , ok := inst .(encode.Precompressed )
126
+ if ! ok {
127
+ return d .Errf ("module %s is not a precompressor; is %T" , modID , inst )
127
128
}
128
- falseBool := false
129
- fsrv .CanonicalURIs = & falseBool
130
-
131
- case "pass_thru" :
132
- if h .NextArg () {
133
- return nil , h .ArgErr ()
129
+ if fsrv .PrecompressedRaw == nil {
130
+ fsrv .PrecompressedRaw = make (caddy.ModuleMap )
134
131
}
135
- fsrv .PassThru = true
132
+ fsrv .PrecompressedRaw [d .Val ()] = caddyconfig .JSON (precompress , nil )
133
+ order = append (order , d .Val ())
134
+ }
135
+ fsrv .PrecompressedOrder = order
136
136
137
- default :
138
- return nil , h .Errf ("unknown subdirective '%s'" , h .Val ())
137
+ case "status" :
138
+ if ! d .NextArg () {
139
+ return d .ArgErr ()
139
140
}
141
+ fsrv .StatusCode = caddyhttp .WeakString (d .Val ())
142
+
143
+ case "disable_canonical_uris" :
144
+ if d .NextArg () {
145
+ return d .ArgErr ()
146
+ }
147
+ falseBool := false
148
+ fsrv .CanonicalURIs = & falseBool
149
+
150
+ case "pass_thru" :
151
+ if d .NextArg () {
152
+ return d .ArgErr ()
153
+ }
154
+ fsrv .PassThru = true
155
+
156
+ default :
157
+ return d .Errf ("unknown subdirective '%s'" , d .Val ())
140
158
}
141
159
}
142
160
143
- // hide the Caddyfile (and any imported Caddyfiles)
161
+ return nil
162
+ }
163
+
164
+ // FinalizeUnmarshalCaddyfile finalizes the Caddyfile parsing which
165
+ // requires having an httpcaddyfile.Helper to function, to setup hidden Caddyfiles.
166
+ func (fsrv * FileServer ) FinalizeUnmarshalCaddyfile (h httpcaddyfile.Helper ) error {
167
+ // Hide the Caddyfile (and any imported Caddyfiles).
168
+ // This needs to be done in here instead of UnmarshalCaddyfile
169
+ // because UnmarshalCaddyfile only has access to the dispenser
170
+ // and not the helper, and only the helper has access to the
171
+ // Caddyfiles function.
144
172
if configFiles := h .Caddyfiles (); len (configFiles ) > 0 {
145
173
for _ , file := range configFiles {
146
174
file = filepath .Clean (file )
@@ -155,8 +183,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
155
183
}
156
184
}
157
185
}
158
-
159
- return & fsrv , nil
186
+ return nil
160
187
}
161
188
162
189
// parseTryFiles parses the try_files directive. It combines a file matcher
@@ -257,3 +284,5 @@ func parseTryFiles(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
257
284
258
285
return result , nil
259
286
}
287
+
288
+ var _ caddyfile.Unmarshaler = (* FileServer )(nil )
0 commit comments