diff options
author | Matt Holt <mholt@users.noreply.github.com> | 2022-06-28 22:43:57 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-29 00:43:57 -0400 |
commit | 660c59b6f3c138ce1a143ea864225ba177005e8e (patch) | |
tree | 42b32f45f4dc443248e97fe18d03b27864775f6b /caddyconfig | |
parent | 58e05cab155643c6543892855f373ea8755eb094 (diff) |
admin: Implement /adapt endpoint (close #4465) (#4846)
Diffstat (limited to 'caddyconfig')
-rw-r--r-- | caddyconfig/load.go | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/caddyconfig/load.go b/caddyconfig/load.go index 7a390d0..78aaba2 100644 --- a/caddyconfig/load.go +++ b/caddyconfig/load.go @@ -58,6 +58,10 @@ func (al adminLoad) Routes() []caddy.AdminRoute { Pattern: "/load", Handler: caddy.AdminHandlerFunc(al.handleLoad), }, + { + Pattern: "/adapt", + Handler: caddy.AdminHandlerFunc(al.handleAdapt), + }, } } @@ -122,7 +126,48 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error { return nil } -// adaptByContentType adapts body to Caddy JSON using the adapter specified by contenType. +// handleAdapt adapts the given Caddy config to JSON and responds with the result. +func (adminLoad) handleAdapt(w http.ResponseWriter, r *http.Request) error { + if r.Method != http.MethodPost { + return caddy.APIError{ + HTTPStatus: http.StatusMethodNotAllowed, + Err: fmt.Errorf("method not allowed"), + } + } + + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + defer bufPool.Put(buf) + + _, err := io.Copy(buf, r.Body) + if err != nil { + return caddy.APIError{ + HTTPStatus: http.StatusBadRequest, + Err: fmt.Errorf("reading request body: %v", err), + } + } + + result, warnings, err := adaptByContentType(r.Header.Get("Content-Type"), buf.Bytes()) + if err != nil { + return caddy.APIError{ + HTTPStatus: http.StatusBadRequest, + Err: err, + } + } + + out := struct { + Warnings []Warning `json:"warnings,omitempty"` + Result json.RawMessage `json:"result"` + }{ + Warnings: warnings, + Result: result, + } + + w.Header().Set("Content-Type", "application/json") + return json.NewEncoder(w).Encode(out) +} + +// adaptByContentType adapts body to Caddy JSON using the adapter specified by contentType. // If contentType is empty or ends with "/json", the input will be returned, as a no-op. func adaptByContentType(contentType string, body []byte) ([]byte, []Warning, error) { // assume JSON as the default |