From 03306e646e3ee421f582ef69a2158724bcf2614b Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Wed, 9 Oct 2019 19:10:00 -0600 Subject: admin: /config and /id endpoints This integrates a feature that was previously reserved for enterprise users, according to https://github.com/caddyserver/caddy/issues/2786. The /config and /id endpoints make granular config changes possible as well as the exporting of the current configuration. The /load endpoint has been modified to wrap the /config handler so that the currently-running config can always be available for export. The difference is that /load allows configs of varying formats and converts them using config adapters. The adapted config is then processed with /config as JSON. The /config and /id endpoints accept only JSON. --- admin.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'admin.go') diff --git a/admin.go b/admin.go index 860ed05..db8b700 100644 --- a/admin.go +++ b/admin.go @@ -87,7 +87,7 @@ func StartAdmin(initialConfigJSON []byte) error { return fmt.Errorf("parsing admin listener address: %v", err) } if len(listenAddrs) != 1 { - return fmt.Errorf("admin endpoint must have exactly one listener; cannot listen on %v", listenAddrs) + return fmt.Errorf("admin endpoint must have exactly one address; cannot listen on %v", listenAddrs) } ln, err := net.Listen(netw, listenAddrs[0]) if err != nil { @@ -120,7 +120,7 @@ func StartAdmin(initialConfigJSON []byte) error { ReadTimeout: 5 * time.Second, ReadHeaderTimeout: 5 * time.Second, IdleTimeout: 5 * time.Second, - MaxHeaderBytes: 1024 * 256, + MaxHeaderBytes: 1024 * 64, } go cfgEndptSrv.Serve(ln) @@ -169,14 +169,11 @@ type AdminRoute struct { } func handleLoadConfig(w http.ResponseWriter, r *http.Request) { - r.Close = true if r.Method != http.MethodPost { http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) return } - var payload io.Reader = r.Body - // if the config is formatted other than Caddy's native // JSON, we need to adapt it before loading it if ctHeader := r.Header.Get("Content-Type"); ctHeader != "" { @@ -215,16 +212,15 @@ func handleLoadConfig(w http.ResponseWriter, r *http.Request) { } w.Write(respBody) } - payload = bytes.NewReader(result) + // replace original request body with adapted JSON + r.Body.Close() + r.Body = ioutil.NopCloser(bytes.NewReader(result)) } } - err := Load(payload) - if err != nil { - log.Printf("[ADMIN][ERROR] loading config: %v", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } + // pass this off to the /config/ endpoint + r.URL.Path = "/" + rawConfigKey + "/" + handleConfig(w, r) } func handleStop(w http.ResponseWriter, r *http.Request) { -- cgit v1.2.3