MCPcopy
hub / github.com/caddyserver/caddy / changeConfig

Function changeConfig

caddy.go:158–276  ·  view source on GitHub ↗

changeConfig changes the current config (rawCfg) according to the method, traversed via the given path, and uses the given input as the new value (if applicable; i.e. "DELETE" doesn't have an input). If the resulting config is the same as the previous, no reload will occur unless forceReload is true

(method, path string, input []byte, ifMatchHeader string, forceReload bool)

Source from the content-addressed store, hash-verified

156// the config at that path. If the hash in the ifMatchHeader doesn't match
157// the hash of the config, then an APIError with status 412 will be returned.
158func changeConfig(method, path string, input []byte, ifMatchHeader string, forceReload bool) error {
159 switch method {
160 case http.MethodGet,
161 http.MethodHead,
162 http.MethodOptions,
163 http.MethodConnect,
164 http.MethodTrace:
165 return fmt.Errorf("method not allowed")
166 }
167
168 rawCfgMu.Lock()
169 defer rawCfgMu.Unlock()
170
171 if ifMatchHeader != "" {
172 // expect the first and last character to be quotes
173 if len(ifMatchHeader) < 2 || ifMatchHeader[0] != '"' || ifMatchHeader[len(ifMatchHeader)-1] != '"' {
174 return APIError{
175 HTTPStatus: http.StatusBadRequest,
176 Err: fmt.Errorf("malformed If-Match header; expect quoted string"),
177 }
178 }
179
180 // read out the parts
181 parts := strings.Fields(ifMatchHeader[1 : len(ifMatchHeader)-1])
182 if len(parts) != 2 {
183 return APIError{
184 HTTPStatus: http.StatusBadRequest,
185 Err: fmt.Errorf("malformed If-Match header; expect format \"<path> <hash>\""),
186 }
187 }
188
189 // get the current hash of the config
190 // at the given path
191 hash := etagHasher()
192 err := unsyncedConfigAccess(http.MethodGet, parts[0], nil, hash)
193 if err != nil {
194 return err
195 }
196
197 if hex.EncodeToString(hash.Sum(nil)) != parts[1] {
198 return APIError{
199 HTTPStatus: http.StatusPreconditionFailed,
200 Err: fmt.Errorf("If-Match header did not match current config hash"),
201 }
202 }
203 }
204
205 err := unsyncedConfigAccess(method, path, input, nil)
206 if err != nil {
207 return err
208 }
209
210 // the mutation is complete, so encode the entire config as JSON
211 newCfg, err := json.Marshal(rawCfg[rawConfigKey])
212 if err != nil {
213 return APIError{
214 HTTPStatus: http.StatusBadRequest,
215 Err: fmt.Errorf("encoding new config: %v", err),

Callers 4

handleConfigFunction · 0.85
TestETagsFunction · 0.85
LoadFunction · 0.85
finishSettingUpFunction · 0.85

Calls 6

etagHasherFunction · 0.85
unsyncedConfigAccessFunction · 0.85
LogFunction · 0.85
indexConfigObjectsFunction · 0.85
unsyncedDecodeAndRunFunction · 0.85
EqualMethod · 0.45

Tested by 1

TestETagsFunction · 0.68